aboutsummaryrefslogtreecommitdiff
path: root/src/net/dnsclient_unix.go
diff options
context:
space:
mode:
authorjfbus <jf@bustarret.com>2019-04-18 12:39:24 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2019-04-18 18:51:13 +0000
commit825ff1e3171a97fba1f29473d0be484ebfdc08b4 (patch)
treee6279276986c5e2c31b92970a222fb7e0a6c2019 /src/net/dnsclient_unix.go
parente900964e0f2709fe9ac5d4c8f760c3398ec0bbbd (diff)
downloadgo-825ff1e3171a97fba1f29473d0be484ebfdc08b4.tar.gz
go-825ff1e3171a97fba1f29473d0be484ebfdc08b4.zip
net: use DNS over TCP when use-vc is set in resolv.conf
There is a DNS resolution bug in Kubernetes (UDP response packets get dropped by conntrack, causing timeouts in DNS queries). The recommended workaround on Linux is to configure the resolver to use TCP for DNS queries, by setting the use-vc option in resolv.conf. With this PR, the pure Go resolver searches for "use-vc" in resolv.conf and switches to TCP when found. Fixes #29358 Change-Id: I26b935cae2c80e5bb9955da83299a8dea84591de GitHub-Last-Rev: 70bc00fe41f44f0b2b3cfebe67bbcc45701968cf GitHub-Pull-Request: golang/go#29594 Reviewed-on: https://go-review.googlesource.com/c/go/+/156366 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/dnsclient_unix.go')
-rw-r--r--src/net/dnsclient_unix.go18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index 4e7462b66fa..7ed4ea8708c 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -26,6 +26,12 @@ import (
"golang.org/x/net/dns/dnsmessage"
)
+const (
+ // to be used as a useTCP parameter to exchange
+ useTCPOnly = true
+ useUDPOrTCP = false
+)
+
var (
errLameReferral = errors.New("lame referral")
errCannotUnmarshalDNSMessage = errors.New("cannot unmarshal DNS message")
@@ -131,13 +137,19 @@ func dnsStreamRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte)
}
// exchange sends a query on the connection and hopes for a response.
-func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration) (dnsmessage.Parser, dnsmessage.Header, error) {
+func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, useTCP bool) (dnsmessage.Parser, dnsmessage.Header, error) {
q.Class = dnsmessage.ClassINET
id, udpReq, tcpReq, err := newRequest(q)
if err != nil {
return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage
}
- for _, network := range []string{"udp", "tcp"} {
+ var networks []string
+ if useTCP {
+ networks = []string{"tcp"}
+ } else {
+ networks = []string{"udp", "tcp"}
+ }
+ for _, network := range networks {
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout))
defer cancel()
@@ -241,7 +253,7 @@ func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string,
for j := uint32(0); j < sLen; j++ {
server := cfg.servers[(serverOffset+j)%sLen]
- p, h, err := r.exchange(ctx, server, q, cfg.timeout)
+ p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.useTCP)
if err != nil {
dnsErr := &DNSError{
Err: err.Error(),