1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 type nssHostTest struct {
22 func nssStr(t *testing.T, s string) *nssConf {
23 f, err := os.CreateTemp(t.TempDir(), "nss")
27 if _, err := f.WriteString(s); err != nil {
30 if err := f.Close(); err != nil {
33 return parseNSSConfFile(f.Name())
36 // represents a dnsConfig returned by parsing a nonexistent resolv.conf
37 var defaultResolvConf = &dnsConfig{
45 func TestConfHostLookupOrder(t *testing.T) {
46 // These tests are written for a system with cgo available,
47 // without using the netgo tag.
49 t.Skip("skipping test because net package built with netgo tag")
52 t.Skip("skipping test because cgo resolver not available")
61 hostTests []nssHostTest
69 resolv: defaultResolvConf,
70 nss: nssStr(t, "foo: bar"),
71 hostTests: []nssHostTest{
72 {"foo.local", "myhostname", hostLookupCgo},
73 {"google.com", "myhostname", hostLookupCgo},
77 name: "netgo_dns_before_files",
81 resolv: defaultResolvConf,
82 nss: nssStr(t, "hosts: dns files"),
83 hostTests: []nssHostTest{
84 {"x.com", "myhostname", hostLookupDNSFiles},
88 name: "netgo_fallback_on_cgo",
92 resolv: defaultResolvConf,
93 nss: nssStr(t, "hosts: dns files something_custom"),
94 hostTests: []nssHostTest{
95 {"x.com", "myhostname", hostLookupDNSFiles},
99 name: "ubuntu_trusty_avahi",
101 mdnsTest: mdnsAssumeDoesNotExist,
103 resolv: defaultResolvConf,
104 nss: nssStr(t, "hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4"),
105 hostTests: []nssHostTest{
106 {"foo.local", "myhostname", hostLookupCgo},
107 {"foo.local.", "myhostname", hostLookupCgo},
108 {"foo.LOCAL", "myhostname", hostLookupCgo},
109 {"foo.LOCAL.", "myhostname", hostLookupCgo},
110 {"google.com", "myhostname", hostLookupFilesDNS},
114 name: "freebsdlinux_no_resolv_conf",
118 resolv: defaultResolvConf,
119 nss: nssStr(t, "foo: bar"),
120 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
122 // On OpenBSD, no resolv.conf means no DNS.
124 name: "openbsd_no_resolv_conf",
128 resolv: defaultResolvConf,
129 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
132 name: "solaris_no_nsswitch",
136 resolv: defaultResolvConf,
137 nss: &nssConf{err: fs.ErrNotExist},
138 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
141 name: "openbsd_lookup_bind_file",
145 resolv: &dnsConfig{lookup: []string{"bind", "file"}},
146 hostTests: []nssHostTest{
147 {"google.com", "myhostname", hostLookupDNSFiles},
148 {"foo.local", "myhostname", hostLookupDNSFiles},
152 name: "openbsd_lookup_file_bind",
156 resolv: &dnsConfig{lookup: []string{"file", "bind"}},
157 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
160 name: "openbsd_lookup_bind",
164 resolv: &dnsConfig{lookup: []string{"bind"}},
165 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNS}},
168 name: "openbsd_lookup_file",
172 resolv: &dnsConfig{lookup: []string{"file"}},
173 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
176 name: "openbsd_lookup_yp",
180 resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}},
181 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
184 name: "openbsd_lookup_two",
188 resolv: &dnsConfig{lookup: []string{"file", "foo"}},
189 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
192 name: "openbsd_lookup_empty",
196 resolv: &dnsConfig{lookup: nil},
197 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}},
200 name: "linux_no_nsswitch.conf",
204 resolv: defaultResolvConf,
205 nss: &nssConf{err: fs.ErrNotExist},
206 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
209 name: "linux_empty_nsswitch.conf",
213 resolv: defaultResolvConf,
215 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
218 name: "files_mdns_dns",
220 mdnsTest: mdnsAssumeDoesNotExist,
222 resolv: defaultResolvConf,
223 nss: nssStr(t, "hosts: files mdns dns"),
224 hostTests: []nssHostTest{
225 {"x.com", "myhostname", hostLookupFilesDNS},
226 {"x.local", "myhostname", hostLookupCgo},
230 name: "dns_special_hostnames",
232 resolv: defaultResolvConf,
233 nss: nssStr(t, "hosts: dns"),
234 hostTests: []nssHostTest{
235 {"x.com", "myhostname", hostLookupDNS},
236 {"x\\.com", "myhostname", hostLookupCgo}, // punt on weird glibc escape
237 {"foo.com%en0", "myhostname", hostLookupCgo}, // and IPv6 zones
243 mdnsTest: mdnsAssumeExists,
245 resolv: defaultResolvConf,
246 nss: nssStr(t, "hosts: files mdns dns"),
247 hostTests: []nssHostTest{
248 {"x.com", "myhostname", hostLookupCgo},
249 {"x.local", "myhostname", hostLookupCgo},
255 resolv: defaultResolvConf,
256 nss: nssStr(t, "hosts: files dns"),
257 hostTests: []nssHostTest{
258 {"x.com", "myhostname", hostLookupFilesDNS},
259 {"x", "myhostname", hostLookupFilesDNS},
260 {"x.local", "myhostname", hostLookupCgo},
266 resolv: defaultResolvConf,
267 nss: nssStr(t, "hosts: dns files"),
268 hostTests: []nssHostTest{
269 {"x.com", "myhostname", hostLookupDNSFiles},
270 {"x", "myhostname", hostLookupDNSFiles},
271 {"x.local", "myhostname", hostLookupCgo},
275 name: "something_custom",
277 resolv: defaultResolvConf,
278 nss: nssStr(t, "hosts: dns files something_custom"),
279 hostTests: []nssHostTest{
280 {"x.com", "myhostname", hostLookupCgo},
286 resolv: defaultResolvConf,
287 nss: nssStr(t, "hosts: files dns myhostname"),
288 hostTests: []nssHostTest{
289 {"x.com", "myhostname", hostLookupFilesDNS},
290 {"myhostname", "myhostname", hostLookupCgo},
291 {"myHostname", "myhostname", hostLookupCgo},
292 {"myhostname.dot", "myhostname.dot", hostLookupCgo},
293 {"myHostname.dot", "myhostname.dot", hostLookupCgo},
294 {"_gateway", "myhostname", hostLookupCgo},
295 {"_Gateway", "myhostname", hostLookupCgo},
296 {"_outbound", "myhostname", hostLookupCgo},
297 {"_Outbound", "myhostname", hostLookupCgo},
298 {"localhost", "myhostname", hostLookupCgo},
299 {"Localhost", "myhostname", hostLookupCgo},
300 {"anything.localhost", "myhostname", hostLookupCgo},
301 {"Anything.localhost", "myhostname", hostLookupCgo},
302 {"localhost.localdomain", "myhostname", hostLookupCgo},
303 {"Localhost.Localdomain", "myhostname", hostLookupCgo},
304 {"anything.localhost.localdomain", "myhostname", hostLookupCgo},
305 {"Anything.Localhost.Localdomain", "myhostname", hostLookupCgo},
306 {"somehostname", "myhostname", hostLookupFilesDNS},
310 name: "ubuntu14.04.02",
312 mdnsTest: mdnsAssumeDoesNotExist,
314 resolv: defaultResolvConf,
315 nss: nssStr(t, "hosts: files myhostname mdns4_minimal [NOTFOUND=return] dns mdns4"),
316 hostTests: []nssHostTest{
317 {"x.com", "myhostname", hostLookupFilesDNS},
318 {"somehostname", "myhostname", hostLookupFilesDNS},
319 {"myhostname", "myhostname", hostLookupCgo},
322 // Debian Squeeze is just "dns,files", but lists all
323 // the default criteria for dns, but then has a
324 // non-standard but redundant notfound=return for the
327 name: "debian_squeeze",
329 resolv: defaultResolvConf,
330 nss: nssStr(t, "hosts: dns [success=return notfound=continue unavail=continue tryagain=continue] files [notfound=return]"),
331 hostTests: []nssHostTest{
332 {"x.com", "myhostname", hostLookupDNSFiles},
333 {"somehostname", "myhostname", hostLookupDNSFiles},
337 name: "resolv.conf-unknown",
339 resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true},
340 nss: nssStr(t, "foo: bar"),
341 hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
343 // Issue 24393: make sure "Resolver.PreferGo = true" acts like netgo.
345 name: "resolver-prefergo",
346 resolver: &Resolver{PreferGo: true},
351 resolv: defaultResolvConf,
353 hostTests: []nssHostTest{
354 {"localhost", "myhostname", hostLookupFilesDNS},
358 name: "unknown-source",
359 resolver: &Resolver{PreferGo: true},
361 resolv: defaultResolvConf,
362 nss: nssStr(t, "hosts: resolve files"),
363 hostTests: []nssHostTest{
364 {"x.com", "myhostname", hostLookupDNSFiles},
368 name: "dns-among-unknown-sources",
369 resolver: &Resolver{PreferGo: true},
371 resolv: defaultResolvConf,
372 nss: nssStr(t, "hosts: mymachines files dns"),
373 hostTests: []nssHostTest{
374 {"x.com", "myhostname", hostLookupFilesDNS},
378 name: "dns-among-unknown-sources-2",
379 resolver: &Resolver{PreferGo: true},
381 resolv: defaultResolvConf,
382 nss: nssStr(t, "hosts: dns mymachines files"),
383 hostTests: []nssHostTest{
384 {"x.com", "myhostname", hostLookupDNSFiles},
389 origGetHostname := getHostname
390 defer func() { getHostname = origGetHostname }()
391 defer setSystemNSS(getSystemNSS(), 0)
392 conf, err := newResolvConfTest()
396 defer conf.teardown()
398 for _, tt := range tests {
399 if !conf.forceUpdateConf(tt.resolv, time.Now().Add(time.Hour)) {
400 t.Errorf("%s: failed to change resolv config", tt.name)
402 for _, ht := range tt.hostTests {
403 getHostname = func() (string, error) { return ht.localhost, nil }
404 setSystemNSS(tt.nss, time.Hour)
406 gotOrder, _ := tt.c.hostLookupOrder(tt.resolver, ht.host)
407 if gotOrder != ht.want {
408 t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want)
414 func TestAddrLookupOrder(t *testing.T) {
415 // This test is written for a system with cgo available,
416 // without using the netgo tag.
418 t.Skip("skipping test because net package built with netgo tag")
421 t.Skip("skipping test because cgo resolver not available")
424 defer setSystemNSS(getSystemNSS(), 0)
425 c, err := newResolvConfTest()
431 if !c.forceUpdateConf(defaultResolvConf, time.Now().Add(time.Hour)) {
432 t.Fatal("failed to change resolv config")
435 setSystemNSS(nssStr(t, "hosts: files myhostname dns"), time.Hour)
437 order, _ := cnf.addrLookupOrder(nil, "192.0.2.1")
438 if order != hostLookupCgo {
439 t.Errorf("addrLookupOrder returned: %v, want cgo", order)
442 setSystemNSS(nssStr(t, "hosts: files mdns4 dns"), time.Hour)
443 order, _ = cnf.addrLookupOrder(nil, "192.0.2.1")
444 if order != hostLookupCgo {
445 t.Errorf("addrLookupOrder returned: %v, want cgo", order)
450 func setSystemNSS(nss *nssConf, addDur time.Duration) {
452 nssConfig.nssConf = nss
453 nssConfig.mu.Unlock()
454 nssConfig.acquireSema()
455 nssConfig.lastChecked = time.Now().Add(addDur)
456 nssConfig.releaseSema()
459 func TestSystemConf(t *testing.T) {