net: respect resolv.conf rotate option

Instead of ranging over servers in the config, grab an offset
from the config that is used to determine indices.

When the rotate option is enabled, the offset increases which
rotates queries through servers. Otherwise, it is always 0
which uses servers in config order.

Fixes #17126

Change-Id: If233f6de7bfa42f88570055b9ab631be08a76b3e
Reviewed-on: https://go-review.googlesource.com/29233
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Dan Peterson 2016-09-15 17:24:42 -03:00 committed by Matthew Dempsky
parent f7e49f6644
commit a1bf203b57
3 changed files with 90 additions and 6 deletions

View file

@ -797,3 +797,73 @@ func TestRetryTimeout(t *testing.T) {
t.Error("deadline0 still zero", deadline0)
}
}
func TestRotate(t *testing.T) {
// without rotation, always uses the first server
testRotate(t, false, []string{"192.0.2.1", "192.0.2.2"}, []string{"192.0.2.1:53", "192.0.2.1:53", "192.0.2.1:53"})
// with rotation, rotates through back to first
testRotate(t, true, []string{"192.0.2.1", "192.0.2.2"}, []string{"192.0.2.1:53", "192.0.2.2:53", "192.0.2.1:53"})
}
func testRotate(t *testing.T, rotate bool, nameservers, wantServers []string) {
origTestHookDNSDialer := testHookDNSDialer
defer func() { testHookDNSDialer = origTestHookDNSDialer }()
conf, err := newResolvConfTest()
if err != nil {
t.Fatal(err)
}
defer conf.teardown()
var confLines []string
for _, ns := range nameservers {
confLines = append(confLines, "nameserver "+ns)
}
if rotate {
confLines = append(confLines, "options rotate")
}
if err := conf.writeAndUpdate(confLines); err != nil {
t.Fatal(err)
}
d := &fakeDNSDialer{}
testHookDNSDialer = func() dnsDialer { return d }
var usedServers []string
d.rh = func(s string, q *dnsMsg, _ time.Time) (*dnsMsg, error) {
usedServers = append(usedServers, s)
r := &dnsMsg{
dnsMsgHdr: dnsMsgHdr{
id: q.id,
response: true,
recursion_available: true,
},
question: q.question,
answer: []dnsRR{
&dnsRR_CNAME{
Hdr: dnsRR_Header{
Name: q.question[0].Name,
Rrtype: dnsTypeCNAME,
Class: dnsClassINET,
},
Cname: "golang.org",
},
},
}
return r, nil
}
// len(nameservers) + 1 to allow rotation to get back to start
for i := 0; i < len(nameservers)+1; i++ {
if _, err := goLookupCNAME(context.Background(), "www.golang.org"); err != nil {
t.Fatal(err)
}
}
if !reflect.DeepEqual(usedServers, wantServers) {
t.Fatalf("rotate=%t got used servers:\n%v\nwant:\n%v", rotate, usedServers, wantServers)
}
}