tailscale.comtailscale.com/net/dns/resolver Index | Files

package resolver

import "tailscale.com/net/dns/resolver"

Package resolver implements a stub DNS resolver that can also serve records out of an internal local zone.

Index

Functions

func ShouldUseRoutes

func ShouldUseRoutes(knobs *controlknobs.Knobs) bool

ShouldUseRoutes reports whether the DNS resolver should consider routes when dialing upstream nameservers via TCP.

If true, routes should be considered (tsdial.Dialer.UserDial), otherwise defer to the system routes (tsdial.Dialer.SystemDial).

TODO(nickkhyl): Update tsdial.Dialer to reuse the bart.Table we create in net/tstun.Wrapper to avoid having two bart tables in memory, especially on iOS. Once that's done, we can get rid of the nodeAttr/control knob and always use UserDial for DNS.

See tailscale/tailscale#12027.

func WriteDNSResolver

func WriteDNSResolver(w *bufio.Writer, r *dnstype.Resolver)

WriteDNSResolver writes r to w.

func WriteDNSResolvers

func WriteDNSResolvers(w *bufio.Writer, resolvers []*dnstype.Resolver)

WriteDNSResolvers writes resolvers to w.

func WriteIPPorts

func WriteIPPorts(w *bufio.Writer, vv []netip.AddrPort)

WriteIPPorts writes vv to w.

func WriteRoutes

func WriteRoutes(w *bufio.Writer, routes map[dnsname.FQDN][]*dnstype.Resolver)

WriteRoutes writes routes to w, omitting *.arpa routes and instead summarizing how many of them there were.

Types

type Config

type Config struct {
	// Routes is a map of DNS name suffix to the resolvers to use for
	// queries within that suffix.
	// Queries only match the most specific suffix.
	// To register a "default route", add an entry for ".".
	Routes map[dnsname.FQDN][]*dnstype.Resolver
	// LocalHosts is a map of FQDNs to corresponding IPs.
	Hosts map[dnsname.FQDN][]netip.Addr
	// LocalDomains is a list of DNS name suffixes that should not be
	// routed to upstream resolvers.
	LocalDomains []dnsname.FQDN
}

Config is a resolver configuration. Given a Config, queries are resolved in the following order: If the query is an exact match for an entry in LocalHosts, return that. Else if the query suffix matches an entry in LocalDomains, return NXDOMAIN. Else forward the query to the most specific matching entry in Routes. Else return SERVFAIL.

func (*Config) RoutesRequireNoCustomResolvers

func (c *Config) RoutesRequireNoCustomResolvers() bool

RoutesRequireNoCustomResolvers returns true if this resolver.Config only contains routes that do not specify a set of custom resolver(s), i.e. they can be resolved by the local upstream DNS resolver.

func (*Config) WriteToBufioWriter

func (c *Config) WriteToBufioWriter(w *bufio.Writer)

WriteToBufioWriter write a debug version of c for logs to w, omitting spammy stuff like *.arpa entries and replacing it with a total count.

type ForwardLinkSelector

type ForwardLinkSelector interface {
	// PickLink returns which network device should be used to query
	// the DNS server at the given IP.
	// The empty string means to use an unspecified default.
	PickLink(netip.Addr) (linkName string)
}

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver is a DNS resolver for nodes on the Tailscale network, associating them with domain names of the form <mynode>.<mydomain>.<root>. If it is asked to resolve a domain that is not of that form, it delegates to upstream nameservers if any are set.

func New

func New(logf logger.Logf, linkSel ForwardLinkSelector, dialer *tsdial.Dialer, health *health.Tracker, knobs *controlknobs.Knobs) *Resolver

New returns a new resolver. dialer and health must be non-nil.

func (*Resolver) Close

func (r *Resolver) Close()

Close shuts down the resolver and ensures poll goroutines have exited. The Resolver cannot be used again after Close is called.

func (*Resolver) GetUpstreamResolvers

func (r *Resolver) GetUpstreamResolvers(name dnsname.FQDN) []*dnstype.Resolver

GetUpstreamResolvers returns the resolvers that would be used to resolve the given FQDN.

func (*Resolver) HandlePeerDNSQuery

func (r *Resolver) HandlePeerDNSQuery(ctx context.Context, q []byte, from netip.AddrPort, allowName func(name string) bool) (res []byte, err error)

HandlePeerDNSQuery handles a DNS query that arrived from a peer via the peerapi's DoH server. This is used when the local node is being an exit node or an app connector.

The provided allowName callback is whether a DNS query for a name (as found by parsing q) is allowed.

In most (all?) cases, err will be nil. A bogus DNS query q will still result in a response DNS packet (saying there's a failure) and a nil error. TODO: figure out if we even need an error result.

func (*Resolver) Query

func (r *Resolver) Query(ctx context.Context, bs []byte, family string, from netip.AddrPort) ([]byte, error)

func (*Resolver) SetConfig

func (r *Resolver) SetConfig(cfg Config) error

func (*Resolver) SetMissingUpstreamRecovery

func (r *Resolver) SetMissingUpstreamRecovery(f func())

SetMissingUpstreamRecovery sets a callback to be called upon encountering a SERVFAIL due to missing upstream resolvers.

This call should only happen before the resolver is used. It is not safe for concurrent use.

func (*Resolver) TestOnlySetHook

func (r *Resolver) TestOnlySetHook(hook func(Config))

Source Files

debug.go forwarder.go tsdns.go

Version
v1.84.0 (latest)
Published
May 21, 2025
Platform
linux/amd64
Imports
47 packages
Last checked
1 day ago

Tools for package owners.