]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use stale on error also when unable to recurse
authorMatthijs Mekking <matthijs@isc.org>
Thu, 4 Feb 2021 12:57:01 +0000 (13:57 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Mon, 8 Feb 2021 14:17:09 +0000 (15:17 +0100)
The 'query_usestale()' function was only called when in
'query_gotanswer()' and an unexpected error occurred. This may have
been "quota reached", and thus we were in some cases returning
stale data on fetch-limits (and if serve-stale enabled of course).

But we can also hit fetch-limits when recursing because we are
following a referral (in 'query_notfound()' and
'query_delegation_recurse()'). Here we should also check for using
stale data in case an error occurred.

Specifically don't check for using stale data when refetching a
zero TTL RRset from cache.

Move the setting of DNS_DBFIND_STALESTART into the 'query_usestale()'
function to avoid code duplication.

lib/ns/query.c

index e7a666ef2ac74524513059c65cc4ba81c3b87e34..9d5844084f22d0849815456fd2225ebaf6be5973 100644 (file)
@@ -7440,7 +7440,7 @@ root_key_sentinel_return_servfail(query_ctx_t *qctx, isc_result_t result) {
  * return true; otherwise, return false.
  */
 static bool
-query_usestale(query_ctx_t *qctx) {
+query_usestale(query_ctx_t *qctx, isc_result_t result) {
        if ((qctx->client->query.dboptions & DNS_DBFIND_STALEOK) != 0) {
                /*
                 * Query was already using stale, if that didn't work the
@@ -7459,6 +7459,13 @@ query_usestale(query_ctx_t *qctx) {
                        dns_resolver_destroyfetch(&qctx->client->query.fetch);
                }
 
+               /*
+                * Start the stale-refresh-time window in case there was a
+                * resolver query timeout.
+                */
+               if (qctx->resuming && result == ISC_R_TIMEDOUT) {
+                       qctx->client->query.dboptions |= DNS_DBFIND_STALESTART;
+               }
                return (true);
        }
 
@@ -7556,19 +7563,11 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
                         "query_gotanswer: unexpected error: %s",
                         isc_result_totext(result));
                CCTRACE(ISC_LOG_ERROR, errmsg);
-               if (query_usestale(qctx)) {
+               if (query_usestale(qctx, result)) {
                        /*
                         * If serve-stale is enabled, query_usestale() already
                         * set up 'qctx' for looking up a stale response.
-                        *
-                        * We only need to check if the query timed out or
-                        * something else has gone wrong. If the query timed
-                        * out, we will start the stale-refresh-time window.
                         */
-                       if (qctx->resuming && result == ISC_R_TIMEDOUT) {
-                               qctx->client->query.dboptions |=
-                                       DNS_DBFIND_STALESTART;
-                       }
                        return (query_lookup(qctx));
                }
 
@@ -8527,6 +8526,13 @@ query_notfound(query_ctx_t *qctx) {
                                        qctx->client->query.attributes |=
                                                NS_QUERYATTR_DNS64EXCLUDE;
                                }
+                       } else if (query_usestale(qctx, result)) {
+                               /*
+                                * If serve-stale is enabled, query_usestale()
+                                * already set up 'qctx' for looking up a
+                                * stale response.
+                                */
+                               return (query_lookup(qctx));
                        } else {
                                QUERY_ERROR(qctx, result);
                        }
@@ -8831,6 +8837,12 @@ query_delegation_recurse(query_ctx_t *qctx) {
                        qctx->client->query.attributes |=
                                NS_QUERYATTR_DNS64EXCLUDE;
                }
+       } else if (query_usestale(qctx, result)) {
+               /*
+                * If serve-stale is enabled, query_usestale() already set up
+                * 'qctx' for looking up a stale response.
+                */
+               return (query_lookup(qctx));
        } else {
                QUERY_ERROR(qctx, result);
        }
@@ -10225,6 +10237,10 @@ query_zerottl_refetch(query_ctx_t *qctx) {
                                NS_QUERYATTR_DNS64EXCLUDE;
                }
        } else {
+               /*
+                * There was a zero ttl from the cache, don't fallback to
+                * serve-stale lookup.
+                */
                QUERY_ERROR(qctx, result);
        }