mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
net: restore per-query timeout logic
The handling of "options timeout:n" is supposed to be per individual DNS server exchange, not per Lookup call. Fixes #16865. Change-Id: I2304579b9169c1515292f142cb372af9d37ff7c1 Reviewed-on: https://go-review.googlesource.com/28057 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
aaa6b53524
commit
11e3955e10
2 changed files with 92 additions and 21 deletions
|
|
@ -141,7 +141,7 @@ func (d *Dialer) dialDNS(ctx context.Context, network, server string) (dnsConn,
|
|||
}
|
||||
|
||||
// exchange sends a query on the connection and hopes for a response.
|
||||
func exchange(ctx context.Context, server, name string, qtype uint16) (*dnsMsg, error) {
|
||||
func exchange(ctx context.Context, server, name string, qtype uint16, timeout time.Duration) (*dnsMsg, error) {
|
||||
d := testHookDNSDialer()
|
||||
out := dnsMsg{
|
||||
dnsMsgHdr: dnsMsgHdr{
|
||||
|
|
@ -152,6 +152,12 @@ func exchange(ctx context.Context, server, name string, qtype uint16) (*dnsMsg,
|
|||
},
|
||||
}
|
||||
for _, network := range []string{"udp", "tcp"} {
|
||||
// TODO(mdempsky): Refactor so defers from UDP-based
|
||||
// exchanges happen before TCP-based exchange.
|
||||
|
||||
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout))
|
||||
defer cancel()
|
||||
|
||||
c, err := d.dialDNS(ctx, network, server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -180,17 +186,10 @@ func tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype uint16)
|
|||
return "", nil, &DNSError{Err: "no DNS servers", Name: name}
|
||||
}
|
||||
|
||||
deadline := time.Now().Add(cfg.timeout)
|
||||
if old, ok := ctx.Deadline(); !ok || deadline.Before(old) {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithDeadline(ctx, deadline)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
var lastErr error
|
||||
for i := 0; i < cfg.attempts; i++ {
|
||||
for _, server := range cfg.servers {
|
||||
msg, err := exchange(ctx, server, name, qtype)
|
||||
msg, err := exchange(ctx, server, name, qtype, cfg.timeout)
|
||||
if err != nil {
|
||||
lastErr = &DNSError{
|
||||
Err: err.Error(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue