From: Michał Kępień Date: Thu, 21 May 2026 09:52:56 +0000 (+0200) Subject: Fix flawed response logic for COOKIE-less queries X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=de42425bbd6f51edf2abc0e57d4d3e3dd2e92159;p=thirdparty%2Fbind9.git Fix flawed response logic for COOKIE-less queries The "yield" keyword does not cause a function to return. By design, get_responses() may yield multiple DNS responses in a single call. As currently implemented, CookieHandler.get_responses() sends two responses to each client query that does not contain a COOKIE option. Make the logic in that method consistent with code comments by only sending one response to every query - either SERVFAIL or BADCOOKIE, never both. --- diff --git a/bin/tests/system/resend_loop/ans3/ans.py b/bin/tests/system/resend_loop/ans3/ans.py index 69ea0be6c76..47275bf3777 100644 --- a/bin/tests/system/resend_loop/ans3/ans.py +++ b/bin/tests/system/resend_loop/ans3/ans.py @@ -73,21 +73,17 @@ class CookieHandler(DomainHandler): async def get_responses( self, qctx: QueryContext ) -> AsyncGenerator[DnsResponseSend, None]: - - # Check for client cookie - cookie = _get_cookie(qctx) - - # If missing cookie entirely, just return SERVFAIL - if cookie is None: + if cookie := _get_cookie(qctx): + # If there is a client cookie, mock BADCOOKIE to trigger + # the resend loop logic. + qctx.response.use_edns(options=[cookie]) + qctx.response.set_rcode(dns.rcode.BADCOOKIE) + yield DnsResponseSend(qctx.response) + else: + # If missing cookie entirely, just return SERVFAIL qctx.response.set_rcode(dns.rcode.SERVFAIL) yield DnsResponseSend(qctx.response) - # If there is a client cookie, mock BADCOOKIE to trigger - # the resend loop logic. - qctx.response.use_edns(options=[cookie]) - qctx.response.set_rcode(dns.rcode.BADCOOKIE) - yield DnsResponseSend(qctx.response) - def resend_server() -> AsyncDnsServer: server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR)