Documentation
¶
Overview ¶
Package dns provides a channel-based DNS message interface and adapters for composing DNS providers, consumers, and middleware.
The central contract is Interface. Implementations expose a request channel; every Request carries its own context and reply channel, so callers can cancel one request without closing the whole provider. Providers and middleware are safe for concurrent consumers unless a concrete type documents otherwise.
The package includes detached middleware, a request router, resolver adapters, an in-memory cache middleware, a simple UDP/TCP DNS client, and a simple UDP DNS server. These pieces are intentionally small and composable so callers can build chains or trees such as resolver adapters feeding shared cache middleware that fans out to local or remote DNS transports.
Index ¶
- Constants
- Variables
- func NextID() uint16
- func Pack(m *Message) ([]byte, error)
- type Cache
- type CacheStorage
- type Client
- type Detached
- type Interface
- type MemoryStorage
- type Message
- type Question
- type Request
- type RequestContext
- type Resolver
- func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error)
- func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error)
- func (r *Resolver) LookupHost(ctx context.Context, host string) ([]string, error)
- func (r *Resolver) LookupIP(ctx context.Context, network, host string) ([]net.IP, error)
- func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, error)
- func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*net.MX, error)
- func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*net.NS, error)
- func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error)
- func (r *Resolver) LookupPort(ctx context.Context, network, service string) (int, error)
- func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*net.SRV, error)
- func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error)
- type ResolverProvider
- type Resource
- type Response
- type RouteFunc
- type Router
- func (r *Router) Attach(name string, backend Interface) error
- func (r *Router) AttachRouter(route RouteFunc) error
- func (r *Router) Close() error
- func (r *Router) Detach(name string) error
- func (r *Router) DetachRouter() error
- func (r *Router) Requests() chan<- Request
- func (r *Router) SetRouter(route RouteFunc) error
- type Server
Constants ¶
const ( TypeA uint16 = 1 TypeNS uint16 = 2 TypeCNAME uint16 = 5 TypeSOA uint16 = 6 TypePTR uint16 = 12 TypeMX uint16 = 15 TypeTXT uint16 = 16 TypeAAAA uint16 = 28 TypeSRV uint16 = 33 ClassIN uint16 = 1 OpcodeQuery uint8 = 0 RCodeSuccess uint8 = 0 RCodeFormatError uint8 = 1 RCodeServerFailure uint8 = 2 RCodeNameError uint8 = 3 RCodeNotImplemented uint8 = 4 )
Variables ¶
var ( // ErrNoUpstream is returned when middleware has no wrapped DNS interface. ErrNoUpstream = errors.New("dns: no upstream attached") // ErrClosed is returned by providers and middleware after Close. ErrClosed = net.ErrClosed )
var ErrInvalidBackendName = errors.New("dns: invalid backend name")
ErrInvalidBackendName is returned when a backend mutation uses an empty name.
Functions ¶
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache is a DNS middleware that caches successful responses and forwards misses to an attachable upstream. Detach cancels requests that are currently waiting on the old upstream. Cached responses remain available across attach, detach, and reattach operations.
func NewCache ¶
func NewCache(upstream Interface, storage CacheStorage) *Cache
NewCache creates a cache using storage. If storage is nil, a new MemoryStorage is used.
func (*Cache) Attach ¶
Attach replaces the upstream DNS interface. Existing requests going through a previous upstream are canceled before the new upstream is installed.
type CacheStorage ¶
type CacheStorage interface {
Get(key string, now time.Time) (*Message, bool)
Set(key string, msg *Message, now time.Time)
Delete(key string)
}
CacheStorage stores DNS messages by cache key. Implementations must be safe for concurrent callers when shared by multiple Cache values.
type Client ¶
type Client struct {
// TLSConfig configures TLS for dot:// upstreams. The config is cloned for
// each connection. If ServerName is empty, the URL host is used.
TLSConfig *tls.Config
// contains filtered or unexported fields
}
Client is a simple DNS client for udp://, tcp://, and dot:// servers.
It sends supported DNS query messages to the configured servers and returns the first successful wire response. The client allocates a fresh wire ID for every upstream request and maps the response ID back to the caller's message ID before replying.
type Detached ¶
type Detached struct {
// contains filtered or unexported fields
}
Detached is an independently closable wrapper around another DNS Interface.
Closing the detached wrapper cancels requests that are currently passing through it but does not close the wrapped interface. Other users of the wrapped interface continue to operate normally.
type Interface ¶
Interface is a concurrent, channel based DNS message transport.
Implementations accept request messages through Requests and respond through the per-request Reply channel. Close terminates the implementation and cancels in-flight work owned by that implementation. Callers may share one Interface between multiple goroutines.
type MemoryStorage ¶
type MemoryStorage struct {
// contains filtered or unexported fields
}
MemoryStorage is a simple map-backed CacheStorage implementation.
func NewMemoryStorage ¶
func NewMemoryStorage() *MemoryStorage
NewMemoryStorage returns an empty in-memory cache storage.
func (*MemoryStorage) Delete ¶
func (s *MemoryStorage) Delete(key string)
type Message ¶
type Message struct {
ID uint16
Response bool
Opcode uint8
RCode uint8
Authoritative bool
Truncated bool
RecursionDesired bool
RecursionAvailable bool
AuthenticatedData bool
CheckingDisabled bool
Questions []Question
Answers []Resource
Authorities []Resource
Additionals []Resource
}
Message is the package-level representation of a DNS message.
It intentionally models the message header and the four standard sections without tying callers to a concrete wire codec. Name values are regular DNS names; callers may use either absolute names with a trailing dot or relative presentation names.
type Request ¶
type Request struct {
Context RequestContext
Message *Message
Reply chan<- Response
}
Request is the channel envelope used by DNS implementations. Context cancels only this request. Reply receives exactly one Response unless the provider has already been closed before it can accept the request.
type RequestContext ¶
RequestContext is the subset of context.Context carried by a Request.
type Resolver ¶
type Resolver struct {
DNS Interface
}
Resolver adapts a DNS Interface into a full gonnect.Resolver.
func NewResolver ¶
func (*Resolver) LookupAddr ¶
func (*Resolver) LookupCNAME ¶
func (*Resolver) LookupHost ¶
func (*Resolver) LookupIPAddr ¶
func (*Resolver) LookupNetIP ¶
func (*Resolver) LookupPort ¶
type ResolverProvider ¶
type ResolverProvider struct {
// contains filtered or unexported fields
}
ResolverProvider adapts a gonnect.Resolver into a DNS Interface.
It supports standard IN-class A, AAAA, PTR, CNAME, TXT, MX, NS, and SRV queries. Unsupported opcodes, classes, or record types are answered with RCodeNotImplemented. Resolver lookup failures are mapped to NameError when the resolver reports not-found and ServerFailure otherwise. Successful resource records use the configured TTL.
func NewResolverProvider ¶
func NewResolverProvider( resolver gonnect.Resolver, ttl time.Duration, ) *ResolverProvider
NewResolverProvider returns a DNS provider backed by resolver.
func (*ResolverProvider) Close ¶
func (r *ResolverProvider) Close() error
func (*ResolverProvider) Requests ¶
func (r *ResolverProvider) Requests() chan<- Request
type Resource ¶
Resource identifies one DNS resource record. Data stores record-specific payload in DNS wire format without the owner name, type, class, or TTL.
type RouteFunc ¶
RouteFunc selects the backend name for a DNS request.
Returning an empty string or a name without an attached backend rejects the request with ErrNoUpstream.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router is a DNS Interface that routes requests to named backend interfaces.
Backends and the route function can be attached, detached, or replaced while the Router is serving requests. Mutations cancel in-flight requests that were routed through an older backend set or route function. Closing the Router cancels in-flight work owned by the Router but does not close attached backends.
func (*Router) AttachRouter ¶
AttachRouter installs or replaces the route function. Passing nil is equivalent to DetachRouter.
func (*Router) DetachRouter ¶
DetachRouter removes the route function.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a simple UDP DNS server backed by a packet connection.
For every client packet it unpacks the DNS message, replaces the client's ID with a new internal ID before forwarding through the attached DNS Interface, then maps the response ID back to the original client ID. Attach and Detach can replace the upstream without closing the packet connection; detaching cancels requests currently waiting on the old upstream.
func NewServer ¶
func NewServer(conn net.PacketConn, upstream Interface) *Server
NewServer starts serving DNS packets from conn.
func (*Server) Attach ¶
Attach replaces the upstream DNS interface and cancels requests using the previous upstream.