diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-07-22 18:15:38 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-07-22 18:15:38 +0000 |
commit | 22b955cca564a9a3a5b8c9d9dd1e295b7943c128 (patch) | |
tree | abdbd898676e1f853fca2d7e031d105d7ebcf676 /libgo/go/net/lookup.go | |
parent | 9d04a3af4c6491536badf6bde9707c907e4d196b (diff) |
libgo: update to go1.7rc3
Reviewed-on: https://go-review.googlesource.com/25150
From-SVN: r238662
Diffstat (limited to 'libgo/go/net/lookup.go')
-rw-r--r-- | libgo/go/net/lookup.go | 98 |
1 files changed, 56 insertions, 42 deletions
diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go index 7aa111ba929..c169e9e902c 100644 --- a/libgo/go/net/lookup.go +++ b/libgo/go/net/lookup.go @@ -1,12 +1,13 @@ -// Copyright 2012 The Go Authors. All rights reserved. +// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package net import ( + "context" + "internal/nettrace" "internal/singleflight" - "time" ) // protocols contains minimal mappings between internet protocol @@ -33,7 +34,7 @@ func LookupHost(host string) (addrs []string, err error) { if ip := ParseIP(host); ip != nil { return []string{host}, nil } - return lookupHost(host) + return lookupHost(context.Background(), host) } // LookupIP looks up host using the local resolver. @@ -47,7 +48,7 @@ func LookupIP(host string) (ips []IP, err error) { if ip := ParseIP(host); ip != nil { return []IP{ip}, nil } - addrs, err := lookupIPMerge(host) + addrs, err := lookupIPMerge(context.Background(), host) if err != nil { return } @@ -63,9 +64,9 @@ var lookupGroup singleflight.Group // lookupIPMerge wraps lookupIP, but makes sure that for any given // host, only one lookup is in-flight at a time. The returned memory // is always owned by the caller. -func lookupIPMerge(host string) (addrs []IPAddr, err error) { +func lookupIPMerge(ctx context.Context, host string) (addrs []IPAddr, err error) { addrsi, err, shared := lookupGroup.Do(host, func() (interface{}, error) { - return testHookLookupIP(lookupIP, host) + return testHookLookupIP(ctx, lookupIP, host) }) return lookupIPReturn(addrsi, err, shared) } @@ -85,52 +86,65 @@ func lookupIPReturn(addrsi interface{}, err error, shared bool) ([]IPAddr, error return addrs, nil } -// lookupIPDeadline looks up a hostname with a deadline. -func lookupIPDeadline(host string, deadline time.Time) (addrs []IPAddr, err error) { - if deadline.IsZero() { - return lookupIPMerge(host) +// ipAddrsEface returns an empty interface slice of addrs. +func ipAddrsEface(addrs []IPAddr) []interface{} { + s := make([]interface{}, len(addrs)) + for i, v := range addrs { + s[i] = v } + return s +} - // We could push the deadline down into the name resolution - // functions. However, the most commonly used implementation - // calls getaddrinfo, which has no timeout. - - timeout := deadline.Sub(time.Now()) - if timeout <= 0 { - return nil, errTimeout +// lookupIPContext looks up a hostname with a context. +// +// TODO(bradfitz): rename this function. All the other +// build-tag-specific lookupIP funcs also take a context now, so this +// name is no longer great. Maybe make this lookupIPMerge and ditch +// the other one, making its callers call this instead with a +// context.Background(). +func lookupIPContext(ctx context.Context, host string) (addrs []IPAddr, err error) { + trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace) + if trace != nil && trace.DNSStart != nil { + trace.DNSStart(host) + } + // The underlying resolver func is lookupIP by default but it + // can be overridden by tests. This is needed by net/http, so it + // uses a context key instead of unexported variables. + resolverFunc := lookupIP + if alt, _ := ctx.Value(nettrace.LookupIPAltResolverKey{}).(func(context.Context, string) ([]IPAddr, error)); alt != nil { + resolverFunc = alt } - t := time.NewTimer(timeout) - defer t.Stop() ch := lookupGroup.DoChan(host, func() (interface{}, error) { - return testHookLookupIP(lookupIP, host) + return testHookLookupIP(ctx, resolverFunc, host) }) select { - case <-t.C: - // The DNS lookup timed out for some reason. Force + case <-ctx.Done(): + // The DNS lookup timed out for some reason. Force // future requests to start the DNS lookup again // rather than waiting for the current lookup to - // complete. See issue 8602. + // complete. See issue 8602. + err := mapErr(ctx.Err()) lookupGroup.Forget(host) - - return nil, errTimeout - + if trace != nil && trace.DNSDone != nil { + trace.DNSDone(nil, false, err) + } + return nil, err case r := <-ch: + if trace != nil && trace.DNSDone != nil { + addrs, _ := r.Val.([]IPAddr) + trace.DNSDone(ipAddrsEface(addrs), r.Shared, r.Err) + } return lookupIPReturn(r.Val, r.Err, r.Shared) } } // LookupPort looks up the port for the given network and service. func LookupPort(network, service string) (port int, err error) { - if service == "" { - // Lock in the legacy behavior that an empty string - // means port 0. See Issue 13610. - return 0, nil - } - port, _, ok := dtoi(service, 0) - if !ok && port != big && port != -big { - port, err = lookupPort(network, service) + port, needsLookup := parsePort(service) + if needsLookup { + port, err = lookupPort(context.Background(), network, service) if err != nil { return 0, err } @@ -146,39 +160,39 @@ func LookupPort(network, service string) (port int, err error) { // LookupHost or LookupIP directly; both take care of resolving // the canonical name as part of the lookup. func LookupCNAME(name string) (cname string, err error) { - return lookupCNAME(name) + return lookupCNAME(context.Background(), name) } // LookupSRV tries to resolve an SRV query of the given service, -// protocol, and domain name. The proto is "tcp" or "udp". +// protocol, and domain name. The proto is "tcp" or "udp". // The returned records are sorted by priority and randomized // by weight within a priority. // // LookupSRV constructs the DNS name to look up following RFC 2782. -// That is, it looks up _service._proto.name. To accommodate services +// That is, it looks up _service._proto.name. To accommodate services // publishing SRV records under non-standard names, if both service // and proto are empty strings, LookupSRV looks up name directly. func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { - return lookupSRV(service, proto, name) + return lookupSRV(context.Background(), service, proto, name) } // LookupMX returns the DNS MX records for the given domain name sorted by preference. func LookupMX(name string) (mxs []*MX, err error) { - return lookupMX(name) + return lookupMX(context.Background(), name) } // LookupNS returns the DNS NS records for the given domain name. func LookupNS(name string) (nss []*NS, err error) { - return lookupNS(name) + return lookupNS(context.Background(), name) } // LookupTXT returns the DNS TXT records for the given domain name. func LookupTXT(name string) (txts []string, err error) { - return lookupTXT(name) + return lookupTXT(context.Background(), name) } // LookupAddr performs a reverse lookup for the given address, returning a list // of names mapping to that address. func LookupAddr(addr string) (names []string, err error) { - return lookupAddr(addr) + return lookupAddr(context.Background(), addr) } |