aboutsummaryrefslogtreecommitdiff
path: root/src/net/dnsclient_unix_test.go
diff options
context:
space:
mode:
authorjfbus <jf@bustarret.com>2019-03-26 18:21:53 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2019-04-17 14:42:35 +0000
commitdbc17037815bdce5df3f355f2171c57804f7870e (patch)
treed1b7e6669f254f3642b3e9aa3c11d151cc6d9bb5 /src/net/dnsclient_unix_test.go
parent33e5da48d5d22a722f2363b15e2d53061fb71cf4 (diff)
downloadgo-dbc17037815bdce5df3f355f2171c57804f7870e.tar.gz
go-dbc17037815bdce5df3f355f2171c57804f7870e.zip
net: support single-request resolv.conf option in pure Go resolver
There is a DNS resolution issue in Kubernetes (UDP response packets get dropped due to a race in conntrack between the parallel A and AAAA queries, causing timeouts in DNS queries). A workaround is to enable single-request / single-request-reopen in resolv.conf in order to use sequential A and AAAA queries instead of parallel queries. With this PR, the pure Go resolver searches for "single-request" and "single-request-reopen" in resolv.conf and send A and AAAA queries sequentially when found. Fixes #29644 Change-Id: I906b3484008c1b9adf2e3e9241ea23767e29df59 GitHub-Last-Rev: d481acfb4c49d82fd474078b31a1a4697b57dadf GitHub-Pull-Request: golang/go#29661 Reviewed-on: https://go-review.googlesource.com/c/go/+/157377 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_test.go')
-rw-r--r--src/net/dnsclient_unix_test.go74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 810f400f0bd..51d54a4ccad 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -17,6 +17,7 @@ import (
"reflect"
"strings"
"sync"
+ "sync/atomic"
"testing"
"time"
@@ -1621,3 +1622,76 @@ func TestTXTRecordTwoStrings(t *testing.T) {
t.Errorf("txt[1], got %q, want %q", txt[1], want)
}
}
+
+// Issue 29644: support single-request resolv.conf option in pure Go resolver.
+// The A and AAAA queries will be sent sequentially, not in parallel.
+func TestSingleRequestLookup(t *testing.T) {
+ defer dnsWaitGroup.Wait()
+ var (
+ firstcalled int32
+ ipv4 int32 = 1
+ ipv6 int32 = 2
+ )
+ fake := fakeDNSServer{rh: func(n, s string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+ r := dnsmessage.Message{
+ Header: dnsmessage.Header{
+ ID: q.ID,
+ Response: true,
+ },
+ Questions: q.Questions,
+ }
+ for _, question := range q.Questions {
+ switch question.Type {
+ case dnsmessage.TypeA:
+ if question.Name.String() == "slowipv4.example.net." {
+ time.Sleep(10 * time.Millisecond)
+ }
+ if !atomic.CompareAndSwapInt32(&firstcalled, 0, ipv4) {
+ t.Errorf("the A query was received after the AAAA query !")
+ }
+ r.Answers = append(r.Answers, dnsmessage.Resource{
+ Header: dnsmessage.ResourceHeader{
+ Name: q.Questions[0].Name,
+ Type: dnsmessage.TypeA,
+ Class: dnsmessage.ClassINET,
+ Length: 4,
+ },
+ Body: &dnsmessage.AResource{
+ A: TestAddr,
+ },
+ })
+ case dnsmessage.TypeAAAA:
+ atomic.CompareAndSwapInt32(&firstcalled, 0, ipv6)
+ r.Answers = append(r.Answers, dnsmessage.Resource{
+ Header: dnsmessage.ResourceHeader{
+ Name: q.Questions[0].Name,
+ Type: dnsmessage.TypeAAAA,
+ Class: dnsmessage.ClassINET,
+ Length: 16,
+ },
+ Body: &dnsmessage.AAAAResource{
+ AAAA: TestAddr6,
+ },
+ })
+ }
+ }
+ return r, nil
+ }}
+ r := Resolver{PreferGo: true, Dial: fake.DialContext}
+
+ conf, err := newResolvConfTest()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conf.teardown()
+ if err := conf.writeAndUpdate([]string{"options single-request"}); err != nil {
+ t.Fatal(err)
+ }
+ for _, name := range []string{"hostname.example.net", "slowipv4.example.net"} {
+ firstcalled = 0
+ _, err := r.LookupIPAddr(context.Background(), name)
+ if err != nil {
+ t.Error(err)
+ }
+ }
+}