diff --git a/net/dnscache/dnscache.go b/net/dnscache/dnscache.go index 0983ae875..969e0b58d 100644 --- a/net/dnscache/dnscache.go +++ b/net/dnscache/dnscache.go @@ -31,19 +31,19 @@ import ( var zaddr netip.Addr var single = &Resolver{ - Forward: &net.Resolver{PreferGo: preferGoResolver()}, + Forward: &net.Resolver{PreferGo: preferGoResolver(runtime.GOOS)}, } -func preferGoResolver() bool { +func preferGoResolver(goos string) bool { // There does not appear to be a local resolver running // on iOS, and NetworkExtension is good at isolating DNS. // So do not use the Go resolver on macOS/iOS. - if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { + if goos == "darwin" || goos == "ios" { return false } // The local resolver is not available on Android. - if runtime.GOOS == "android" { + if goos == "android" { return false } @@ -140,12 +140,7 @@ func (r *Resolver) dlogf(format string, args ...any) { // cloudHostResolver returns a Resolver for the current cloud hosting environment. // It currently only supports Google Cloud. func (r *Resolver) cloudHostResolver() (v *net.Resolver, ok bool) { - switch runtime.GOOS { - case "android", "ios", "darwin": - return nil, false - case "windows": - // TODO(bradfitz): remove this restriction once we're using Go 1.19 - // which supports net.Resolver.PreferGo on Windows. + if !preferGoResolver(runtime.GOOS) { return nil, false } ip := cloudenv.Get().ResolverIP() diff --git a/net/dnscache/dnscache_test.go b/net/dnscache/dnscache_test.go index ef4249b74..8fcf9c9ec 100644 --- a/net/dnscache/dnscache_test.go +++ b/net/dnscache/dnscache_test.go @@ -37,6 +37,78 @@ func TestDialer(t *testing.T) { c.Close() } +func TestPreferGoResolver(t *testing.T) { + // List of all known GOOS values as of Go 1.20. + // + // https://github.com/golang/go/blob/go1.20.3/src/go/build/syslist.go#L14-L33 + testCases := []struct { + goos string + preferred bool + }{{ + goos: "aix", + preferred: true, + }, { + goos: "android", + preferred: false, + }, { + goos: "darwin", + preferred: false, + }, { + goos: "dragonfly", + preferred: true, + }, { + goos: "freebsd", + preferred: true, + }, { + goos: "hurd", + preferred: true, + }, { + goos: "illumos", + preferred: true, + }, { + goos: "ios", + preferred: false, + }, { + goos: "js", + preferred: true, + }, { + goos: "linux", + preferred: true, + }, { + goos: "nacl", + preferred: true, + }, { + goos: "netbsd", + preferred: true, + }, { + goos: "openbsd", + preferred: true, + }, { + goos: "plan9", + preferred: true, + }, { + goos: "solaris", + preferred: true, + }, { + goos: "wasip1", + preferred: true, + }, { + goos: "windows", + preferred: true, + }, { + goos: "zos", + preferred: true, + }} + for _, tc := range testCases { + t.Run(tc.goos, func(t *testing.T) { + preferred := preferGoResolver(tc.goos) + if preferred != tc.preferred { + t.Fatalf("%s: got %t, want %t", tc.goos, preferred, tc.preferred) + } + }) + } +} + func TestDialCall_DNSWasTrustworthy(t *testing.T) { type step struct { ip netip.Addr // IP we pretended to dial