net/dns/resolver: send NXDOMAIN to iOS DNS-SD/Bonjour queries

Don't just ignore them. See if this makes them calm down.

Updates #3363

Change-Id: Id1d66308e26660d26719b2538b577522a1e36b63
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2021-12-18 15:37:40 -08:00 committed by Brad Fitzpatrick
parent 394c9de02b
commit 39f22a357d

View File

@ -598,8 +598,18 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
// out, playing on Sonos still works. // out, playing on Sonos still works.
if hasRDNSBonjourPrefix(domain) { if hasRDNSBonjourPrefix(domain) {
metricDNSFwdDropBonjour.Add(1) metricDNSFwdDropBonjour.Add(1)
res, err := nxDomainResponse(query)
if err != nil {
f.logf("error parsing bonjour query: %v", err)
return nil return nil
} }
select {
case <-ctx.Done():
return ctx.Err()
case responseChan <- res:
return nil
}
}
clampEDNSSize(query.bs, maxResponseBytes) clampEDNSSize(query.bs, maxResponseBytes)
@ -696,6 +706,28 @@ func nameFromQuery(bs []byte) (dnsname.FQDN, error) {
return dnsname.ToFQDN(rawNameToLower(n)) return dnsname.ToFQDN(rawNameToLower(n))
} }
// nxDomainResponse returns an NXDomain DNS reply for the provided request.
func nxDomainResponse(req packet) (res packet, err error) {
p := dnsParserPool.Get().(*dnsParser)
defer dnsParserPool.Put(p)
if err := p.parseQuery(req.bs); err != nil {
return packet{}, err
}
h := p.Header
h.Response = true
h.RecursionAvailable = h.RecursionDesired
h.RCode = dns.RCodeNameError
b := dns.NewBuilder(nil, h)
// TODO(bradfitz): should we add an SOA record in the Authority
// section too? (for the nxdomain negative caching TTL)
// For which zone? Does iOS care?
res.bs, err = b.Finish()
res.addr = req.addr
return res, err
}
// closePool is a dynamic set of io.Closers to close as a group. // closePool is a dynamic set of io.Closers to close as a group.
// It's intended to be Closed at most once. // It's intended to be Closed at most once.
// //