aboutsummaryrefslogtreecommitdiff
path: root/src/net/lookup.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-03-15 11:55:30 -0700
committerIan Lance Taylor <iant@golang.org>2018-03-16 13:39:38 +0000
commitbd859439e72a0c48c64259f7de9f175aae3b9c37 (patch)
tree9364a5653d1d0e570781d8a640383645c74a35b4 /src/net/lookup.go
parent0b20aece1aa4782070660a80dc4cf87c183533c9 (diff)
downloadgo-bd859439e72a0c48c64259f7de9f175aae3b9c37.tar.gz
go-bd859439e72a0c48c64259f7de9f175aae3b9c37.zip
net: don't let cancelation of a DNS lookup affect another lookup
Updates #8602 Updates #20703 Fixes #22724 Change-Id: I27b72311b2c66148c59977361bd3f5101e47b51d Reviewed-on: https://go-review.googlesource.com/100840 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/lookup.go')
-rw-r--r--src/net/lookup.go32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/net/lookup.go b/src/net/lookup.go
index 6844b1118f..dffbc016b2 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -194,10 +194,16 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err
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())
+
dnsWaitGroup.Add(1)
ch, called := lookupGroup.DoChan(host, func() (interface{}, error) {
defer dnsWaitGroup.Done()
- return testHookLookupIP(ctx, resolverFunc, host)
+ return testHookLookupIP(lookupGroupCtx, resolverFunc, host)
})
if !called {
dnsWaitGroup.Done()
@@ -205,20 +211,28 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err
select {
case <-ctx.Done():
- // If 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.
- ctxErr := ctx.Err()
- if ctxErr == context.DeadlineExceeded {
- lookupGroup.Forget(host)
+ // Our context was canceled. If we are the only
+ // goroutine looking up this key, then drop the key
+ // from the lookupGroup and cancel the lookup.
+ // If there are other goroutines looking up this key,
+ // let the lookup continue uncanceled, and let later
+ // lookups with the same key share the result.
+ // See issues 8602, 20703, 22724.
+ if lookupGroup.ForgetUnshared(host) {
+ lookupGroupCancel()
+ } else {
+ go func() {
+ <-ch
+ lookupGroupCancel()
+ }()
}
- err := mapErr(ctxErr)
+ err := mapErr(ctx.Err())
if trace != nil && trace.DNSDone != nil {
trace.DNSDone(nil, false, err)
}
return nil, err
case r := <-ch:
+ lookupGroupCancel()
if trace != nil && trace.DNSDone != nil {
addrs, _ := r.Val.([]IPAddr)
trace.DNSDone(ipAddrsEface(addrs), r.Shared, r.Err)