]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Reset DNS_DBFIND_STALETIMEOUT in query_lookup()
authorAram Sargsyan <aram@isc.org>
Wed, 18 Jun 2025 13:32:03 +0000 (13:32 +0000)
committerAndoni Duarte Pintado <andoni@isc.org>
Thu, 3 Jul 2025 09:03:34 +0000 (11:03 +0200)
If ns__query_start() is called because of a chained query (e.g.
after encountering a CNAME), a previously set DNS_DBFIND_STALETIMEOUT
flag on the query's 'dboptions' field can cause an assertion
failure if the new query's 'stalefirst' value is not true (e.g. if the
target qname is an authoritative zone for the server). Reset the
DNS_DBFIND_STALETIMEOUT flag in the query_lookup() function before
evaluating the 'stalefirst' value, and make sure to assign a fresh
value to the `stalefirst' flag instead of conditionally assigning it
only if the value is 'true'.

lib/ns/query.c

index e4e769d85be01fdf0203a43f3616222906b22a13..4ea0859c82414a27f51edc5436933b15618e4836 100644 (file)
@@ -5635,16 +5635,14 @@ ns__query_start(query_ctx_t *qctx) {
                }
        }
 
-       if (!qctx->is_zone && qctx->view->staleanswerclienttimeout == 0 &&
-           dns_view_staleanswerenabled(qctx->view))
-       {
-               /*
-                * If stale answers are enabled and
-                * stale-answer-client-timeout is zero, then we can promptly
-                * answer with a stale RRset if one is available in cache.
-                */
-               qctx->options.stalefirst = true;
-       }
+       /*
+        * If stale answers are enabled and stale-answer-client-timeout is zero,
+        * then we can promptly answer with a stale RRset if one is available in
+        * cache.
+        */
+       qctx->options.stalefirst = (!qctx->is_zone &&
+                                   qctx->view->staleanswerclienttimeout == 0 &&
+                                   dns_view_staleanswerenabled(qctx->view));
 
        result = query_lookup(qctx);
 
@@ -5773,7 +5771,9 @@ query_lookup(query_ctx_t *qctx) {
                rpzqname = qctx->client->query.qname;
        }
 
-       if (qctx->options.stalefirst) {
+       qctx->client->query.dboptions &= ~DNS_DBFIND_STALETIMEOUT;
+
+       if (qctx->options.stalefirst && !qctx->is_zone) {
                /*
                 * If the 'stalefirst' flag is set, it means that a stale
                 * RRset may be returned as part of this lookup. An attempt
@@ -5937,8 +5937,6 @@ query_lookup(query_ctx_t *qctx) {
                                qctx_freedata(qctx);
                                dns_db_attach(qctx->client->view->cachedb,
                                              &qctx->db);
-                               qctx->client->query.dboptions &=
-                                       ~DNS_DBFIND_STALETIMEOUT;
                                qctx->options.stalefirst = false;
                                if (FETCH_RECTYPE_NORMAL(qctx->client) != NULL)
                                {
@@ -8570,11 +8568,9 @@ query_zone_delegation(query_ctx_t *qctx) {
                 * setting the 'stalefirst' option, which is usually set in
                 * the beginning in ns__query_start().
                 */
-               if (qctx->view->staleanswerclienttimeout == 0 &&
-                   dns_view_staleanswerenabled(qctx->view))
-               {
-                       qctx->options.stalefirst = true;
-               }
+               qctx->options.stalefirst =
+                       (qctx->view->staleanswerclienttimeout == 0 &&
+                        dns_view_staleanswerenabled(qctx->view));
 
                result = query_lookup(qctx);