]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Only start stale refresh window when resuming
authorMatthijs Mekking <matthijs@isc.org>
Wed, 27 Jan 2021 15:59:27 +0000 (16:59 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 28 Jan 2021 15:38:34 +0000 (16:38 +0100)
If we did not attempt a fetch due to fetch-limits, we should not start
the stale-refresh-time window.

Introduce a new flag DNS_DBFIND_STALESTART to differentiate between
a resolver failure and unexpected error. If we are resuming, this
indicates a resolver failure, then start the stale-refresh-time window,
otherwise don't start the stale-refresh-time window, but still fall
back to using stale data.

(This commit also wraps some docstrings to 80 characters width)

lib/dns/include/dns/db.h
lib/dns/rbtdb.c
lib/ns/query.c

index 1e01c43dfda87f753a84bfcd93568ae842b969b6..f77cc797d46f812638678fc7e1d90c20313f07ae 100644 (file)
@@ -241,33 +241,36 @@ struct dns_dbonupdatelistener {
 #define DNS_DBFIND_NOZONECUT   0x0200
 
 /*
- * DNS_DBFIND_STALEOK: This flag is set when BIND fails to refresh a
- * RRset due to timeout (resolver-query-timeout), its intent is to
- * try to look for stale data in cache as a fallback, but only if
- * stale answers are enabled in configuration.
- *
- * This flag is also used to activate stale-refresh-time window, since it
- * is the only way the database knows that a resolution has failed.
+ * DNS_DBFIND_STALEOK: This flag is set when BIND fails to refresh a RRset due
+ * to timeout (resolver-query-timeout). Its intent is to try to look for stale
+ * data in cache as a fallback, but only if stale answers are enabled in
+ * configuration.
  */
 #define DNS_DBFIND_STALEOK 0x0400
 
 /*
- * DNS_DBFIND_STALEENABLED: This flag is used as a hint to the database
- * that it may use stale data. It is always set during query lookup if
- * stale answers are enabled, but only effectively used during
- * stale-refresh-time window. Also during this window, the resolver will
- * not try to resolve the query, in other words no attempt to refresh the
- * data in cache is made when the stale-refresh-time window is active.
+ * DNS_DBFIND_STALEENABLED: This flag is used as a hint to the database that
+ * it may use stale data. It is always set during query lookup if stale
+ * answers are enabled, but only effectively used during stale-refresh-time
+ * window. Also during this window, the resolver will not try to resolve the
+ * query, in other words no attempt to refresh the data in cache is made when
+ * the stale-refresh-time window is active.
  */
 #define DNS_DBFIND_STALEENABLED 0x0800
 
 /*
- * DNS_DBFIND_STALEONLY: This new introduced flag is used when we want
- * stale data from the database, but not due to a failure in resolution,
- * it also doesn't require stale-refresh-time window timer to be active.
- * As long as there is a stale RRset available, it should be returned.
+ * DNS_DBFIND_STALEONLY: This flag is used when we want stale data from the
+ * database, but not due to a failure in resolution, it also doesn't require
+ * stale-refresh-time window timer to be active. As long as there is a stale
+ * RRset available, it should be returned.
  */
 #define DNS_DBFIND_STALEONLY 0x1000
+
+/*
+ * DNS_DBFIND_STALESTART: This flag is used to activate stale-refresh-time
+ * window.
+ */
+#define DNS_DBFIND_STALESTART 0x2000
 /*@}*/
 
 /*@{*/
index 13be34268fa46a9fe6a0cdbe3655a24644b33e37..83f6e30c7c2b89faa821d8b9e55f13c7d437c71a 100644 (file)
@@ -4565,11 +4565,12 @@ check_stale_header(dns_rbtnode_t *node, rdatasetheader_t *header,
                        mark_header_stale(search->rbtdb, header);
                        *header_prev = header;
                        /*
-                        * If DNS_DBFIND_STALEOK is set then it means we failed
-                        * to resolve the name during recursion, in this case we
-                        * mark the time in which the refresh failed.
+                        * If DNS_DBFIND_STALESTART is set then it means we
+                        * failed to resolve the name during recursion, in
+                        * this case we mark the time in which the refresh
+                        * failed.
                         */
-                       if ((search->options & DNS_DBFIND_STALEOK) != 0) {
+                       if ((search->options & DNS_DBFIND_STALESTART) != 0) {
                                header->last_refresh_fail_ts = search->now;
                        } else if ((search->options &
                                    DNS_DBFIND_STALEENABLED) != 0 &&
index 2248e4b0b3c9101b7b0876a5300641431e082c33..e7a666ef2ac74524513059c65cc4ba81c3b87e34 100644 (file)
@@ -7560,7 +7560,15 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
                        /*
                         * 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));
                }