diff options
Diffstat (limited to 'src/net/conf_test.go')
-rw-r--r-- | src/net/conf_test.go | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/src/net/conf_test.go b/src/net/conf_test.go new file mode 100644 index 0000000..3736709 --- /dev/null +++ b/src/net/conf_test.go @@ -0,0 +1,393 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build unix + +package net + +import ( + "io/fs" + "os" + "testing" + "time" +) + +type nssHostTest struct { + host string + localhost string + want hostLookupOrder +} + +func nssStr(t *testing.T, s string) *nssConf { + f, err := os.CreateTemp(t.TempDir(), "nss") + if err != nil { + t.Fatal(err) + } + if _, err := f.WriteString(s); err != nil { + t.Fatal(err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } + return parseNSSConfFile(f.Name()) +} + +// represents a dnsConfig returned by parsing a nonexistent resolv.conf +var defaultResolvConf = &dnsConfig{ + servers: defaultNS, + ndots: 1, + timeout: 5, + attempts: 2, + err: fs.ErrNotExist, +} + +func TestConfHostLookupOrder(t *testing.T) { + tests := []struct { + name string + c *conf + nss *nssConf + resolver *Resolver + resolv *dnsConfig + hostTests []nssHostTest + }{ + { + name: "force", + c: &conf{ + forceCgoLookupHost: true, + }, + resolv: defaultResolvConf, + nss: nssStr(t, "foo: bar"), + hostTests: []nssHostTest{ + {"foo.local", "myhostname", hostLookupCgo}, + {"google.com", "myhostname", hostLookupCgo}, + }, + }, + { + name: "netgo_dns_before_files", + c: &conf{ + netGo: true, + }, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: dns files"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupDNSFiles}, + }, + }, + { + name: "netgo_fallback_on_cgo", + c: &conf{ + netGo: true, + }, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: dns files something_custom"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupFilesDNS}, + }, + }, + { + name: "ubuntu_trusty_avahi", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4"), + hostTests: []nssHostTest{ + {"foo.local", "myhostname", hostLookupCgo}, + {"foo.local.", "myhostname", hostLookupCgo}, + {"foo.LOCAL", "myhostname", hostLookupCgo}, + {"foo.LOCAL.", "myhostname", hostLookupCgo}, + {"google.com", "myhostname", hostLookupFilesDNS}, + }, + }, + { + name: "freebsdlinux_no_resolv_conf", + c: &conf{ + goos: "freebsd", + }, + resolv: defaultResolvConf, + nss: nssStr(t, "foo: bar"), + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}}, + }, + // On OpenBSD, no resolv.conf means no DNS. + { + name: "openbsd_no_resolv_conf", + c: &conf{ + goos: "openbsd", + }, + resolv: defaultResolvConf, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}}, + }, + { + name: "solaris_no_nsswitch", + c: &conf{ + goos: "solaris", + }, + resolv: defaultResolvConf, + nss: &nssConf{err: fs.ErrNotExist}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}}, + }, + { + name: "openbsd_lookup_bind_file", + c: &conf{ + goos: "openbsd", + }, + resolv: &dnsConfig{lookup: []string{"bind", "file"}}, + hostTests: []nssHostTest{ + {"google.com", "myhostname", hostLookupDNSFiles}, + {"foo.local", "myhostname", hostLookupDNSFiles}, + }, + }, + { + name: "openbsd_lookup_file_bind", + c: &conf{ + goos: "openbsd", + }, + resolv: &dnsConfig{lookup: []string{"file", "bind"}}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}}, + }, + { + name: "openbsd_lookup_bind", + c: &conf{ + goos: "openbsd", + }, + resolv: &dnsConfig{lookup: []string{"bind"}}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNS}}, + }, + { + name: "openbsd_lookup_file", + c: &conf{ + goos: "openbsd", + }, + resolv: &dnsConfig{lookup: []string{"file"}}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}}, + }, + { + name: "openbsd_lookup_yp", + c: &conf{ + goos: "openbsd", + }, + resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}}, + }, + { + name: "openbsd_lookup_two", + c: &conf{ + goos: "openbsd", + }, + resolv: &dnsConfig{lookup: []string{"file", "foo"}}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}}, + }, + { + name: "openbsd_lookup_empty", + c: &conf{ + goos: "openbsd", + }, + resolv: &dnsConfig{lookup: nil}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}}, + }, + { + name: "linux_no_nsswitch.conf", + c: &conf{ + goos: "linux", + }, + resolv: defaultResolvConf, + nss: &nssConf{err: fs.ErrNotExist}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}}, + }, + { + name: "linux_empty_nsswitch.conf", + c: &conf{ + goos: "linux", + }, + resolv: defaultResolvConf, + nss: nssStr(t, ""), + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}}, + }, + { + name: "files_mdns_dns", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: files mdns dns"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupFilesDNS}, + {"x.local", "myhostname", hostLookupCgo}, + }, + }, + { + name: "dns_special_hostnames", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: dns"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupDNS}, + {"x\\.com", "myhostname", hostLookupCgo}, // punt on weird glibc escape + {"foo.com%en0", "myhostname", hostLookupCgo}, // and IPv6 zones + }, + }, + { + name: "mdns_allow", + c: &conf{ + hasMDNSAllow: true, + }, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: files mdns dns"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupCgo}, + {"x.local", "myhostname", hostLookupCgo}, + }, + }, + { + name: "files_dns", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: files dns"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupFilesDNS}, + {"x", "myhostname", hostLookupFilesDNS}, + {"x.local", "myhostname", hostLookupCgo}, + }, + }, + { + name: "dns_files", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: dns files"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupDNSFiles}, + {"x", "myhostname", hostLookupDNSFiles}, + {"x.local", "myhostname", hostLookupCgo}, + }, + }, + { + name: "something_custom", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: dns files something_custom"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupCgo}, + }, + }, + { + name: "myhostname", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: files dns myhostname"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupFilesDNS}, + {"myhostname", "myhostname", hostLookupCgo}, + {"myHostname", "myhostname", hostLookupCgo}, + {"myhostname.dot", "myhostname.dot", hostLookupCgo}, + {"myHostname.dot", "myhostname.dot", hostLookupCgo}, + {"_gateway", "myhostname", hostLookupCgo}, + {"_Gateway", "myhostname", hostLookupCgo}, + {"_outbound", "myhostname", hostLookupCgo}, + {"_Outbound", "myhostname", hostLookupCgo}, + {"localhost", "myhostname", hostLookupCgo}, + {"Localhost", "myhostname", hostLookupCgo}, + {"anything.localhost", "myhostname", hostLookupCgo}, + {"Anything.localhost", "myhostname", hostLookupCgo}, + {"localhost.localdomain", "myhostname", hostLookupCgo}, + {"Localhost.Localdomain", "myhostname", hostLookupCgo}, + {"anything.localhost.localdomain", "myhostname", hostLookupCgo}, + {"Anything.Localhost.Localdomain", "myhostname", hostLookupCgo}, + {"somehostname", "myhostname", hostLookupFilesDNS}, + {"", "myhostname", hostLookupFilesDNS}, // Issue 13623 + }, + }, + { + name: "ubuntu14.04.02", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: files myhostname mdns4_minimal [NOTFOUND=return] dns mdns4"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupFilesDNS}, + {"somehostname", "myhostname", hostLookupFilesDNS}, + {"myhostname", "myhostname", hostLookupCgo}, + }, + }, + // Debian Squeeze is just "dns,files", but lists all + // the default criteria for dns, but then has a + // non-standard but redundant notfound=return for the + // files. + { + name: "debian_squeeze", + c: &conf{}, + resolv: defaultResolvConf, + nss: nssStr(t, "hosts: dns [success=return notfound=continue unavail=continue tryagain=continue] files [notfound=return]"), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupDNSFiles}, + {"somehostname", "myhostname", hostLookupDNSFiles}, + }, + }, + { + name: "resolv.conf-unknown", + c: &conf{}, + resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true}, + nss: nssStr(t, "foo: bar"), + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}}, + }, + // Android should always use cgo. + { + name: "android", + c: &conf{ + goos: "android", + }, + resolv: defaultResolvConf, + nss: nssStr(t, ""), + hostTests: []nssHostTest{ + {"x.com", "myhostname", hostLookupCgo}, + }, + }, + // Issue 24393: make sure "Resolver.PreferGo = true" acts like netgo. + { + name: "resolver-prefergo", + resolver: &Resolver{PreferGo: true}, + c: &conf{ + goos: "darwin", + forceCgoLookupHost: true, // always true for darwin + netCgo: true, + }, + resolv: defaultResolvConf, + nss: nssStr(t, ""), + hostTests: []nssHostTest{ + {"localhost", "myhostname", hostLookupFilesDNS}, + }, + }, + } + + origGetHostname := getHostname + defer func() { getHostname = origGetHostname }() + defer setSystemNSS(getSystemNSS(), 0) + conf, err := newResolvConfTest() + if err != nil { + t.Fatal(err) + } + defer conf.teardown() + + for _, tt := range tests { + if !conf.forceUpdateConf(tt.resolv, time.Now().Add(time.Hour)) { + t.Errorf("%s: failed to change resolv config", tt.name) + } + for _, ht := range tt.hostTests { + getHostname = func() (string, error) { return ht.localhost, nil } + setSystemNSS(tt.nss, time.Hour) + + gotOrder, _ := tt.c.hostLookupOrder(tt.resolver, ht.host) + if gotOrder != ht.want { + t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want) + } + } + } +} + +func setSystemNSS(nss *nssConf, addDur time.Duration) { + nssConfig.mu.Lock() + nssConfig.nssConf = nss + nssConfig.mu.Unlock() + nssConfig.acquireSema() + nssConfig.lastChecked = time.Now().Add(addDur) + nssConfig.releaseSema() +} + +func TestSystemConf(t *testing.T) { + systemConf() +} |