package module
v0.0.0-...-df5bfe0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Mar 26, 2017 License: MIT Imports: 16 Imported by: 0



GoDoc Build Status

A simple Golang package and standalone server for recursive DNS resolution.

Golang >= 1.7 is required to make use of the new standard library context package.

Until there is a full test suite you should really not trust this.



Package solvere provides an implementation of a recursive, validating, DNSSEC aware DNS resolver, and a basic question and answer cache implementation.



This section is empty.


View Source
var (
	ErrNoDNSKEY               = errors.New("solvere: No DNSKEY records found")
	ErrMissingKSK             = errors.New("solvere: No KSK DNSKEY found for DS records")
	ErrFailedToConvertKSK     = errors.New("solvere: Failed to convert KSK DNSKEY record to DS record")
	ErrMismatchingDS          = errors.New("solvere: KSK DNSKEY record does not match DS record from parent zone")
	ErrNoSignatures           = errors.New("solvere: No RRSIG records for zone that should be signed")
	ErrMissingDNSKEY          = errors.New("solvere: No matching DNSKEY found for RRSIG records")
	ErrInvalidSignaturePeriod = errors.New("solvere: Incorrect signature validity period")
	ErrBadAnswer              = errors.New("solvere: Response contained a non-zero RCODE")
	ErrMissingSigned          = errors.New("solvere: Signed records are missing")
View Source
var (
	ErrNSECMismatch         = errors.New("solvere: NSEC3 record doesn't match question")
	ErrNSECTypeExists       = errors.New("solvere: NSEC3 record shows question type exists")
	ErrNSECMultipleCoverage = errors.New("solvere: Multiple NSEC3 records cover next closer/source of synthesis")
	ErrNSECMissingCoverage  = errors.New("solvere: NSEC3 record missing for expected encloser")
	ErrNSECBadDelegation    = errors.New("solvere: DS or SOA bit set in NSEC3 type map")
	ErrNSECNSMissing        = errors.New("solvere: NS bit not set in NSEC3 type map")
	ErrNSECOptOut           = errors.New("solvere: Opt-Out bit not set for NSEC3 record covering next closer")
View Source
var (
	// MaxReferrals is the maximum number of referral responses before failing
	MaxReferrals = 10

	ErrTooManyReferrals   = errors.New("solvere: Too many referrals")
	ErrNoNSAuthorties     = errors.New("solvere: No NS authority records found")
	ErrNoAuthorityAddress = errors.New("solvere: No A/AAAA records found for the chosen authority")
	ErrOutOfBailiwick     = errors.New("Out of bailiwick record in message")


This section is empty.


type Answer

type Answer struct {
	Answer        []dns.RR
	Authority     []dns.RR
	Additional    []dns.RR
	Rcode         int
	Authenticated bool

Answer contains the answer to a iterative resolution performed by RecursiveResolver.Lookup

type BasicCache

type BasicCache struct {
	// contains filtered or unexported fields

BasicCache is a basic implementation of the QuestionAnswerCache interface

func NewBasicCache

func NewBasicCache() *BasicCache

NewBasicCache returns an initialized BasicCache

func (*BasicCache) Add

func (bc *BasicCache) Add(q *Question, answer *Answer, forever bool)

Add adds a response to the cache using a index based on the question

func (*BasicCache) Get

func (bc *BasicCache) Get(q *Question) *Answer

Get returns the response for a question if it exists in the cache

type LookupLog

type LookupLog struct {
	Query       *Question
	Rcode       int
	CacheHit    bool `json:",omitempty"`
	DNSSECValid bool
	Latency     time.Duration
	Error       string `json:",omitempty"`
	Truncated   bool   `json:",omitempty"`
	Referral    bool   `json:",omitempty"`
	Started     time.Time

	NS *Nameserver `json:",omitempty"`

	Composites []*LookupLog `json:",omitempty"`

LookupLog describes how a resolution was performed

type Nameserver

type Nameserver struct {
	Name string
	Addr string
	Zone string

Nameserver describes an authoritative nameserver

type Question

type Question struct {
	Name string
	Type uint16

Question represents a DNS IN question

type QuestionAnswerCache

type QuestionAnswerCache interface {
	Get(q *Question) *Answer
	Add(q *Question, answer *Answer, forever bool)

QuestionAnswerCache is used to cache responses to queries. The internal implementation can be bypassed using this interface.

type RecursiveResolver

type RecursiveResolver struct {
	// contains filtered or unexported fields

RecursiveResolver defines the parameters for running a recursive resolver

func NewRecursiveResolver

func NewRecursiveResolver(useIPv6 bool, useDNSSEC bool, rootHints []dns.RR, rootKeys []dns.RR, cache QuestionAnswerCache) *RecursiveResolver

NewRecursiveResolver returns an initialized RecursiveResolver. If cache is nil answers won't be cached.

func (*RecursiveResolver) Lookup

func (rr *RecursiveResolver) Lookup(ctx context.Context, q Question) (*Answer, *LookupLog, error)

Lookup a Question iteratively. All upstream responses are validated and a DNSSEC chain is built if the RecursiveResolver was initialized to do so. If responses are found in the question/answer cache they will be used instead of sending messages to remote nameservers.



  • pretty sure this is 100% incorrect, should prob be its own method...

    if strings.HasPrefix(q.Name, "*.") {
     // RFC 5155 Section 8.7
     ce, _ := findClosestEncloser(q.Name, nsec)
     if ce == "" {
     return ErrNSECMissingCoverage
     matchTypes, err := findMatching(fmt.Sprintf("*.%s", ce), nsec)
     if err != nil {
     return err
     if typesSet(matchTypes, q.Type, dns.TypeCNAME) {
     return ErrNSECTypeExists


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL