From 86a80e723fc7b6bdd87174f4a48aa702dbe17c5a Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 17 Nov 2022 13:52:26 +0000 Subject: [PATCH] Consider non-stale data when in serve-stale mode With 'stale-answer-enable yes;' and 'stale-answer-client-timeout off;', consider the following situation: A CNAME record and its target record are in the cache, then the CNAME record expires, but the target record is still valid. When a new query for the CNAME record arrives, and the query fails, the stale record is used, and then the query "restarts" to follow the CNAME target. The problem is that the query's multiple stale options (like DNS_DBFIND_STALEOK) are not reset, so 'query_lookup()' treats the restarted query as a lookup following a failed lookup, and returns a SERVFAIL answer when there is no stale data found in the cache, even if there is valid non-stale data there available. With this change, query_lookup() now considers non-stale data in the cache in the first place, and returns it if it is available. --- lib/ns/query.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/ns/query.c b/lib/ns/query.c index ee89b62a17..0c3ee43e1a 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -5960,6 +5960,13 @@ query_lookup(query_ctx_t *qctx) { dns_cache_updatestats(qctx->view->cache, result); } + if (dns_rdataset_isassociated(qctx->rdataset) && + dns_rdataset_count(qctx->rdataset) > 0 && !STALE(qctx->rdataset)) + { + /* Found non-stale usable rdataset. */ + goto gotanswer; + } + /* * If DNS_DBFIND_STALEOK is set this means we are dealing with a * lookup following a failed lookup and it is okay to serve a stale @@ -6131,6 +6138,7 @@ query_lookup(query_ctx_t *qctx) { qctx->rdataset->attributes |= DNS_RDATASETATTR_STALE_ADDED; } +gotanswer: result = query_gotanswer(qctx, result); cleanup: