return c.netGo || r.preferGo() || !cgoAvailable
}
+// addrLookupOrder determines which strategy to use to resolve addresses.
+// The provided Resolver is optional. nil means to not consider its options.
+// It also returns dnsConfig when it was used to determine the lookup order.
+func (c *conf) addrLookupOrder(r *Resolver, addr string) (ret hostLookupOrder, dnsConf *dnsConfig) {
+ if c.dnsDebugLevel > 1 {
+ defer func() {
+ print("go package net: addrLookupOrder(", addr, ") = ", ret.String(), "\n")
+ }()
+ }
+ return c.lookupOrder(r, "")
+}
+
// hostLookupOrder determines which strategy to use to resolve hostname.
// The provided Resolver is optional. nil means to not consider its options.
// It also returns dnsConfig when it was used to determine the lookup order.
print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
}()
}
+ return c.lookupOrder(r, hostname)
+}
+func (c *conf) lookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConf *dnsConfig) {
// fallbackOrder is the order we return if we can't figure it out.
var fallbackOrder hostLookupOrder
return fallbackOrder, dnsConf
}
- var mdnsSource, filesSource, dnsSource, unknownSource bool
+ var filesSource, dnsSource, unknownSource bool
var first string
for _, src := range srcs {
- if src.source == "myhostname" {
- // Let the cgo resolver handle myhostname
- // if we are looking up the local hostname.
- if canUseCgo {
- if isLocalhost(hostname) || isGateway(hostname) || isOutbound(hostname) {
- return hostLookupCgo, dnsConf
- }
- hn, err := getHostname()
- if err != nil || stringsEqualFold(hostname, hn) {
- return hostLookupCgo, dnsConf
- }
- }
- continue
- }
if src.source == "files" || src.source == "dns" {
if canUseCgo && !src.standardCriteria() {
// non-standard; let libc deal with it.
}
continue
}
- if stringsHasPrefix(src.source, "mdns") {
- // e.g. "mdns4", "mdns4_minimal"
- // We already returned true before if it was *.local.
- // libc wouldn't have found a hit on this anyway.
- mdnsSource = true
- continue
- }
- // Some source we don't know how to deal with.
+
if canUseCgo {
- return hostLookupCgo, dnsConf
+ switch {
+ case hostname != "" && src.source == "myhostname":
+ // Let the cgo resolver handle myhostname
+ // if we are looking up the local hostname.
+ if isLocalhost(hostname) || isGateway(hostname) || isOutbound(hostname) {
+ return hostLookupCgo, dnsConf
+ }
+ hn, err := getHostname()
+ if err != nil || stringsEqualFold(hostname, hn) {
+ return hostLookupCgo, dnsConf
+ }
+ continue
+ case hostname != "" && stringsHasPrefix(src.source, "mdns"):
+ // e.g. "mdns4", "mdns4_minimal"
+ // We already returned true before if it was *.local.
+ // libc wouldn't have found a hit on this anyway.
+
+ // We don't parse mdns.allow files. They're rare. If one
+ // exists, it might list other TLDs (besides .local) or even
+ // '*', so just let libc deal with it.
+ var haveMDNSAllow bool
+ switch c.mdnsTest {
+ case mdnsFromSystem:
+ _, err := os.Stat("/etc/mdns.allow")
+ if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ // Let libc figure out what is going on.
+ return hostLookupCgo, dnsConf
+ }
+ haveMDNSAllow = err == nil
+ case mdnsAssumeExists:
+ haveMDNSAllow = true
+ case mdnsAssumeDoesNotExist:
+ haveMDNSAllow = false
+ }
+ if haveMDNSAllow {
+ return hostLookupCgo, dnsConf
+ }
+ continue
+ default:
+ // Some source we don't know how to deal with.
+ return hostLookupCgo, dnsConf
+ }
}
unknownSource = true
}
}
- // We don't parse mdns.allow files. They're rare. If one
- // exists, it might list other TLDs (besides .local) or even
- // '*', so just let libc deal with it.
- if canUseCgo && mdnsSource {
- var haveMDNSAllow bool
- switch c.mdnsTest {
- case mdnsFromSystem:
- _, err := os.Stat("/etc/mdns.allow")
- if err != nil && !errors.Is(err, fs.ErrNotExist) {
- // Let libc figure out what is going on.
- return hostLookupCgo, dnsConf
- }
- haveMDNSAllow = err == nil
- case mdnsAssumeExists:
- haveMDNSAllow = true
- case mdnsAssumeDoesNotExist:
- haveMDNSAllow = false
- }
- if haveMDNSAllow {
- return hostLookupCgo, dnsConf
- }
- }
-
// If we saw a source we don't recognize, which can only
// happen if we can't use the cgo resolver, treat it as DNS.
if unknownSource {
{"anything.localhost.localdomain", "myhostname", hostLookupCgo},
{"Anything.Localhost.Localdomain", "myhostname", hostLookupCgo},
{"somehostname", "myhostname", hostLookupFilesDNS},
- {"", "myhostname", hostLookupFilesDNS}, // Issue 13623
},
},
{
}
}
+func TestAddrLookupOrder(t *testing.T) {
+ // This test is written for a system with cgo available,
+ // without using the netgo tag.
+ if netGoBuildTag {
+ t.Skip("skipping test because net package built with netgo tag")
+ }
+ if !cgoAvailable {
+ t.Skip("skipping test because cgo resolver not available")
+ }
+
+ defer setSystemNSS(getSystemNSS(), 0)
+ c, err := newResolvConfTest()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer c.teardown()
+
+ if !c.forceUpdateConf(defaultResolvConf, time.Now().Add(time.Hour)) {
+ t.Fatal("failed to change resolv config")
+ }
+
+ setSystemNSS(nssStr(t, "hosts: files myhostname dns"), time.Hour)
+ cnf := &conf{}
+ order, _ := cnf.addrLookupOrder(nil, "192.0.2.1")
+ if order != hostLookupCgo {
+ t.Errorf("addrLookupOrder returned: %v, want cgo", order)
+ }
+
+ setSystemNSS(nssStr(t, "hosts: files mdns4 dns"), time.Hour)
+ order, _ = cnf.addrLookupOrder(nil, "192.0.2.1")
+ if order != hostLookupCgo {
+ t.Errorf("addrLookupOrder returned: %v, want cgo", order)
+ }
+
+}
+
func setSystemNSS(nss *nssConf, addDur time.Duration) {
nssConfig.mu.Lock()
nssConfig.nssConf = nss