|
|
|
@ -44,14 +44,9 @@ var (
|
|
|
|
|
errNotOurName = errors.New("not a Tailscale DNS name")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Packet represents a DNS payload together with the address of its origin.
|
|
|
|
|
type Packet struct {
|
|
|
|
|
// Payload is the application layer DNS payload.
|
|
|
|
|
// Resolver assumes ownership of the request payload when it is enqueued
|
|
|
|
|
// and cedes ownership of the response payload when it is returned from NextResponse.
|
|
|
|
|
Payload []byte
|
|
|
|
|
// Addr is the source address for a request and the destination address for a response.
|
|
|
|
|
Addr netaddr.IPPort
|
|
|
|
|
type packet struct {
|
|
|
|
|
bs []byte
|
|
|
|
|
addr netaddr.IPPort // src for a request, dst for a response
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolver is a DNS resolver for nodes on the Tailscale network,
|
|
|
|
@ -66,9 +61,9 @@ type Resolver struct {
|
|
|
|
|
forwarder *forwarder
|
|
|
|
|
|
|
|
|
|
// queue is a buffered channel holding DNS requests queued for resolution.
|
|
|
|
|
queue chan Packet
|
|
|
|
|
queue chan packet
|
|
|
|
|
// responses is an unbuffered channel to which responses are returned.
|
|
|
|
|
responses chan Packet
|
|
|
|
|
responses chan packet
|
|
|
|
|
// errors is an unbuffered channel to which errors are returned.
|
|
|
|
|
errors chan error
|
|
|
|
|
// closed signals all goroutines to stop.
|
|
|
|
@ -88,8 +83,8 @@ func New(logf logger.Logf, linkMon *monitor.Mon) (*Resolver, error) {
|
|
|
|
|
r := &Resolver{
|
|
|
|
|
logf: logger.WithPrefix(logf, "dns: "),
|
|
|
|
|
linkMon: linkMon,
|
|
|
|
|
queue: make(chan Packet, queueSize),
|
|
|
|
|
responses: make(chan Packet),
|
|
|
|
|
queue: make(chan packet, queueSize),
|
|
|
|
|
responses: make(chan packet),
|
|
|
|
|
errors: make(chan error),
|
|
|
|
|
closed: make(chan struct{}),
|
|
|
|
|
}
|
|
|
|
@ -153,11 +148,11 @@ func (r *Resolver) SetUpstreams(upstreams []net.Addr) {
|
|
|
|
|
// EnqueueRequest places the given DNS request in the resolver's queue.
|
|
|
|
|
// It takes ownership of the payload and does not block.
|
|
|
|
|
// If the queue is full, the request will be dropped and an error will be returned.
|
|
|
|
|
func (r *Resolver) EnqueueRequest(request Packet) error {
|
|
|
|
|
func (r *Resolver) EnqueueRequest(bs []byte, from netaddr.IPPort) error {
|
|
|
|
|
select {
|
|
|
|
|
case <-r.closed:
|
|
|
|
|
return ErrClosed
|
|
|
|
|
case r.queue <- request:
|
|
|
|
|
case r.queue <- packet{bs, from}:
|
|
|
|
|
return nil
|
|
|
|
|
default:
|
|
|
|
|
return errFullQueue
|
|
|
|
@ -166,14 +161,14 @@ func (r *Resolver) EnqueueRequest(request Packet) error {
|
|
|
|
|
|
|
|
|
|
// NextResponse returns a DNS response to a previously enqueued request.
|
|
|
|
|
// It blocks until a response is available and gives up ownership of the response payload.
|
|
|
|
|
func (r *Resolver) NextResponse() (Packet, error) {
|
|
|
|
|
func (r *Resolver) NextResponse() (packet []byte, to netaddr.IPPort, err error) {
|
|
|
|
|
select {
|
|
|
|
|
case <-r.closed:
|
|
|
|
|
return Packet{}, ErrClosed
|
|
|
|
|
return nil, netaddr.IPPort{}, ErrClosed
|
|
|
|
|
case resp := <-r.responses:
|
|
|
|
|
return resp, nil
|
|
|
|
|
return resp.bs, resp.addr, nil
|
|
|
|
|
case err := <-r.errors:
|
|
|
|
|
return Packet{}, err
|
|
|
|
|
return nil, netaddr.IPPort{}, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -266,19 +261,19 @@ func (r *Resolver) ResolveReverse(ip netaddr.IP) (string, dns.RCode, error) {
|
|
|
|
|
func (r *Resolver) poll() {
|
|
|
|
|
defer r.wg.Done()
|
|
|
|
|
|
|
|
|
|
var packet Packet
|
|
|
|
|
var pkt packet
|
|
|
|
|
for {
|
|
|
|
|
select {
|
|
|
|
|
case <-r.closed:
|
|
|
|
|
return
|
|
|
|
|
case packet = <-r.queue:
|
|
|
|
|
case pkt = <-r.queue:
|
|
|
|
|
// continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out, err := r.respond(packet.Payload)
|
|
|
|
|
out, err := r.respond(pkt.bs)
|
|
|
|
|
|
|
|
|
|
if err == errNotOurName {
|
|
|
|
|
err = r.forwarder.forward(packet)
|
|
|
|
|
err = r.forwarder.forward(pkt)
|
|
|
|
|
if err == nil {
|
|
|
|
|
// forward will send response into r.responses, nothing to do.
|
|
|
|
|
continue
|
|
|
|
@ -293,11 +288,11 @@ func (r *Resolver) poll() {
|
|
|
|
|
// continue
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
packet.Payload = out
|
|
|
|
|
pkt.bs = out
|
|
|
|
|
select {
|
|
|
|
|
case <-r.closed:
|
|
|
|
|
return
|
|
|
|
|
case r.responses <- packet:
|
|
|
|
|
case r.responses <- pkt:
|
|
|
|
|
// continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|