net: make Resolver.PreferGo work more as documented
Fixes #24393
Change-Id: I8bcee34cdf30472663d866ed6056301d8445215c
Reviewed-on: https://go-review.googlesource.com/100875
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/net/conf.go b/src/net/conf.go
index c10aafe..2c21331 100644
--- a/src/net/conf.go
+++ b/src/net/conf.go
@@ -114,18 +114,19 @@
// canUseCgo reports whether calling cgo functions is allowed
// for non-hostname lookups.
func (c *conf) canUseCgo() bool {
- return c.hostLookupOrder("") == hostLookupCgo
+ return c.hostLookupOrder(nil, "") == hostLookupCgo
}
// hostLookupOrder determines which strategy to use to resolve hostname.
-func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
+// The provided Resolver is optional. nil means to not consider its options.
+func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder) {
if c.dnsDebugLevel > 1 {
defer func() {
print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
}()
}
fallbackOrder := hostLookupCgo
- if c.netGo {
+ if c.netGo || (r != nil && r.PreferGo) {
fallbackOrder = hostLookupFilesDNS
}
if c.forceCgoLookupHost || c.resolv.unknownOpt || c.goos == "android" {
diff --git a/src/net/conf_test.go b/src/net/conf_test.go
index 17d03f4..a6d6987 100644
--- a/src/net/conf_test.go
+++ b/src/net/conf_test.go
@@ -33,6 +33,7 @@
tests := []struct {
name string
c *conf
+ resolver *Resolver
hostTests []nssHostTest
}{
{
@@ -322,6 +323,21 @@
{"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
+ resolv: defaultResolvConf,
+ nss: nssStr(""),
+ netCgo: true,
+ },
+ hostTests: []nssHostTest{
+ {"localhost", "myhostname", hostLookupFilesDNS},
+ },
+ },
}
origGetHostname := getHostname
@@ -331,7 +347,7 @@
for _, ht := range tt.hostTests {
getHostname = func() (string, error) { return ht.localhost, nil }
- gotOrder := tt.c.hostLookupOrder(ht.host)
+ 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)
}
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index d2a6dc4..7ca5d60 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -524,7 +524,7 @@
// goLookupIP is the native Go implementation of LookupIP.
// The libc versions are in cgo_*.go.
func (r *Resolver) goLookupIP(ctx context.Context, host string) (addrs []IPAddr, err error) {
- order := systemConf().hostLookupOrder(host)
+ order := systemConf().hostLookupOrder(r, host)
addrs, _, err = r.goLookupIPCNAMEOrder(ctx, host, order)
return
}
@@ -676,7 +676,7 @@
// goLookupCNAME is the native Go (non-cgo) implementation of LookupCNAME.
func (r *Resolver) goLookupCNAME(ctx context.Context, host string) (string, error) {
- order := systemConf().hostLookupOrder(host)
+ order := systemConf().hostLookupOrder(r, host)
_, cname, err := r.goLookupIPCNAMEOrder(ctx, host, order)
return cname.String(), err
}
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go
index 0b92242..8e77b8c 100644
--- a/src/net/lookup_unix.go
+++ b/src/net/lookup_unix.go
@@ -74,7 +74,7 @@
}
func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string, err error) {
- order := systemConf().hostLookupOrder(host)
+ order := systemConf().hostLookupOrder(r, host)
if !r.PreferGo && order == hostLookupCgo {
if addrs, err, ok := cgoLookupHost(ctx, host); ok {
return addrs, err
@@ -89,7 +89,7 @@
if r.PreferGo {
return r.goLookupIP(ctx, host)
}
- order := systemConf().hostLookupOrder(host)
+ order := systemConf().hostLookupOrder(r, host)
if order == hostLookupCgo {
if addrs, err, ok := cgoLookupIP(ctx, host); ok {
return addrs, err