resolver: a query cut short by the caller's context records no reason (closes #298)
check / check (push) Waiting to run
check / check (push) Waiting to run
When the caller's context ends, the next query returns ErrContextCanceled before anything is sent. querySingleType recorded that as a network error, which outranks a timeout, so a nameserver that had only timed out could be reported as "network error: context canceled". It now records no reason for it. A try the context's deadline cuts short ends as a timeout. When the context has ended before a further try, tryExchange now returns that try's error instead of ErrContextCanceled, so such a nameserver is reported as timed out, not as answering. Model: opus-5-5
This commit was merged in pull request #299.
This commit is contained in:
@@ -62,7 +62,10 @@ func checkCtx(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// tryExchange sends msg to addr over UDP, up to maxRetries times, until
|
||||
// a reply comes. Every try waits the same queryTimeoutDuration.
|
||||
// a reply comes. Every try waits the same queryTimeoutDuration, or less
|
||||
// when ctx's deadline comes first. When ctx has ended before a further
|
||||
// try, it returns the error of the try already made, such as a timeout,
|
||||
// or ErrContextCanceled when none was made.
|
||||
func (r *Resolver) tryExchange(
|
||||
ctx context.Context,
|
||||
msg *dns.Msg,
|
||||
@@ -74,7 +77,11 @@ func (r *Resolver) tryExchange(
|
||||
|
||||
for range maxRetries {
|
||||
if checkCtx(ctx) != nil {
|
||||
return nil, ErrContextCanceled
|
||||
if err == nil {
|
||||
return nil, ErrContextCanceled
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, _, err = r.client.ExchangeContext(ctx, msg, addr)
|
||||
@@ -863,6 +870,10 @@ func (r *Resolver) querySingleType(
|
||||
if err != nil {
|
||||
err = fmt.Errorf("query %s @%s: %w", hostname, nsIP, err)
|
||||
}
|
||||
case errors.Is(err, ErrContextCanceled):
|
||||
// The caller's context ended before the query was sent.
|
||||
// That says nothing about the nameserver, so no reason is
|
||||
// recorded.
|
||||
case isTimeout(err):
|
||||
state.gotTimeout = true
|
||||
case errors.Is(err, ErrRefused):
|
||||
|
||||
Reference in New Issue
Block a user