]> Cypherpunks repositories - gostls13.git/commitdiff
net: make go resolver aware of network parameter
authorZhang Boyang <zhangboyang.id@gmail.com>
Mon, 15 Mar 2021 15:27:51 +0000 (15:27 +0000)
committerEmmanuel Odeke <emmanuel@orijtech.com>
Tue, 23 Mar 2021 11:14:58 +0000 (11:14 +0000)
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: 3d30c486dedd0d211366b1989034480a22ef2ffc
GitHub-Pull-Request: golang/go#45016
Reviewed-on: https://go-review.googlesource.com/c/go/+/301709
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>

src/net/dnsclient_unix.go
src/net/dnsclient_unix_test.go
src/net/lookup_unix.go
src/net/netgo_unix_test.go

index 86f64335ea7ed011def16a3669b707a96c7e5ffb..50e9bb0f20dd70745541c67c016eab7fa068ccd2 100644 (file)
@@ -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
        }
@@ -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 {
@@ -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 {
@@ -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
 }
 
index b47b83af15c98046f78d0e6dad45c3e4f99a1c69..ec690a1c0cffcf8e51e2043690307e784a3f37a0 100644 (file)
@@ -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
index c09afb300f56504da8ef3bb00ad7283f196713b7..8030e3d99e1e13dfb5e3f2ef8f361edba6e34af4 100644 (file)
@@ -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 {
@@ -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
 }
 
index 0dfd6c2cd7f31268a5f741914a24f2a74a4ce24f..5551e47de7ff7d2c616be585492eb13ebf4aa52e 100644 (file)
@@ -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)
        }
 }