From ea7cb3c6cd0467a7db783fbd30aa8599604a76d8 Mon Sep 17 00:00:00 2001 From: Karan Sharma Date: Thu, 2 Jun 2022 14:59:27 +0530 Subject: [PATCH] fix: fallback to tcp if response is truncated Based on a report `doggo txt google.com @udp://1.1.1.1` failed. This record had 704 bytes as the message length however the response gets truncated if it exceeds 512 bytes with UDP. `dig` transparently fallbacks to `tcp`, so this commit adds the same mechanism. --- pkg/resolvers/classic.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkg/resolvers/classic.go b/pkg/resolvers/classic.go index b922400..366e1d0 100644 --- a/pkg/resolvers/classic.go +++ b/pkg/resolvers/classic.go @@ -79,6 +79,24 @@ func (r *ClassicResolver) Lookup(question dns.Question) (Response, error) { if err != nil { return rsp, err } + + // In case the response size exceeds 512 bytes (can happen with lot of TXT records), + // fallback to TCP as with UDP the response is truncated. Fallback mechanism is in-line with `dig`. + if in.Truncated { + switch r.client.Net { + case "udp": + r.client.Net = "tcp" + case "udp4": + r.client.Net = "tcp4" + case "udp6": + r.client.Net = "tcp6" + default: + r.client.Net = "tcp" + } + r.resolverOptions.Logger.WithField("protocol", r.client.Net).Debug("Response truncated; retrying now") + return r.Lookup(question) + } + // Pack questions in output. for _, q := range msg.Question { ques := Question{