mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
net/dns/resolver: log forwarded query details when TS_DEBUG_DNS_FORWARD_SEND is enabled
Troubleshooting DNS resolution issues often requires additional information. This PR expands the effect of the TS_DEBUG_DNS_FORWARD_SEND envknob to forwarder.forwardWithDestChan, and includes the request type, domain name length, and the first 3 bytes of the domain's SHA-256 hash in the output. Fixes #13070 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
parent
a867a4869d
commit
f23932bd98
@ -6,6 +6,8 @@
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -498,9 +500,10 @@ func (f *forwarder) sendDoH(ctx context.Context, urlBase string, c *http.Client,
|
||||
func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDelay) (ret []byte, err error) {
|
||||
if verboseDNSForward() {
|
||||
id := forwarderCount.Add(1)
|
||||
f.logf("forwarder.send(%q) [%d] ...", rr.name.Addr, id)
|
||||
domain, typ, _ := nameFromQuery(fq.packet)
|
||||
f.logf("forwarder.send(%q, %d, %v, %d) [%d] ...", rr.name.Addr, fq.txid, typ, len(domain), id)
|
||||
defer func() {
|
||||
f.logf("forwarder.send(%q) [%d] = %v, %v", rr.name.Addr, id, len(ret), err)
|
||||
f.logf("forwarder.send(%q, %d, %v, %d) [%d] = %v, %v", rr.name.Addr, fq.txid, typ, len(domain), id, len(ret), err)
|
||||
}()
|
||||
}
|
||||
if strings.HasPrefix(rr.name.Addr, "http://") {
|
||||
@ -866,7 +869,7 @@ type forwardQuery struct {
|
||||
// node DNS proxy queries), otherwise f.resolvers is used.
|
||||
func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, responseChan chan<- packet, resolvers ...resolverAndDelay) error {
|
||||
metricDNSFwd.Add(1)
|
||||
domain, err := nameFromQuery(query.bs)
|
||||
domain, typ, err := nameFromQuery(query.bs)
|
||||
if err != nil {
|
||||
metricDNSFwdErrorName.Add(1)
|
||||
return err
|
||||
@ -943,6 +946,12 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
|
||||
}
|
||||
defer fq.closeOnCtxDone.Close()
|
||||
|
||||
if verboseDNSForward() {
|
||||
domainSha256 := sha256.Sum256([]byte(domain))
|
||||
domainSig := base64.RawStdEncoding.EncodeToString(domainSha256[:3])
|
||||
f.logf("request(%d, %v, %d, %s) %d...", fq.txid, typ, len(domain), domainSig, len(fq.packet))
|
||||
}
|
||||
|
||||
resc := make(chan []byte, 1) // it's fine buffered or not
|
||||
errc := make(chan error, 1) // it's fine buffered or not too
|
||||
for i := range resolvers {
|
||||
@ -982,6 +991,9 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
|
||||
metricDNSFwdErrorContext.Add(1)
|
||||
return fmt.Errorf("waiting to send response: %w", ctx.Err())
|
||||
case responseChan <- packet{v, query.family, query.addr}:
|
||||
if verboseDNSForward() {
|
||||
f.logf("response(%d, %v, %d) = %d, nil", fq.txid, typ, len(domain), len(v))
|
||||
}
|
||||
metricDNSFwdSuccess.Add(1)
|
||||
f.health.SetHealthy(dnsForwarderFailing)
|
||||
return nil
|
||||
@ -1009,6 +1021,9 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
|
||||
}
|
||||
f.health.SetUnhealthy(dnsForwarderFailing, health.Args{health.ArgDNSServers: strings.Join(resolverAddrs, ",")})
|
||||
case responseChan <- res:
|
||||
if verboseDNSForward() {
|
||||
f.logf("forwarder response(%d, %v, %d) = %d, %v", fq.txid, typ, len(domain), len(res.bs), firstErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
return firstErr
|
||||
@ -1037,24 +1052,28 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
|
||||
var initListenConfig func(_ *net.ListenConfig, _ *netmon.Monitor, tunName string) error
|
||||
|
||||
// nameFromQuery extracts the normalized query name from bs.
|
||||
func nameFromQuery(bs []byte) (dnsname.FQDN, error) {
|
||||
func nameFromQuery(bs []byte) (dnsname.FQDN, dns.Type, error) {
|
||||
var parser dns.Parser
|
||||
|
||||
hdr, err := parser.Start(bs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", 0, err
|
||||
}
|
||||
if hdr.Response {
|
||||
return "", errNotQuery
|
||||
return "", 0, errNotQuery
|
||||
}
|
||||
|
||||
q, err := parser.Question()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", 0, err
|
||||
}
|
||||
|
||||
n := q.Name.Data[:q.Name.Length]
|
||||
return dnsname.ToFQDN(rawNameToLower(n))
|
||||
fqdn, err := dnsname.ToFQDN(rawNameToLower(n))
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
return fqdn, q.Type, nil
|
||||
}
|
||||
|
||||
// nxDomainResponse returns an NXDomain DNS reply for the provided request.
|
||||
|
@ -201,7 +201,7 @@ func BenchmarkNameFromQuery(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for range b.N {
|
||||
_, err := nameFromQuery(msg)
|
||||
_, _, err := nameFromQuery(msg)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user