From 19b222f6a8f6740fe76f5b48499ac5a5ba72ce08 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Wed, 15 Jul 2026 22:52:18 +0700 Subject: [PATCH] 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. --- resolver_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resolver_test.go b/resolver_test.go index cfa284f..85b2a2e 100644 --- a/resolver_test.go +++ b/resolver_test.go @@ -442,6 +442,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 { @@ -454,7 +459,6 @@ func countHandler(call *atomic.Int64) dns.HandlerFunc { m.IsEdns0().Option = append(m.IsEdns0().Option, cookieOption) } w.WriteMsg(m) - call.Add(1) } }