Commit ced0ba56 authored by Mikio Hara's avatar Mikio Hara

net: fix parsing literal IP address in builtin dns stub resolver

This CL fixes a bug introduced by CL 128820043 which is that
builtin dns stub resolver doesn't work well with literal IPv6
address namesever entries in /etc/resolv.conf.

Also simplifies resolv.conf parser and adds more test cases.

LGTM=iant
R=golang-codereviews, bradfitz, iant
CC=golang-codereviews
https://golang.org/cl/140040043
parent 55fa7659
...@@ -204,7 +204,7 @@ func TestReloadResolvConfChange(t *testing.T) { ...@@ -204,7 +204,7 @@ func TestReloadResolvConfChange(t *testing.T) {
if _, err := goLookupIP("golang.org"); err != nil { if _, err := goLookupIP("golang.org"); err != nil {
t.Fatalf("goLookupIP(good) failed: %v", err) t.Fatalf("goLookupIP(good) failed: %v", err)
} }
r.WantServers([]string{"[8.8.8.8]"}) r.WantServers([]string{"8.8.8.8"})
// Using a bad resolv.conf when we had a good one // Using a bad resolv.conf when we had a good one
// before should not update the config // before should not update the config
...@@ -215,7 +215,7 @@ func TestReloadResolvConfChange(t *testing.T) { ...@@ -215,7 +215,7 @@ func TestReloadResolvConfChange(t *testing.T) {
// A new good config should get picked up // A new good config should get picked up
r.SetConf("nameserver 8.8.4.4") r.SetConf("nameserver 8.8.4.4")
r.WantServers([]string{"[8.8.4.4]"}) r.WantServers([]string{"8.8.4.4"})
} }
func BenchmarkGoLookupIP(b *testing.B) { func BenchmarkGoLookupIP(b *testing.B) {
......
...@@ -25,13 +25,12 @@ func dnsReadConfig(filename string) (*dnsConfig, error) { ...@@ -25,13 +25,12 @@ func dnsReadConfig(filename string) (*dnsConfig, error) {
if err != nil { if err != nil {
return nil, &DNSConfigError{err} return nil, &DNSConfigError{err}
} }
conf := new(dnsConfig) defer file.close()
conf.servers = make([]string, 0, 3) // small, but the standard limit conf := &dnsConfig{
conf.search = make([]string, 0) ndots: 1,
conf.ndots = 1 timeout: 5,
conf.timeout = 5 attempts: 2,
conf.attempts = 2 }
conf.rotate = false
for line, ok := file.readLine(); ok; line, ok = file.readLine() { for line, ok := file.readLine(); ok; line, ok = file.readLine() {
f := getFields(line) f := getFields(line)
if len(f) < 1 { if len(f) < 1 {
...@@ -39,30 +38,18 @@ func dnsReadConfig(filename string) (*dnsConfig, error) { ...@@ -39,30 +38,18 @@ func dnsReadConfig(filename string) (*dnsConfig, error) {
} }
switch f[0] { switch f[0] {
case "nameserver": // add one name server case "nameserver": // add one name server
a := conf.servers if len(f) > 1 && len(conf.servers) < 3 { // small, but the standard limit
n := len(a)
if len(f) > 1 && n < cap(a) {
// One more check: make sure server name is // One more check: make sure server name is
// just an IP address. Otherwise we need DNS // just an IP address. Otherwise we need DNS
// to look it up. // to look it up.
name := f[1] if ParseIP(f[1]) != nil {
switch len(ParseIP(name)) { conf.servers = append(conf.servers, f[1])
case 16:
name = "[" + name + "]"
fallthrough
case 4:
a = a[0 : n+1]
a[n] = name
conf.servers = a
} }
} }
case "domain": // set search path to just this domain case "domain": // set search path to just this domain
if len(f) > 1 { if len(f) > 1 {
conf.search = make([]string, 1) conf.search = []string{f[1]}
conf.search[0] = f[1]
} else {
conf.search = make([]string, 0)
} }
case "search": // set search path to given servers case "search": // set search path to given servers
...@@ -99,8 +86,6 @@ func dnsReadConfig(filename string) (*dnsConfig, error) { ...@@ -99,8 +86,6 @@ func dnsReadConfig(filename string) (*dnsConfig, error) {
} }
} }
} }
file.close()
return conf, nil return conf, nil
} }
......
...@@ -6,41 +6,64 @@ ...@@ -6,41 +6,64 @@
package net package net
import "testing" import (
"reflect"
"testing"
)
func TestDNSReadConfig(t *testing.T) { var dnsReadConfigTests = []struct {
dnsConfig, err := dnsReadConfig("testdata/resolv.conf") name string
if err != nil { conf dnsConfig
t.Fatal(err) }{
} {
name: "testdata/resolv.conf",
if len(dnsConfig.servers) != 1 { conf: dnsConfig{
t.Errorf("len(dnsConfig.servers) = %d; want %d", len(dnsConfig.servers), 1) servers: []string{"8.8.8.8", "2001:4860:4860::8888"},
} search: []string{"localdomain"},
if dnsConfig.servers[0] != "[192.168.1.1]" { ndots: 5,
t.Errorf("dnsConfig.servers[0] = %s; want %s", dnsConfig.servers[0], "[192.168.1.1]") timeout: 10,
} attempts: 3,
rotate: true,
if len(dnsConfig.search) != 1 { },
t.Errorf("len(dnsConfig.search) = %d; want %d", len(dnsConfig.search), 1) },
} {
if dnsConfig.search[0] != "Home" { name: "testdata/domain-resolv.conf",
t.Errorf("dnsConfig.search[0] = %s; want %s", dnsConfig.search[0], "Home") conf: dnsConfig{
} servers: []string{"8.8.8.8"},
search: []string{"localdomain"},
if dnsConfig.ndots != 5 { ndots: 1,
t.Errorf("dnsConfig.ndots = %d; want %d", dnsConfig.ndots, 5) timeout: 5,
} attempts: 2,
},
if dnsConfig.timeout != 10 { },
t.Errorf("dnsConfig.timeout = %d; want %d", dnsConfig.timeout, 10) {
} name: "testdata/search-resolv.conf",
conf: dnsConfig{
if dnsConfig.attempts != 3 { servers: []string{"8.8.8.8"},
t.Errorf("dnsConfig.attempts = %d; want %d", dnsConfig.attempts, 3) search: []string{"test", "invalid"},
} ndots: 1,
timeout: 5,
attempts: 2,
},
},
{
name: "testdata/empty-resolv.conf",
conf: dnsConfig{
ndots: 1,
timeout: 5,
attempts: 2,
},
},
}
if dnsConfig.rotate != true { func TestDNSReadConfig(t *testing.T) {
t.Errorf("dnsConfig.rotate = %t; want %t", dnsConfig.rotate, true) for _, tt := range dnsReadConfigTests {
conf, err := dnsReadConfig(tt.name)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(conf, &tt.conf) {
t.Errorf("got %v; want %v", conf, &tt.conf)
}
} }
} }
# /etc/resolv.conf
search test invalid
domain localdomain
nameserver 8.8.8.8
# /etc/resolv.conf # /etc/resolv.conf
domain Home domain localdomain
nameserver 192.168.1.1 nameserver 8.8.8.8
nameserver 2001:4860:4860::8888
options ndots:5 timeout:10 attempts:3 rotate options ndots:5 timeout:10 attempts:3 rotate
options attempts 3 options attempts 3
# /etc/resolv.conf
domain localdomain
search test invalid
nameserver 8.8.8.8
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment