darvaza-proxy / resolver

a dns resolver

Home Page:https://pkg.go.dev/darvaza.org/resolver

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Darvaza DNS Resolver

Go Reference Go Report Card Codebeat Score

Resolver

The Resolver interface reproduces the standard net.Resolver but allows us to make a custom implementation on top of any Lookuper.

We provide three mechanisms to create a Resolver:

  • SystemResolver()/SystemResolverWithDialer() as shortcuts for allocating a standard *net.Resolver{}.
  • NewResolver() returning a Resolver using the given Lookuper{}
  • and NewRootResolver() returning a Resolver using iterative lookup.

Lookuper

The Lookuper interface is centred on Resolver, making simple INET queries.

type Lookuper interface {
    Lookup(ctx context.Context, qName string, qType uint16) (*dns.Msg, error)
}

type LookuperFunc func(ctx context.Context, qName string, qType uint16) (*dns.Msg, error)

Additionally we can use any function implementing the same signature as LookuperFunc, which returns a type implementing Lookuper and Exchanger using the given function.

Exchanger

The Exchanger interface is an alternative to Lookuper but taking pre-assembled *dns.Msg{} queries.

type Exchanger interface {
    Exchange(ctx context.Context, msg *dns.Msg) (*dns.Msg, error)
}

type ExchangerFunc func(ctx context.Context, msg *dns.Msg) (*dns.Msg, error)

Additionally we can use any function implementing the same signature as ExchangerFunc, which returns a type implementing Lookuper and Exchanger using the given function.

client.Client

The client.Client interface represents ExchangeContext() of *dns.Client to perform a *dns.Msg{} against the specified server.

type Client interface {
    ExchangeContext(ctx context.Context, req *dns.Msg, server string) (*dns.Msg, time.Duration, error)
}

type ExchangeFunc func(ctx context.Context, req *dns.Msg, server string) (*dns.Msg, time.Duration, error)

type Unwrapper interface {
    Unwrap() *dns.Client
}

Additionally we can use any function implementing the same signature as client.ExchangeFunc, which returns a type implementing client.Client using the given functions.

Clients are advised to also implement Unwrapper to access the underlying *dns.Client{}.

Errors

We use the standard *net.DNSError{} for all our errors, but also provide errors.MsgAsError() and errors.ErrorAsMsg() to convert back and forth between the errors we emit and an equivalent *dns.Msg.

server.Handler

server.Handler implements a dns.Handler on top of a Lookuper or Exchanger.

Client Implementations

Default Standard Client

client.NewDefaultClient() can be used to get a plain UDP *dns.Client{} with an optional message size.

client.Auto

The client.Auto Client distinguishes requests by server protocol and retries truncated UDP requests as TCP. client.Auto uses udp://, tcp:// and tls:// server prefixes for protocol specific and uses UDP followed by a TCP retry if no prefix is specified.

client.NoAAAA

client.NoAAAA is a Client Middleware that removes all AAAA entries, to be used on systems were IPv6 isn't fully functional.

client.SingleFlight

client.SingleFlight is a Client Middleware that implements a barrier to catch identical queries, with a small caching period. Only the req.Id is ignored when comparing requests, and it operates per-server.

client.WorkerPool

client.WorkerPool is a Client Middleware that implements a barrier limiting the number of exchange calls that can happen in parallel. It's ideally use behind a SingleFlight Client.

reflect.Client

reflect.Client implements logging middleware if front of a client.Client.

Lookuper Implementations

RootLookuper

The RootLookuper implements an iterative Lookuper/Exchanger, supporting an optional custom client.Client.

SingleLookuper

SingleLookuper implements a forwarding Lookuper/Exchanger passing requests as-is to a client.Client.

MultiLookuper

MultiLookuper implements a parallel Lookuper/Exchanger that will pass the request to multiple Lookuper/Exchanger instances and return the first response.

SingleFlight

SingleFlight implements a Lookuper/Exchanger barrier to hold identical requests at the same time, before passing them over to another.

reflect.Lookuper

reflect.Lookuper implements logging middleware in front of a Lookuper or Exchanger.

Well-known recursive resolvers

For convenience we provide shortcuts to create forwarding Lookupers to well known recursive resolvers.

  • NewGoogleLookuper() using 8.8.8.8,
  • NewGoogleLookuper2() using 8.8.4.4,
  • NewCloudflareLookuper() using 1.1.1.1,
  • NewQuad9Lookuper() using 9.9.9.9,
  • and NewQuad9Lookuper6() using Quad9's 2620:fe::f3.

Reflection

reflect.Lookuper and reflect.Client allow us to hook a dynamically enabled logging layer with an optional tracing ID, using the darvaza.org/slog.Logger interface.

See also

About

a dns resolver

https://pkg.go.dev/darvaza.org/resolver

License:MIT License


Languages

Language:Go 94.4%Language:Shell 4.3%Language:Makefile 1.3%