Skip to content

Commit

Permalink
net/dnscache: use Go DNS resolver on Windows
Browse files Browse the repository at this point in the history
Go 1.19 introduced Resolver.PreferGo which allows the Go resolver
to be used on Windows.

See golang/go#33097.

Fixes tailscale#5161

Signed-off-by: Thomas Way <thomas@6f.io>
  • Loading branch information
uhthomas committed Apr 21, 2023
1 parent 6f521c1 commit 0860c7a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 10 deletions.
15 changes: 5 additions & 10 deletions net/dnscache/dnscache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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()
Expand Down
72 changes: 72 additions & 0 deletions net/dnscache/dnscache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 0860c7a

Please sign in to comment.