diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index 1e01c43dfd..f77cc797d4 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -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 /*@}*/ /*@{*/ diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 13be34268f..83f6e30c7c 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -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 && diff --git a/lib/ns/query.c b/lib/ns/query.c index 2248e4b0b3..e7a666ef2a 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -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)); }