diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index 6ae21dcc4b..d240d2e019 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -156,6 +156,11 @@ struct dns_rdataset { * * \def DNS_RDATASETATTR_LOADORDER * Output the RRset in load order. + * + * \def DNS_RDATASETATTR_STALE_ADDED + * Set on rdatasets that were added during a stale-answer-client-timeout + * lookup. In other words, the RRset was added during a lookup of stale + * data and does not necessarily mean that the rdataset itself is stale. */ #define DNS_RDATASETATTR_NONE 0x00000000 /*%< No ordering. */ diff --git a/lib/ns/query.c b/lib/ns/query.c index 5bcbe7bb63..faab1340ed 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -5883,6 +5883,7 @@ query_lookup(query_ctx_t *qctx) { dns_ttl_t stale_refresh = 0; bool dbfind_stale = false; bool stale_timeout = false; + bool answer_found = false; bool stale_found = false; bool stale_refresh_window = false; uint16_t ede = 0; @@ -5990,6 +5991,14 @@ query_lookup(query_ctx_t *qctx) { */ stale_timeout = ((dboptions & DNS_DBFIND_STALETIMEOUT) != 0); + if (dns_rdataset_isassociated(qctx->rdataset) && + dns_rdataset_count(qctx->rdataset) > 0 && !STALE(qctx->rdataset)) + { + /* Found non-stale usable rdataset. */ + answer_found = true; + goto gotanswer; + } + if (dbfind_stale || stale_refresh_window || stale_timeout) { dns_name_format(qctx->client->query.qname, namebuf, sizeof(namebuf)); @@ -6121,7 +6130,8 @@ query_lookup(query_ctx_t *qctx) { } } - if (stale_timeout && stale_found) { +gotanswer: + if (stale_timeout && (answer_found || stale_found)) { /* * Mark RRsets that we are adding to the client message on a * lookup during 'stale-answer-client-timeout', so we can