aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Marks <pmarks@google.com>2016-11-01 21:01:08 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2017-03-09 21:59:00 +0000
commitbfc164c64d33edfaf774b5c29b9bf5648a6447fb (patch)
tree11b2a206e29f409ea482d63c800dbc91f017d25a /src
parentb0e91d836a0abd46899cf78fdd93303afcf6c637 (diff)
downloadgo-bfc164c64d33edfaf774b5c29b9bf5648a6447fb.tar.xz
net: add Resolver.StrictErrors
When LookupIP is performing multiple subqueries, this option causes a timeout/servfail affecting a single query to abort the whole operation, instead of returning a partial (IPv4/IPv6-only) result. Similarly, operations that walk the DNS search list will also abort when encountering one of these errors. Fixes #17448 Change-Id: Ice22e4aceb555c5a80d19bd1fde8b8fe87ac9517 Reviewed-on: https://go-review.googlesource.com/32572 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/net/dnsclient_unix.go50
-rw-r--r--src/net/dnsclient_unix_test.go349
-rw-r--r--src/net/lookup.go10
-rw-r--r--src/net/lookup_unix.go24
-rw-r--r--src/net/netgo_unix_test.go2
5 files changed, 393 insertions, 42 deletions
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index 4dd4e16b0f..6613dc7593 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -200,6 +200,11 @@ func tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype uint16)
if nerr, ok := err.(Error); ok && nerr.Timeout() {
lastErr.(*DNSError).IsTimeout = true
}
+ // Set IsTemporary for socket-level errors. Note that this flag
+ // may also be used to indicate a SERVFAIL response.
+ if _, ok := err.(*OpError); ok {
+ lastErr.(*DNSError).IsTemporary = true
+ }
continue
}
// libresolv continues to the next server when it receives
@@ -314,7 +319,7 @@ func (conf *resolverConfig) releaseSema() {
<-conf.ch
}
-func lookup(ctx context.Context, name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
+func (r *Resolver) lookup(ctx context.Context, name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
if !isDomainName(name) {
// We used to use "invalid domain name" as the error,
// but that is a detail of the specific lookup mechanism.
@@ -332,6 +337,11 @@ func lookup(ctx context.Context, name string, qtype uint16) (cname string, rrs [
if err == nil {
break
}
+ if nerr, ok := err.(Error); ok && nerr.Temporary() && r.StrictErrors {
+ // If we hit a temporary error with StrictErrors enabled,
+ // stop immediately instead of trying more names.
+ break
+ }
}
if err, ok := err.(*DNSError); ok {
// Show original name passed to lookup, not suffixed one.
@@ -432,11 +442,11 @@ func (o hostLookupOrder) String() string {
// Normally we let cgo use the C library resolver instead of
// depending on our lookup code, so that Go and C get the same
// answers.
-func goLookupHost(ctx context.Context, name string) (addrs []string, err error) {
- return goLookupHostOrder(ctx, name, hostLookupFilesDNS)
+func (r *Resolver) goLookupHost(ctx context.Context, name string) (addrs []string, err error) {
+ return r.goLookupHostOrder(ctx, name, hostLookupFilesDNS)
}
-func goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []string, err error) {
+func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []string, err error) {
if order == hostLookupFilesDNS || order == hostLookupFiles {
// Use entries from /etc/hosts if they match.
addrs = lookupStaticHost(name)
@@ -444,7 +454,7 @@ func goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder)
return
}
}
- ips, _, err := goLookupIPCNAMEOrder(ctx, name, order)
+ ips, _, err := r.goLookupIPCNAMEOrder(ctx, name, order)
if err != nil {
return
}
@@ -470,13 +480,13 @@ func goLookupIPFiles(name string) (addrs []IPAddr) {
// goLookupIP is the native Go implementation of LookupIP.
// The libc versions are in cgo_*.go.
-func goLookupIP(ctx context.Context, host string) (addrs []IPAddr, err error) {
+func (r *Resolver) goLookupIP(ctx context.Context, host string) (addrs []IPAddr, err error) {
order := systemConf().hostLookupOrder(host)
- addrs, _, err = goLookupIPCNAMEOrder(ctx, host, order)
+ addrs, _, err = r.goLookupIPCNAMEOrder(ctx, host, order)
return
}
-func goLookupIPCNAMEOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []IPAddr, cname string, err error) {
+func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []IPAddr, cname string, err error) {
if order == hostLookupFilesDNS || order == hostLookupFiles {
addrs = goLookupIPFiles(name)
if len(addrs) > 0 || order == hostLookupFiles {
@@ -506,11 +516,16 @@ func goLookupIPCNAMEOrder(ctx context.Context, name string, order hostLookupOrde
lane <- racer{cname, rrs, err}
}(qtype)
}
+ hitStrictError := false
for range qtypes {
racer := <-lane
if racer.error != nil {
- // Prefer error for original name.
- if lastErr == nil || fqdn == name+"." {
+ if nerr, ok := racer.error.(Error); ok && nerr.Temporary() && r.StrictErrors {
+ // This error will abort the nameList loop.
+ hitStrictError = true
+ lastErr = racer.error
+ } else if lastErr == nil || fqdn == name+"." {
+ // Prefer error for original name.
lastErr = racer.error
}
continue
@@ -520,6 +535,13 @@ func goLookupIPCNAMEOrder(ctx context.Context, name string, order hostLookupOrde
cname = racer.cname
}
}
+ if hitStrictError {
+ // If either family hit an error with StrictErrors enabled,
+ // discard all addresses. This ensures that network flakiness
+ // cannot turn a dualstack hostname IPv4/IPv6-only.
+ addrs = nil
+ break
+ }
if len(addrs) > 0 {
break
}
@@ -543,9 +565,9 @@ func goLookupIPCNAMEOrder(ctx context.Context, name string, order hostLookupOrde
}
// goLookupCNAME is the native Go (non-cgo) implementation of LookupCNAME.
-func goLookupCNAME(ctx context.Context, host string) (cname string, err error) {
+func (r *Resolver) goLookupCNAME(ctx context.Context, host string) (cname string, err error) {
order := systemConf().hostLookupOrder(host)
- _, cname, err = goLookupIPCNAMEOrder(ctx, host, order)
+ _, cname, err = r.goLookupIPCNAMEOrder(ctx, host, order)
return
}
@@ -554,7 +576,7 @@ func goLookupCNAME(ctx context.Context, host string) (cname string, err error) {
// only if cgoLookupPTR is the stub in cgo_stub.go).
// Normally we let cgo use the C library resolver instead of depending
// on our lookup code, so that Go and C get the same answers.
-func goLookupPTR(ctx context.Context, addr string) ([]string, error) {
+func (r *Resolver) goLookupPTR(ctx context.Context, addr string) ([]string, error) {
names := lookupStaticAddr(addr)
if len(names) > 0 {
return names, nil
@@ -563,7 +585,7 @@ func goLookupPTR(ctx context.Context, addr string) ([]string, error) {
if err != nil {
return nil, err
}
- _, rrs, err := lookup(ctx, arpa, dnsTypePTR)
+ _, rrs, err := r.lookup(ctx, arpa, dnsTypePTR)
if err != nil {
return nil, err
}
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 4464804c70..ec28af68fb 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -24,6 +24,9 @@ import (
// Test address from 192.0.2.0/24 block, reserved by RFC 5737 for documentation.
const TestAddr uint32 = 0xc0000201
+// Test address from 2001:db8::/32 block, reserved by RFC 3849 for documentation.
+var TestAddr6 = [16]byte{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
+
var dnsTransportFallbackTests = []struct {
server string
name string
@@ -142,7 +145,7 @@ func TestAvoidDNSName(t *testing.T) {
// Issue 13705: don't try to resolve onion addresses, etc
func TestLookupTorOnion(t *testing.T) {
- addrs, err := goLookupIP(context.Background(), "foo.onion")
+ addrs, err := DefaultResolver.goLookupIP(context.Background(), "foo.onion")
if len(addrs) > 0 {
t.Errorf("unexpected addresses: %v", addrs)
}
@@ -258,7 +261,7 @@ func TestUpdateResolvConf(t *testing.T) {
for j := 0; j < N; j++ {
go func(name string) {
defer wg.Done()
- ips, err := goLookupIP(context.Background(), name)
+ ips, err := DefaultResolver.goLookupIP(context.Background(), name)
if err != nil {
t.Error(err)
return
@@ -406,7 +409,7 @@ func TestGoLookupIPWithResolverConfig(t *testing.T) {
t.Error(err)
continue
}
- addrs, err := goLookupIP(context.Background(), tt.name)
+ addrs, err := DefaultResolver.goLookupIP(context.Background(), tt.name)
if err != nil {
// This test uses external network connectivity.
// We need to take care with errors on both
@@ -456,14 +459,14 @@ func TestGoLookupIPOrderFallbackToFile(t *testing.T) {
name := fmt.Sprintf("order %v", order)
// First ensure that we get an error when contacting a non-existent host.
- _, _, err := goLookupIPCNAMEOrder(context.Background(), "notarealhost", order)
+ _, _, err := DefaultResolver.goLookupIPCNAMEOrder(context.Background(), "notarealhost", order)
if err == nil {
t.Errorf("%s: expected error while looking up name not in hosts file", name)
continue
}
// Now check that we get an address when the name appears in the hosts file.
- addrs, _, err := goLookupIPCNAMEOrder(context.Background(), "thor", order) // entry is in "testdata/hosts"
+ addrs, _, err := DefaultResolver.goLookupIPCNAMEOrder(context.Background(), "thor", order) // entry is in "testdata/hosts"
if err != nil {
t.Errorf("%s: expected to successfully lookup host entry", name)
continue
@@ -519,14 +522,24 @@ func TestErrorForOriginalNameWhenSearching(t *testing.T) {
return r, nil
}
- _, err = goLookupIP(context.Background(), fqdn)
- if err == nil {
- t.Fatal("expected an error")
+ cases := []struct {
+ strictErrors bool
+ wantErr *DNSError
+ }{
+ {true, &DNSError{Name: fqdn, Err: "server misbehaving", IsTemporary: true}},
+ {false, &DNSError{Name: fqdn, Err: errNoSuchHost.Error()}},
}
+ for _, tt := range cases {
+ r := Resolver{StrictErrors: tt.strictErrors}
+ _, err = r.goLookupIP(context.Background(), fqdn)
+ if err == nil {
+ t.Fatal("expected an error")
+ }
- want := &DNSError{Name: fqdn, Err: errNoSuchHost.Error()}
- if err, ok := err.(*DNSError); !ok || err.Name != want.Name || err.Err != want.Err {
- t.Errorf("got %v; want %v", err, want)
+ want := tt.wantErr
+ if err, ok := err.(*DNSError); !ok || err.Name != want.Name || err.Err != want.Err || err.IsTemporary != want.IsTemporary {
+ t.Errorf("got %v; want %v", err, want)
+ }
}
}
@@ -579,7 +592,7 @@ func TestIgnoreLameReferrals(t *testing.T) {
return r, nil
}
- addrs, err := goLookupIP(context.Background(), "www.golang.org")
+ addrs, err := DefaultResolver.goLookupIP(context.Background(), "www.golang.org")
if err != nil {
t.Fatal(err)
}
@@ -598,7 +611,7 @@ func BenchmarkGoLookupIP(b *testing.B) {
ctx := context.Background()
for i := 0; i < b.N; i++ {
- goLookupIP(ctx, "www.example.com")
+ DefaultResolver.goLookupIP(ctx, "www.example.com")
}
}
@@ -607,7 +620,7 @@ func BenchmarkGoLookupIPNoSuchHost(b *testing.B) {
ctx := context.Background()
for i := 0; i < b.N; i++ {
- goLookupIP(ctx, "some.nonexistent")
+ DefaultResolver.goLookupIP(ctx, "some.nonexistent")
}
}
@@ -630,7 +643,7 @@ func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
ctx := context.Background()
for i := 0; i < b.N; i++ {
- goLookupIP(ctx, "www.example.com")
+ DefaultResolver.goLookupIP(ctx, "www.example.com")
}
}
@@ -861,3 +874,309 @@ func mockTXTResponse(q *dnsMsg) *dnsMsg {
return r
}
+
+// Issue 17448. With StrictErrors enabled, temporary errors should make
+// LookupIP fail rather than return a partial result.
+func TestStrictErrorsLookupIP(t *testing.T) {
+ origTestHookDNSDialer := testHookDNSDialer
+ defer func() { testHookDNSDialer = origTestHookDNSDialer }()
+
+ conf, err := newResolvConfTest()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conf.teardown()
+
+ confData := []string{
+ "nameserver 192.0.2.53",
+ "search x.golang.org y.golang.org",
+ }
+ if err := conf.writeAndUpdate(confData); err != nil {
+ t.Fatal(err)
+ }
+
+ const name = "test"
+ const server = "192.0.2.53:53"
+ const searchX = "test.x.golang.org."
+ const searchY = "test.y.golang.org."
+ const ip4 = "192.0.2.1"
+ const ip6 = "2001:db8::1"
+
+ type resolveWhichEnum int
+ const (
+ resolveOK resolveWhichEnum = iota
+ resolveOpError
+ resolveServfail
+ resolveTimeout
+ )
+
+ makeTempError := func(err string) error {
+ return &DNSError{
+ Err: err,
+ Name: name,
+ Server: server,
+ IsTemporary: true,
+ }
+ }
+ makeTimeout := func() error {
+ return &DNSError{
+ Err: poll.ErrTimeout.Error(),
+ Name: name,
+ Server: server,
+ IsTimeout: true,
+ }
+ }
+ makeNxDomain := func() error {
+ return &DNSError{
+ Err: errNoSuchHost.Error(),
+ Name: name,
+ Server: server,
+ }
+ }
+
+ cases := []struct {
+ desc string
+ resolveWhich func(quest *dnsQuestion) resolveWhichEnum
+ wantStrictErr error
+ wantLaxErr error
+ wantIPs []string
+ }{
+ {
+ desc: "No errors",
+ resolveWhich: func(quest *dnsQuestion) resolveWhichEnum {
+ return resolveOK
+ },
+ wantIPs: []string{ip4, ip6},
+ },
+ {
+ desc: "searchX error fails in strict mode",
+ resolveWhich: func(quest *dnsQuestion) resolveWhichEnum {
+ if quest.Name == searchX {
+ return resolveTimeout
+ }
+ return resolveOK
+ },
+ wantStrictErr: makeTimeout(),
+ wantIPs: []string{ip4, ip6},
+ },
+ {
+ desc: "searchX IPv4-only timeout fails in strict mode",
+ resolveWhich: func(quest *dnsQuestion) resolveWhichEnum {
+ if quest.Name == searchX && quest.Qtype == dnsTypeA {
+ return resolveTimeout
+ }
+ return resolveOK
+ },
+ wantStrictErr: makeTimeout(),
+ wantIPs: []string{ip4, ip6},
+ },
+ {
+ desc: "searchX IPv6-only servfail fails in strict mode",
+ resolveWhich: func(quest *dnsQuestion) resolveWhichEnum {
+ if quest.Name == searchX && quest.Qtype == dnsTypeAAAA {
+ return resolveServfail
+ }
+ return resolveOK
+ },
+ wantStrictErr: makeTempError("server misbehaving"),
+ wantIPs: []string{ip4, ip6},
+ },
+ {
+ desc: "searchY error always fails",
+ resolveWhich: func(quest *dnsQuestion) resolveWhichEnum {
+ if quest.Name == searchY {
+ return resolveTimeout
+ }
+ return resolveOK
+ },
+ wantStrictErr: makeTimeout(),
+ wantLaxErr: makeNxDomain(), // This one reaches the "test." FQDN.
+ },
+ {
+ desc: "searchY IPv4-only socket error fails in strict mode",
+ resolveWhich: func(quest *dnsQuestion) resolveWhichEnum {
+ if quest.Name == searchY && quest.Qtype == dnsTypeA {
+ return resolveOpError
+ }
+ return resolveOK
+ },
+ wantStrictErr: makeTempError("write: socket on fire"),
+ wantIPs: []string{ip6},
+ },
+ {
+ desc: "searchY IPv6-only timeout fails in strict mode",
+ resolveWhich: func(quest *dnsQuestion) resolveWhichEnum {
+ if quest.Name == searchY && quest.Qtype == dnsTypeAAAA {
+ return resolveTimeout
+ }
+ return resolveOK
+ },
+ wantStrictErr: makeTimeout(),
+ wantIPs: []string{ip4},
+ },
+ }
+
+ for i, tt := range cases {
+ d := &fakeDNSDialer{}
+ testHookDNSDialer = func() dnsDialer { return d }
+
+ d.rh = func(s string, q *dnsMsg, deadline time.Time) (*dnsMsg, error) {
+ t.Log(s, q)
+
+ switch tt.resolveWhich(&q.question[0]) {
+ case resolveOK:
+ // Handle below.
+ case resolveOpError:
+ return nil, &OpError{Op: "write", Err: fmt.Errorf("socket on fire")}
+ case resolveServfail:
+ return &dnsMsg{dnsMsgHdr: dnsMsgHdr{id: q.id, rcode: dnsRcodeServerFailure}}, nil
+ case resolveTimeout:
+ return nil, poll.ErrTimeout
+ default:
+ t.Fatal("Impossible resolveWhich")
+ }
+
+ switch q.question[0].Name {
+ case searchX, name + ".":
+ // Return NXDOMAIN to utilize the search list.
+ return &dnsMsg{dnsMsgHdr: dnsMsgHdr{id: q.id, rcode: dnsRcodeNameError}}, nil
+ case searchY:
+ // Return records below.
+ default:
+ return nil, fmt.Errorf("Unexpected Name: %v", q.question[0].Name)
+ }
+
+ r := &dnsMsg{
+ dnsMsgHdr: dnsMsgHdr{
+ id: q.id,
+ response: true,
+ },
+ question: q.question,
+ }
+ switch q.question[0].Qtype {
+ case dnsTypeA:
+ r.answer = []dnsRR{
+ &dnsRR_A{
+ Hdr: dnsRR_Header{
+ Name: q.question[0].Name,
+ Rrtype: dnsTypeA,
+ Class: dnsClassINET,
+ Rdlength: 4,
+ },
+ A: TestAddr,
+ },
+ }
+ case dnsTypeAAAA:
+ r.answer = []dnsRR{
+ &dnsRR_AAAA{
+ Hdr: dnsRR_Header{
+ Name: q.question[0].Name,
+ Rrtype: dnsTypeAAAA,
+ Class: dnsClassINET,
+ Rdlength: 16,
+ },
+ AAAA: TestAddr6,
+ },
+ }
+ default:
+ return nil, fmt.Errorf("Unexpected Qtype: %v", q.question[0].Qtype)
+ }
+ return r, nil
+ }
+
+ for _, strict := range []bool{true, false} {
+ r := Resolver{StrictErrors: strict}
+ ips, err := r.goLookupIP(context.Background(), name)
+
+ var wantErr error
+ if strict {
+ wantErr = tt.wantStrictErr
+ } else {
+ wantErr = tt.wantLaxErr
+ }
+ if !reflect.DeepEqual(err, wantErr) {
+ t.Errorf("#%d (%s) strict=%v: got err %#v; want %#v", i, tt.desc, strict, err, wantErr)
+ }
+
+ gotIPs := map[string]struct{}{}
+ for _, ip := range ips {
+ gotIPs[ip.String()] = struct{}{}
+ }
+ wantIPs := map[string]struct{}{}
+ if wantErr == nil {
+ for _, ip := range tt.wantIPs {
+ wantIPs[ip] = struct{}{}
+ }
+ }
+ if !reflect.DeepEqual(gotIPs, wantIPs) {
+ t.Errorf("#%d (%s) strict=%v: got ips %v; want %v", i, tt.desc, strict, gotIPs, wantIPs)
+ }
+ }
+ }
+}
+
+// Issue 17448. With StrictErrors enabled, temporary errors should make
+// LookupTXT stop walking the search list.
+func TestStrictErrorsLookupTXT(t *testing.T) {
+ origTestHookDNSDialer := testHookDNSDialer
+ defer func() { testHookDNSDialer = origTestHookDNSDialer }()
+
+ conf, err := newResolvConfTest()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conf.teardown()
+
+ confData := []string{
+ "nameserver 192.0.2.53",
+ "search x.golang.org y.golang.org",
+ }
+ if err := conf.writeAndUpdate(confData); err != nil {
+ t.Fatal(err)
+ }
+
+ const name = "test"
+ const server = "192.0.2.53:53"
+ const searchX = "test.x.golang.org."
+ const searchY = "test.y.golang.org."
+ const txt = "Hello World"
+
+ d := &fakeDNSDialer{}
+ testHookDNSDialer = func() dnsDialer { return d }
+
+ d.rh = func(s string, q *dnsMsg, deadline time.Time) (*dnsMsg, error) {
+ t.Log(s, q)
+
+ switch q.question[0].Name {
+ case searchX:
+ return nil, poll.ErrTimeout
+ case searchY:
+ return mockTXTResponse(q), nil
+ default:
+ return nil, fmt.Errorf("Unexpected Name: %v", q.question[0].Name)
+ }
+ }
+
+ for _, strict := range []bool{true, false} {
+ r := Resolver{StrictErrors: strict}
+ _, rrs, err := r.lookup(context.Background(), name, dnsTypeTXT)
+ var wantErr error
+ var wantRRs int
+ if strict {
+ wantErr = &DNSError{
+ Err: poll.ErrTimeout.Error(),
+ Name: name,
+ Server: server,
+ IsTimeout: true,
+ }
+ } else {
+ wantRRs = 1
+ }
+ if !reflect.DeepEqual(err, wantErr) {
+ t.Errorf("strict=%v: got err %#v; want %#v", strict, err, wantErr)
+ }
+ if len(rrs) != wantRRs {
+ t.Errorf("strict=%v: got %v; want %v", strict, len(rrs), wantRRs)
+ }
+ }
+}
diff --git a/src/net/lookup.go b/src/net/lookup.go
index cc2013e432..463b374aff 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -97,6 +97,16 @@ type Resolver struct {
// GODEBUG=netdns=go, but scoped to just this resolver.
PreferGo bool
+ // StrictErrors controls the behavior of temporary errors
+ // (including timeout, socket errors, and SERVFAIL) when using
+ // Go's built-in resolver. For a query composed of multiple
+ // sub-queries (such as an A+AAAA address lookup, or walking the
+ // DNS search list), this option causes such errors to abort the
+ // whole query instead of returning a partial result. This is
+ // not enabled by default because it may affect compatibility
+ // with resolvers that process AAAA queries incorrectly.
+ StrictErrors bool
+
// TODO(bradfitz): optional interface impl override hook
// TODO(bradfitz): Timeout time.Duration?
}
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go
index be2ced9c39..8d4b7bddf4 100644
--- a/src/net/lookup_unix.go
+++ b/src/net/lookup_unix.go
@@ -57,12 +57,12 @@ func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string,
// cgo not available (or netgo); fall back to Go's DNS resolver
order = hostLookupFilesDNS
}
- return goLookupHostOrder(ctx, host, order)
+ return r.goLookupHostOrder(ctx, host, order)
}
func (r *Resolver) lookupIP(ctx context.Context, host string) (addrs []IPAddr, err error) {
if r.PreferGo {
- return goLookupIP(ctx, host)
+ return r.goLookupIP(ctx, host)
}
order := systemConf().hostLookupOrder(host)
if order == hostLookupCgo {
@@ -72,7 +72,7 @@ func (r *Resolver) lookupIP(ctx context.Context, host string) (addrs []IPAddr, e
// cgo not available (or netgo); fall back to Go's DNS resolver
order = hostLookupFilesDNS
}
- addrs, _, err = goLookupIPCNAMEOrder(ctx, host, order)
+ addrs, _, err = r.goLookupIPCNAMEOrder(ctx, host, order)
return
}
@@ -98,17 +98,17 @@ func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error)
return cname, err
}
}
- return goLookupCNAME(ctx, name)
+ return r.goLookupCNAME(ctx, name)
}
-func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
+func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
var target string
if service == "" && proto == "" {
target = name
} else {
target = "_" + service + "._" + proto + "." + name
}
- cname, rrs, err := lookup(ctx, target, dnsTypeSRV)
+ cname, rrs, err := r.lookup(ctx, target, dnsTypeSRV)
if err != nil {
return "", nil, err
}
@@ -121,8 +121,8 @@ func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (st
return cname, srvs, nil
}
-func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
- _, rrs, err := lookup(ctx, name, dnsTypeMX)
+func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
+ _, rrs, err := r.lookup(ctx, name, dnsTypeMX)
if err != nil {
return nil, err
}
@@ -135,8 +135,8 @@ func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
return mxs, nil
}
-func (*Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
- _, rrs, err := lookup(ctx, name, dnsTypeNS)
+func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
+ _, rrs, err := r.lookup(ctx, name, dnsTypeNS)
if err != nil {
return nil, err
}
@@ -148,7 +148,7 @@ func (*Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
}
func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) {
- _, rrs, err := lookup(ctx, name, dnsTypeTXT)
+ _, rrs, err := r.lookup(ctx, name, dnsTypeTXT)
if err != nil {
return nil, err
}
@@ -165,5 +165,5 @@ func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error
return ptrs, err
}
}
- return goLookupPTR(ctx, addr)
+ return r.goLookupPTR(ctx, addr)
}
diff --git a/src/net/netgo_unix_test.go b/src/net/netgo_unix_test.go
index 5f1eb19e12..47901b03cf 100644
--- a/src/net/netgo_unix_test.go
+++ b/src/net/netgo_unix_test.go
@@ -22,7 +22,7 @@ func TestGoLookupIP(t *testing.T) {
if err != nil {
t.Error(err)
}
- if _, err := goLookupIP(ctx, host); err != nil {
+ if _, err := DefaultResolver.goLookupIP(ctx, host); err != nil {
t.Error(err)
}
}