Skip to content

Commit

Permalink
net: make go resolver aware of network parameter
Browse files Browse the repository at this point in the history
Currently, the go resolver always send two DNS queries (A and AAAA) even
if tcp4/udp4/ip4 or tcp6/udp6/ip6 is used. This can cause unwanted
latencies when making IPv4-only or IPv6-only connections.

This change make go resolver aware of network parameter. Now, only one A
query is sent when tcp4/udp4/ip4 is used, and vice versa for
tcp6/udp6/ip6.

Fixes #45024

Change-Id: I815f909e6df5f7242cfc900f7dfecca628c3a2c8
GitHub-Last-Rev: 3d30c48
GitHub-Pull-Request: #45016
Reviewed-on: https://go-review.googlesource.com/c/go/+/301709
Run-TryBot: Ian Lance Taylor <[email protected]>
TryBot-Result: Go Bot <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
Trust: Emmanuel Odeke <[email protected]>
  • Loading branch information
zhangboyang authored and odeke-em committed Mar 23, 2021
1 parent f4b9183 commit 53dd0d7
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 11 deletions.
18 changes: 12 additions & 6 deletions src/net/dnsclient_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hos
return
}
}
ips, _, err := r.goLookupIPCNAMEOrder(ctx, name, order)
ips, _, err := r.goLookupIPCNAMEOrder(ctx, "ip", name, order)
if err != nil {
return
}
Expand All @@ -558,13 +558,13 @@ func goLookupIPFiles(name string) (addrs []IPAddr) {

// 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) {
func (r *Resolver) goLookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
order := systemConf().hostLookupOrder(r, host)
addrs, _, err = r.goLookupIPCNAMEOrder(ctx, host, order)
addrs, _, err = r.goLookupIPCNAMEOrder(ctx, network, host, order)
return
}

func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []IPAddr, cname dnsmessage.Name, err error) {
func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder) (addrs []IPAddr, cname dnsmessage.Name, err error) {
if order == hostLookupFilesDNS || order == hostLookupFiles {
addrs = goLookupIPFiles(name)
if len(addrs) > 0 || order == hostLookupFiles {
Expand All @@ -585,7 +585,13 @@ func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, name string, order
error
}
lane := make(chan result, 1)
qtypes := [...]dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA}
qtypes := []dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA}
switch ipVersion(network) {
case '4':
qtypes = []dnsmessage.Type{dnsmessage.TypeA}
case '6':
qtypes = []dnsmessage.Type{dnsmessage.TypeAAAA}
}
var queryFn func(fqdn string, qtype dnsmessage.Type)
var responseFn func(fqdn string, qtype dnsmessage.Type) result
if conf.singleRequest {
Expand Down Expand Up @@ -730,7 +736,7 @@ func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, name string, order
// goLookupCNAME is the native Go (non-cgo) implementation of LookupCNAME.
func (r *Resolver) goLookupCNAME(ctx context.Context, host string) (string, error) {
order := systemConf().hostLookupOrder(r, host)
_, cname, err := r.goLookupIPCNAMEOrder(ctx, host, order)
_, cname, err := r.goLookupIPCNAMEOrder(ctx, "ip", host, order)
return cname.String(), err
}

Expand Down
4 changes: 2 additions & 2 deletions src/net/dnsclient_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -601,14 +601,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 := r.goLookupIPCNAMEOrder(context.Background(), "notarealhost", order)
_, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "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 := r.goLookupIPCNAMEOrder(context.Background(), "thor", order) // entry is in "testdata/hosts"
addrs, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "thor", order) // entry is in "testdata/hosts"
if err != nil {
t.Errorf("%s: expected to successfully lookup host entry", name)
continue
Expand Down
4 changes: 2 additions & 2 deletions src/net/lookup_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string,

func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
if r.preferGo() {
return r.goLookupIP(ctx, host)
return r.goLookupIP(ctx, network, host)
}
order := systemConf().hostLookupOrder(r, host)
if order == hostLookupCgo {
Expand All @@ -100,7 +100,7 @@ func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []
// cgo not available (or netgo); fall back to Go's DNS resolver
order = hostLookupFilesDNS
}
ips, _, err := r.goLookupIPCNAMEOrder(ctx, host, order)
ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order)
return ips, err
}

Expand Down
2 changes: 1 addition & 1 deletion src/net/netgo_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestGoLookupIP(t *testing.T) {
if err != nil {
t.Error(err)
}
if _, err := DefaultResolver.goLookupIP(ctx, host); err != nil {
if _, err := DefaultResolver.goLookupIP(ctx, "ip", host); err != nil {
t.Error(err)
}
}

0 comments on commit 53dd0d7

Please sign in to comment.