Phase 4.1: Error handling, edge cases, and robustness (#11)
CI / test (push) Failing after 2m36s

This commit was merged in pull request #11.
This commit is contained in:
2026-06-07 17:24:00 +00:00
parent 76f5010a5e
commit fe1afe2a97
12 changed files with 1118 additions and 22 deletions
+16 -2
View File
@@ -93,7 +93,7 @@ func QueryWithExchange(ctx context.Context, server net.IP, name string, qtype ui
select {
case <-ctx.Done():
return nil, fmt.Errorf("query retries cancelled: %w", ctx.Err())
case <-time.After(100 * time.Millisecond):
case <-time.After(backoffDelay(attempt)):
}
}
@@ -156,7 +156,7 @@ func IterativeQueryWithExchange(ctx context.Context, server net.IP, name string,
select {
case <-ctx.Done():
return nil, fmt.Errorf("query retries cancelled: %w", ctx.Err())
case <-time.After(100 * time.Millisecond):
case <-time.After(backoffDelay(attempt)):
}
}
@@ -195,6 +195,20 @@ func IterativeQueryWithExchange(ctx context.Context, server net.IP, name string,
return nil, fmt.Errorf("iterative query %s %s failed after %d retries: %w", name, QNameType(qtype), cfg.Retries, lastErr)
}
// backoffDelay computes the wait duration before the given retry attempt (1-indexed).
// Delays: attempt=1 → 100ms, attempt=2 → 200ms, attempt=3 → 400ms, capped at 2s.
func backoffDelay(attempt int) time.Duration {
if attempt <= 0 {
return 0
}
delay := time.Duration(uint(1)<<uint(attempt-1)) * 100 * time.Millisecond
const maxDelay = 2 * time.Second
if delay > maxDelay {
return maxDelay
}
return delay
}
func buildQuery(name string, qtype uint16, udpSize int) *dns.Msg {
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn(name), qtype)