From 39f22a357d5b418e248a8f53c4933bbecf636525 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 18 Dec 2021 15:37:40 -0800 Subject: [PATCH] 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 --- net/dns/resolver/forwarder.go | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/net/dns/resolver/forwarder.go b/net/dns/resolver/forwarder.go index fb75793b9..d84400e70 100644 --- a/net/dns/resolver/forwarder.go +++ b/net/dns/resolver/forwarder.go @@ -598,7 +598,17 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo // out, playing on Sonos still works. if hasRDNSBonjourPrefix(domain) { metricDNSFwdDropBonjour.Add(1) - return nil + res, err := nxDomainResponse(query) + if err != nil { + f.logf("error parsing bonjour query: %v", err) + return nil + } + select { + case <-ctx.Done(): + return ctx.Err() + case responseChan <- res: + return nil + } } clampEDNSSize(query.bs, maxResponseBytes) @@ -696,6 +706,28 @@ func nameFromQuery(bs []byte) (dnsname.FQDN, error) { 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. // It's intended to be Closed at most once. //