mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 13:05:46 +00:00
net/dns/resolver: add metric for number of truncated dns packets
Updates #2067 This should help us determine if more robust control of edns parameters + implementing answer truncation is warranted, given its likely complexity. Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
parent
80ba161c40
commit
5fb8e01a8b
@ -41,6 +41,19 @@
|
|||||||
// headerBytes is the number of bytes in a DNS message header.
|
// headerBytes is the number of bytes in a DNS message header.
|
||||||
const headerBytes = 12
|
const headerBytes = 12
|
||||||
|
|
||||||
|
// dnsFlagTruncated is set in the flags word when the packet is truncated.
|
||||||
|
const dnsFlagTruncated = 0x200
|
||||||
|
|
||||||
|
// truncatedFlagSet returns true if the DNS packet signals that it has
|
||||||
|
// been truncated. False is also returned if the packet was too small
|
||||||
|
// to be valid.
|
||||||
|
func truncatedFlagSet(pkt []byte) bool {
|
||||||
|
if len(pkt) < headerBytes {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (binary.BigEndian.Uint16(pkt[2:4]) & dnsFlagTruncated) != 0
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// responseTimeout is the maximal amount of time to wait for a DNS response.
|
// responseTimeout is the maximal amount of time to wait for a DNS response.
|
||||||
responseTimeout = 5 * time.Second
|
responseTimeout = 5 * time.Second
|
||||||
@ -420,6 +433,9 @@ func (f *forwarder) sendDoH(ctx context.Context, urlBase string, c *http.Client,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
metricDNSFwdDoHErrorBody.Add(1)
|
metricDNSFwdDoHErrorBody.Add(1)
|
||||||
}
|
}
|
||||||
|
if truncatedFlagSet(res) {
|
||||||
|
metricDNSFwdTruncated.Add(1)
|
||||||
|
}
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,13 +472,18 @@ func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDe
|
|||||||
metricDNSFwdErrorType.Add(1)
|
metricDNSFwdErrorType.Add(1)
|
||||||
return nil, fmt.Errorf("tls:// resolvers not supported yet")
|
return nil, fmt.Errorf("tls:// resolvers not supported yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return f.sendUDP(ctx, fq, rr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *forwarder) sendUDP(ctx context.Context, fq *forwardQuery, rr resolverAndDelay) (ret []byte, err error) {
|
||||||
ipp, ok := rr.name.IPPort()
|
ipp, ok := rr.name.IPPort()
|
||||||
if !ok {
|
if !ok {
|
||||||
metricDNSFwdErrorType.Add(1)
|
metricDNSFwdErrorType.Add(1)
|
||||||
return nil, fmt.Errorf("unrecognized resolver type %q", rr.name.Addr)
|
return nil, fmt.Errorf("unrecognized resolver type %q", rr.name.Addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
metricDNSFwdUDP.Add(1)
|
metricDNSFwdUDP.Add(1)
|
||||||
|
|
||||||
ln, err := f.packetListener(ipp.IP())
|
ln, err := f.packetListener(ipp.IP())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -522,7 +543,7 @@ func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if truncated {
|
if truncated {
|
||||||
const dnsFlagTruncated = 0x200
|
// Set the truncated bit if it wasn't already.
|
||||||
flags := binary.BigEndian.Uint16(out[2:4])
|
flags := binary.BigEndian.Uint16(out[2:4])
|
||||||
flags |= dnsFlagTruncated
|
flags |= dnsFlagTruncated
|
||||||
binary.BigEndian.PutUint16(out[2:4], flags)
|
binary.BigEndian.PutUint16(out[2:4], flags)
|
||||||
@ -534,6 +555,10 @@ func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDe
|
|||||||
// best we can do.
|
// best we can do.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if truncatedFlagSet(out) {
|
||||||
|
metricDNSFwdTruncated.Add(1)
|
||||||
|
}
|
||||||
|
|
||||||
clampEDNSSize(out, maxResponseBytes)
|
clampEDNSSize(out, maxResponseBytes)
|
||||||
metricDNSFwdUDPSuccess.Add(1)
|
metricDNSFwdUDPSuccess.Add(1)
|
||||||
return out, nil
|
return out, nil
|
||||||
|
@ -1340,6 +1340,7 @@ func unARPA(a string) (ipStr string, ok bool) {
|
|||||||
|
|
||||||
metricDNSFwdErrorType = clientmetric.NewCounter("dns_query_fwd_error_type")
|
metricDNSFwdErrorType = clientmetric.NewCounter("dns_query_fwd_error_type")
|
||||||
metricDNSFwdErrorParseAddr = clientmetric.NewCounter("dns_query_fwd_error_parse_addr")
|
metricDNSFwdErrorParseAddr = clientmetric.NewCounter("dns_query_fwd_error_parse_addr")
|
||||||
|
metricDNSFwdTruncated = clientmetric.NewCounter("dns_query_fwd_truncated")
|
||||||
|
|
||||||
metricDNSFwdUDP = clientmetric.NewCounter("dns_query_fwd_udp") // on entry
|
metricDNSFwdUDP = clientmetric.NewCounter("dns_query_fwd_udp") // on entry
|
||||||
metricDNSFwdUDPWrote = clientmetric.NewCounter("dns_query_fwd_udp_wrote") // sent UDP packet
|
metricDNSFwdUDPWrote = clientmetric.NewCounter("dns_query_fwd_udp_wrote") // sent UDP packet
|
||||||
|
Loading…
Reference in New Issue
Block a user