aboutsummaryrefslogtreecommitdiff
path: root/src/net/lookup.go
diff options
context:
space:
mode:
authorEugene Kalinin <e.v.kalinin@gmail.com>2018-06-21 01:23:37 +0300
committerBrad Fitzpatrick <bradfitz@golang.org>2018-10-25 03:14:03 +0000
commitc659be4dc862cdf14a24134f2cfc16fa81e6d84c (patch)
treefb0200ce7fa6e9b5f3ad066e0da1589538ca2c57 /src/net/lookup.go
parentfc4f2e5692ab800a450e07c3d983eda02dfd4711 (diff)
downloadgo-c659be4dc862cdf14a24134f2cfc16fa81e6d84c.tar.gz
go-c659be4dc862cdf14a24134f2cfc16fa81e6d84c.zip
net: make cgo resolver work more accurately with network parameter
Unlike the go resolver, the existing cgo resolver exchanges both DNS A and AAAA RR queries unconditionally and causes unreasonable connection setup latencies to applications using the cgo resolver. This change adds new argument (`network`) in all functions through the series of calls: from Resolver.internetAddrList to cgoLookupIPCNAME. Benefit: no redundant DNS calls if certain IP version is used IPv4/IPv6 (no `AAAA` DNS requests if used tcp4, udp4, ip4 network. And vice versa: no `A` DNS requests if used tcp6, udp6, ip6 network) Fixes #25947 Change-Id: I39edbd726d82d6133fdada4d06cd90d401e7e669 Reviewed-on: https://go-review.googlesource.com/c/120215 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/lookup.go')
-rw-r--r--src/net/lookup.go30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/net/lookup.go b/src/net/lookup.go
index e0f21fa9a8..cb810dea26 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -97,6 +97,19 @@ func lookupPortMap(network, service string) (port int, error error) {
return 0, &AddrError{Err: "unknown port", Addr: network + "/" + service}
}
+// ipVersion returns the provided network's IP version: '4', '6' or 0
+// if network does not end in a '4' or '6' byte.
+func ipVersion(network string) byte {
+ if network == "" {
+ return 0
+ }
+ n := network[len(network)-1]
+ if n != '4' && n != '6' {
+ n = 0
+ }
+ return n
+}
+
// DefaultResolver is the resolver used by the package-level Lookup
// functions and by Dialers without a specified Resolver.
var DefaultResolver = &Resolver{}
@@ -189,6 +202,12 @@ func LookupIP(host string) ([]IP, error) {
// LookupIPAddr looks up host using the local resolver.
// It returns a slice of that host's IPv4 and IPv6 addresses.
func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, error) {
+ return r.lookupIPAddr(ctx, "ip", host)
+}
+
+// lookupIPAddr looks up host using the local resolver and particular network.
+// It returns a slice of that host's IPv4 and IPv6 addresses.
+func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IPAddr, error) {
// Make sure that no matter what we do later, host=="" is rejected.
// parseIP, for example, does accept empty strings.
if host == "" {
@@ -205,7 +224,7 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err
// can be overridden by tests. This is needed by net/http, so it
// uses a context key instead of unexported variables.
resolverFunc := r.lookupIP
- if alt, _ := ctx.Value(nettrace.LookupIPAltResolverKey{}).(func(context.Context, string) ([]IPAddr, error)); alt != nil {
+ if alt, _ := ctx.Value(nettrace.LookupIPAltResolverKey{}).(func(context.Context, string, string) ([]IPAddr, error)); alt != nil {
resolverFunc = alt
}
@@ -218,7 +237,7 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err
dnsWaitGroup.Add(1)
ch, called := r.getLookupGroup().DoChan(host, func() (interface{}, error) {
defer dnsWaitGroup.Done()
- return testHookLookupIP(lookupGroupCtx, resolverFunc, host)
+ return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host)
})
if !called {
dnsWaitGroup.Done()
@@ -289,6 +308,13 @@ func LookupPort(network, service string) (port int, err error) {
func (r *Resolver) LookupPort(ctx context.Context, network, service string) (port int, err error) {
port, needsLookup := parsePort(service)
if needsLookup {
+ switch network {
+ case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
+ case "": // a hint wildcard for Go 1.0 undocumented behavior
+ network = "ip"
+ default:
+ return 0, &AddrError{Err: "unknown network", Addr: network}
+ }
port, err = r.lookupPort(ctx, network, service)
if err != nil {
return 0, err