Documentation
¶
Overview ¶
package recursive provides a minimal iterative DNS resolver with QNAME minimization using github.com/miekg/dns for wire format and transport.
Index ¶
- Constants
- Variables
- func ErrorFromExtendedErrorCode(code uint16) (err error)
- func ExtendedErrorCodeFromError(err error) (rcode uint16)
- type Cache
- func (cache *Cache) Clean()
- func (cache *Cache) CleanAllow(t time.Time, allowfn func(msg *dns.Msg, ttl time.Duration) bool)
- func (cache *Cache) CleanBefore(t time.Time)
- func (cache *Cache) Clear()
- func (cache *Cache) DnsGet(qname string, qtype uint16) (msg *dns.Msg)
- func (cache *Cache) DnsResolve(ctx context.Context, qname string, qtype uint16) (msg *dns.Msg, srv netip.Addr, err error)
- func (cache *Cache) DnsSet(msg *dns.Msg)
- func (cache *Cache) Entries() (n int)
- func (cache *Cache) Get(qname string, qtype uint16, allowfn func(msg *dns.Msg, ttl time.Duration) bool) (msg *dns.Msg, stale bool)
- func (cache *Cache) HitRatio() (n float64)
- func (cache *Cache) Merge(other *Cache)
- func (cache *Cache) ReadFrom(r io.Reader) (n int64, err error)
- func (cache *Cache) Walk(fn func(msg *dns.Msg, expires time.Time) (err error)) (err error)
- func (cache *Cache) WriteTo(w io.Writer) (n int64, err error)
- type CachedNetError
- type Cacher
- type CachingResolver
- type Recursive
- func (r *Recursive) DnsResolve(ctx context.Context, qname string, qtype uint16) (msg *dns.Msg, srv netip.Addr, err error)
- func (r *Recursive) GetRoots() (root4, root6 []netip.Addr)
- func (r *Recursive) OrderRoots(ctx context.Context)
- func (r *Recursive) OrderRootsTimeout(ctx context.Context, cutoff time.Duration)
- func (r *Recursive) ResetCookies()
- func (r *Recursive) ResolveWithOptions(ctx context.Context, cache Cacher, logw io.Writer, qname string, qtype uint16) (msg *dns.Msg, origin netip.Addr, err error)
- type Resolver
Constants ¶
const DefaultMaxTTL = 7 * 24 * 60 * 60
const DefaultMinTTL = 10
const DefaultNXTTL = 60 * 60
Variables ¶
var ( // ErrInvalidCookie is returned if the DNS cookie from the server is invalid. ErrInvalidCookie = errors.New("invalid cookie") // ErrMismatchedQuestion is returned when a response question does not match the query. ErrMismatchedQuestion = errors.New("mismatched response question") // ErrMaxDepth is returned when recursive resolving exceeds the allowed limit. ErrMaxDepth = errors.New("recursion depth exceeded 16") // ErrMaxSteps is returned when resolving exceeds the step limit. ErrMaxSteps = errors.New("resolve steps exceeded 4096") // ErrNoResponse is returned when no authoritative server could be successfully queried. // It is equivalent to SERVFAIL. ErrNoResponse = errors.New("no authoritative response") DefaultCache = NewCache() DefaultTimeout = time.Second * 3 DefaultDNSPort uint16 = 53 DefaultMsgSize uint16 = 1232 // default UDP message size )
var ErrExtendedErrorCode = extendedErrorCodeError(0)
var ErrInvalidCacheEntry = errors.New("invalid cache entry")
var ErrWrongMagic = errors.New("wrong magic number")
var Roots4 = []netip.Addr{ netip.AddrFrom4([4]byte([]byte{0xaa, 0xf7, 0xaa, 0x2})), netip.AddrFrom4([4]byte([]byte{0xc0, 0x5, 0x5, 0xf1})), netip.AddrFrom4([4]byte([]byte{0xc0, 0x21, 0x4, 0xc})), netip.AddrFrom4([4]byte([]byte{0xc0, 0x24, 0x94, 0x11})), netip.AddrFrom4([4]byte([]byte{0xc0, 0x3a, 0x80, 0x1e})), netip.AddrFrom4([4]byte([]byte{0xc0, 0x70, 0x24, 0x4})), netip.AddrFrom4([4]byte([]byte{0xc0, 0xcb, 0xe6, 0xa})), netip.AddrFrom4([4]byte([]byte{0xc1, 0x0, 0xe, 0x81})), netip.AddrFrom4([4]byte([]byte{0xc6, 0x29, 0x0, 0x4})), netip.AddrFrom4([4]byte([]byte{0xc6, 0x61, 0xbe, 0x35})), netip.AddrFrom4([4]byte([]byte{0xc7, 0x7, 0x53, 0x2a})), netip.AddrFrom4([4]byte([]byte{0xc7, 0x7, 0x5b, 0xd})), netip.AddrFrom4([4]byte([]byte{0xca, 0xc, 0x1b, 0x21})), }
var Roots6 = []netip.Addr{ netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x53})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xd})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x0, 0x0, 0x9f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x3, 0xc, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x30})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x5, 0x3, 0xba, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x30})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x7, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0x7, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x53})), netip.AddrFrom16([16]byte([]byte{0x20, 0x1, 0xd, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x35})), netip.AddrFrom16([16]byte([]byte{0x28, 0x1, 0x1, 0xb8, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb})), }
Functions ¶
func ErrorFromExtendedErrorCode ¶ added in v0.16.0
ErrorFromExtendedErrorCode returns the canonical Go error for the provided Extended Error Code. It returns ErrExtendedErrorCode if there is no known mapping.
func ExtendedErrorCodeFromError ¶ added in v0.16.0
ExtendedErrorCodeFromError attempts to map a Go error to a DNS Extended Rcode. The function understands well-known errors from the os, io, and net packages (including their wrapper types) and returns dns.ExtendedErrorCodeOther if no mapping is known.
Types ¶
type Cache ¶ added in v0.1.2
type Cache struct {
MinTTL int64 // always cache responses for at least this long seconds
MaxTTL int64 // never cache responses for longer than this seconds (excepting successful NS responses)
NXTTL int64 // cache NXDOMAIN responses for this long seconds
// contains filtered or unexported fields
}
func (*Cache) Clean ¶ added in v0.1.2
func (cache *Cache) Clean()
Clean removes stale entries from the cache.
func (*Cache) CleanAllow ¶ added in v0.22.6
CleanAllow calls allowfn with 't' as the time to use to determine staleness. If allowfn returns false, the cache entry is removed.
func (*Cache) CleanBefore ¶ added in v0.21.3
CleanBefore removes entries that expired before t from the cache.
func (*Cache) DnsGet ¶ added in v0.2.0
DnsGet returns a caches DNS message if one exists that has not expired.
If an expired message is found, it is removed from the cache and nil is returned.
func (*Cache) DnsResolve ¶ added in v0.2.0
func (*Cache) DnsSet ¶ added in v0.2.0
DnsSet add a DNS message to the cache.
Does nothing if the message has the Zero flag set, or does not have exactly one Question.
func (*Cache) Get ¶ added in v0.1.2
func (cache *Cache) Get(qname string, qtype uint16, allowfn func(msg *dns.Msg, ttl time.Duration) bool) (msg *dns.Msg, stale bool)
Get allows filtering DNS entries from the cache and control of eviction.
If and entry is found, and allowfn returns true, the entry is returned. Otherwise, the entry is purged from the cache,
The default allowfn returns false if the entry is stale.
func (*Cache) Merge ¶ added in v0.21.1
Merge inserts all entries from other into cache. If an entry exists in both, the one that expires last wins.
type CachedNetError ¶ added in v0.22.10
func (*CachedNetError) Error ¶ added in v0.22.10
func (ne *CachedNetError) Error() string
func (*CachedNetError) Unwrap ¶ added in v0.22.10
func (ne *CachedNetError) Unwrap() error
type Cacher ¶ added in v0.1.4
type Cacher interface {
// DnsSet stores msg for the supplied question. Implementations may keep a
// private copy, but the cached instance must have dns.Msg.Zero set to true
// before it is returned by DnsGet.
DnsSet(msg *dns.Msg)
// DnsGet returns the cached dns.Msg pointer for the given qname and qtype, or
// nil if no entry exists. The returned message MUST keep dns.Msg.Zero set to
// true to signal it originated from cache, and callers MUST treat it as
// immutable by copying it before applying any mutations.
DnsGet(qname string, qtype uint16) *dns.Msg
}
type CachingResolver ¶ added in v0.2.0
type Recursive ¶ added in v0.1.6
type Recursive struct {
proxy.ContextDialer // context dialer to use
Cacher // cache to use for DnsResolve
Timeout time.Duration // default is DefaultTimeout
DNSPort uint16 // default is DefaultDNSPort
Deterministic bool // if true, always query nameservers in the same order
MsgSize uint16 // UDP message size
// contains filtered or unexported fields
}
func New ¶
func New(dialer proxy.ContextDialer) *Recursive
New returns a new Recursive resolver using the given ContextDialer and has DefaultCache as it's cache.
It calls OrderRoots before returning.
func NewWithOptions ¶
func NewWithOptions(dialer proxy.ContextDialer, cache Cacher, roots4, roots6 []netip.Addr, rateLimiter <-chan struct{}) *Recursive
NewWithOptions returns a new Recursive resolver using the given ContextDialer and using the given Cacher as the cache when calling DnsResolve. It does not call OrderRoots.
Passing nil for dialer will use a net.Dialer. Passing nil for the roots will use the default set of roots. Passing nil for the rateLimiter means no rate limiting
func (*Recursive) DnsResolve ¶ added in v0.2.0
func (*Recursive) GetRoots ¶ added in v0.9.1
GetRoots returns the current set of root servers in use.
func (*Recursive) OrderRoots ¶ added in v0.2.0
func (*Recursive) OrderRootsTimeout ¶ added in v0.18.0
OrderRootsTimeout sorts the root server list by their current latency and removes those that don't respond within cutoff.
func (*Recursive) ResetCookies ¶ added in v0.5.0
func (r *Recursive) ResetCookies()
ResetCookies generates a new DNS client cookie and clears the known DNS server cookies.
func (*Recursive) ResolveWithOptions ¶ added in v0.1.6
func (r *Recursive) ResolveWithOptions(ctx context.Context, cache Cacher, logw io.Writer, qname string, qtype uint16) (msg *dns.Msg, origin netip.Addr, err error)
ResolveWithOptions performs iterative resolution with QNAME minimization for qname/qtype.