diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-01-18 19:04:36 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-01-18 19:04:36 +0000 |
commit | 4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch) | |
tree | f12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/go/net/lookup.go | |
parent | 225220d668dafb8262db7012bced688acbe63b33 (diff) |
libgo: update to Go1.12beta2
Reviewed-on: https://go-review.googlesource.com/c/158019
gotools/:
* Makefile.am (go_cmd_vet_files): Update for Go1.12beta2 release.
(GOTOOLS_TEST_TIMEOUT): Increase to 600.
(check-runtime): Export LD_LIBRARY_PATH before computing GOARCH
and GOOS.
(check-vet): Copy golang.org/x/tools into check-vet-dir.
* Makefile.in: Regenerate.
gcc/testsuite/:
* go.go-torture/execute/names-1.go: Stop using debug/xcoff, which
is no longer externally visible.
From-SVN: r268084
Diffstat (limited to 'libgo/go/net/lookup.go')
-rw-r--r-- | libgo/go/net/lookup.go | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go index e0f21fa9a8d..e10889331e4 100644 --- a/libgo/go/net/lookup.go +++ b/libgo/go/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,39 @@ 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) +} + +// onlyValuesCtx is a context that uses an underlying context +// for value lookup if the underlying context hasn't yet expired. +type onlyValuesCtx struct { + context.Context + lookupValues context.Context +} + +var _ context.Context = (*onlyValuesCtx)(nil) + +// Value performs a lookup if the original context hasn't expired. +func (ovc *onlyValuesCtx) Value(key interface{}) interface{} { + select { + case <-ovc.lookupValues.Done(): + return nil + default: + return ovc.lookupValues.Value(key) + } +} + +// withUnexpiredValuesPreserved returns a context.Context that only uses lookupCtx +// for its values, otherwise it is never canceled and has no deadline. +// If the lookup context expires, any looked up values will return nil. +// See Issue 28600. +func withUnexpiredValuesPreserved(lookupCtx context.Context) context.Context { + return &onlyValuesCtx{Context: context.Background(), lookupValues: lookupCtx} +} + +// 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,20 +251,21 @@ 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 } // We don't want a cancelation of ctx to affect the // lookupGroup operation. Otherwise if our context gets // canceled it might cause an error to be returned to a lookup - // using a completely different context. - lookupGroupCtx, lookupGroupCancel := context.WithCancel(context.Background()) + // using a completely different context. However we need to preserve + // only the values in context. See Issue 28600. + lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx)) 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 +336,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 |