fix: count DoQ/UDP test server call before writing reply

countHandler incremented its call counter after w.WriteMsg, but the DNS
client returns as soon as it receives the reply. A test reading the
counter right after Resolve returned could therefore observe a stale
zero, e.g. Test_Edns0_CacheReply intermittently failing on CI with
"cache not hit, server was called: 0" while passing on retry.

Increment the counter before writing the reply so it is guaranteed
visible once the client has the response. Verified by widening the
post-write window to reproduce the failure deterministically, then
confirming the reordered handler passes 500x and under -race.
This commit is contained in:
Cuong Manh Le
2026-07-28 16:13:36 +07:00
parent c596ef586b
commit fa074f1f5e
+5 -1
View File
@@ -383,6 +383,11 @@ func nonSuccessHandlerWithRcode(rcode int) dns.HandlerFunc {
func countHandler(call *atomic.Int64) dns.HandlerFunc {
return func(w dns.ResponseWriter, msg *dns.Msg) {
// Count the call before writing the reply. The client returns as soon
// as it receives the response, so a caller that reads this counter right
// after Resolve returns would race an increment done after WriteMsg and
// could observe a stale zero.
call.Add(1)
m := new(dns.Msg)
m.SetRcode(msg, dns.RcodeSuccess)
if cookie := getEdns0Cookie(msg.IsEdns0()); cookie != nil {
@@ -395,7 +400,6 @@ func countHandler(call *atomic.Int64) dns.HandlerFunc {
m.IsEdns0().Option = append(m.IsEdns0().Option, cookieOption)
}
w.WriteMsg(m)
call.Add(1)
}
}