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) 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) HitRatio() (n float64)
- 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 = 6 * time.Hour // six hours
const DefaultMinTTL = 10 * time.Second // ten seconds
const DefaultNXTTL = time.Hour // one hour
const MaxQtype = 260
Variables ¶
var ( // ErrInvalidCookie is returned if the DNS cookie from the server is invalid. ErrInvalidCookie = errors.New("invalid cookie") // ErrMaxDepth is returned when recursive resolving exceeds the allowed limit. ErrMaxDepth = fmt.Errorf("recursion depth exceeded %d", maxDepth) // ErrMaxSteps is returned when resolving exceeds the step limit. ErrMaxSteps = fmt.Errorf("resolve steps exceeded %d", maxSteps) // 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 )
var ErrExtendedErrorCode = extendedErrorCodeError(0)
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 time.Duration // always cache responses for at least this long
MaxTTL time.Duration // never cache responses for longer than this (excepting successful NS responses)
NXTTL time.Duration // cache NXDOMAIN responses for this long
// contains filtered or unexported fields
}
func (*Cache) DnsResolve ¶ added in v0.2.0
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
// 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.