don't keep stale NXDOMAIN cache entries

when serve-stale is enabled, NXDOMAIN cache entries are no longer
preserved after the normal negative cache TTL, in order to reduce
unnecessary cache memory consumption.

(cherry picked from commit f1485ca145)
This commit is contained in:
Evan Hunt 2022-06-03 16:22:01 -07:00 committed by Ondřej Surý
parent b6df5bfe2b
commit 2b78a2f9fa
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
2 changed files with 16 additions and 29 deletions

View file

@ -173,10 +173,8 @@ status=$((status+ret))
n=$((n+1))
echo_i "check stale nxdomain.example TXT ($n)"
ret=0
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
grep "EDE: 19 (Stale NXDOMAIN Answer): (resolver failure)" dig.out.test$n > /dev/null || ret=1
grep "example\..*4.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
@ -195,7 +193,6 @@ grep "1 TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #Others" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #!TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #NXDOMAIN" ns1/named.stats.$n.cachedb > /dev/null || ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
@ -409,10 +406,8 @@ status=$((status+ret))
n=$((n+1))
echo_i "check stale nxdomain.example TXT (serve-stale on) ($n)"
ret=0
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
grep "EDE: 19 (Stale NXDOMAIN Answer): (resolver failure)" dig.out.test$n > /dev/null || ret=1
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
grep "example\..*4.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
@ -479,10 +474,8 @@ status=$((status+ret))
n=$((n+1))
echo_i "check stale nxdomain.example TXT (serve-stale reset) ($n)"
ret=0
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
grep "EDE: 19 (Stale NXDOMAIN Answer): (resolver failure)" dig.out.test$n > /dev/null || ret=1
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
grep "example\..*4.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
@ -675,10 +668,8 @@ status=$((status+ret))
n=$((n+1))
echo_i "check stale nxdomain.example TXT (low max-stale-ttl) ($n)"
ret=0
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
grep "EDE: 19 (Stale NXDOMAIN Answer): (resolver failure)" dig.out.test$n > /dev/null || ret=1
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
grep "example\..*3.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
@ -697,7 +688,6 @@ grep "1 TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #Others" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #!TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #NXDOMAIN" ns1/named.stats.$n.cachedb > /dev/null || ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
@ -1118,7 +1108,6 @@ grep "1 TXT" ns3/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #TXT" ns3/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #Others" ns3/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #!TXT" ns3/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #NXDOMAIN" ns3/named.stats.$n.cachedb > /dev/null || ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
@ -1193,10 +1182,8 @@ status=$((status+ret))
n=$((n+1))
echo_i "check nxdomain.example TXT (max-stale-ttl default) ($n)"
ret=0
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
grep "EDE: 19 (Stale NXDOMAIN Answer): (resolver failure)" dig.out.test$n > /dev/null || ret=1
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
grep "example\..*30.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
@ -1369,7 +1356,6 @@ grep "1 TXT" ns4/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #TXT" ns4/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #Others" ns4/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #!TXT" ns4/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 #NXDOMAIN" ns4/named.stats.$n.cachedb > /dev/null || ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
@ -1497,7 +1483,6 @@ grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n > ns5/named.stats.$n.cache
grep "2 TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 Others" ns5/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 !TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 NXDOMAIN" ns5/named.stats.$n.cachedb > /dev/null || ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
@ -1579,7 +1564,6 @@ grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n > ns5/named.stats.$n.cache
grep -F "1 Others" ns5/named.stats.$n.cachedb > /dev/null || ret=1
grep -F "2 TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
grep -F "1 !TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
grep -F "1 NXDOMAIN" ns5/named.stats.$n.cachedb > /dev/null || ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
@ -1655,7 +1639,6 @@ grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n > ns5/named.stats.$n.cache
grep -F "#TXT" ns5/named.stats.$n.cachedb > /dev/null && ret=1
grep -F "#Others" ns5/named.stats.$n.cachedb > /dev/null && ret=1
grep -F "#!TXT" ns5/named.stats.$n.cachedb > /dev/null && ret=1
grep -F "#NXDOMAIN" ns5/named.stats.$n.cachedb > /dev/null && ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi

View file

@ -297,6 +297,7 @@ typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
#define STATCOUNT(header) \
((atomic_load_acquire(&(header)->attributes) & \
RDATASET_ATTR_STATCOUNT) != 0)
#define STALE_TTL(header, rbtdb) (NXDOMAIN(header) ? 0 : rbtdb->serve_stale_ttl)
#define RDATASET_ATTR_GET(header, attribute) \
(atomic_load_acquire(&(header)->attributes) & attribute)
@ -3003,7 +3004,8 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header,
* Mark header stale or ancient if the RRset is no longer active.
*/
if (!ACTIVE(header, now)) {
dns_ttl_t stale_ttl = header->rdh_ttl + rbtdb->serve_stale_ttl;
dns_ttl_t stale_ttl = header->rdh_ttl +
STALE_TTL(header, rbtdb);
/*
* If this data is in the stale window keep it and if
* DNS_DBFIND_STALEOK is not set we tell the caller to
@ -3043,7 +3045,8 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header,
}
if (stale && !ancient) {
dns_ttl_t stale_ttl = header->rdh_ttl + rbtdb->serve_stale_ttl;
dns_ttl_t stale_ttl = header->rdh_ttl +
STALE_TTL(header, rbtdb);
if (stale_ttl > now) {
rdataset->ttl = stale_ttl - now;
} else {
@ -4468,7 +4471,7 @@ check_stale_header(dns_rbtnode_t *node, rdatasetheader_t *header,
rbtdb_search_t *search, rdatasetheader_t **header_prev) {
if (!ACTIVE(header, search->now)) {
dns_ttl_t stale = header->rdh_ttl +
search->rbtdb->serve_stale_ttl;
STALE_TTL(header, search->rbtdb);
/*
* If this data is in the stale window keep it and if
* DNS_DBFIND_STALEOK is not set we tell the caller to
@ -5606,7 +5609,7 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
isc_rwlocktype_write);
for (header = rbtnode->data; header != NULL; header = header->next) {
if (header->rdh_ttl + rbtdb->serve_stale_ttl <=
if (header->rdh_ttl + STALE_TTL(header, rbtdb) <=
now - RBTDB_VIRTUAL)
{
/*
@ -5880,7 +5883,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
for (header = rbtnode->data; header != NULL; header = header_next) {
header_next = header->next;
if (!ACTIVE(header, now)) {
if ((header->rdh_ttl + rbtdb->serve_stale_ttl <
if ((header->rdh_ttl + STALE_TTL(header, rbtdb) <
now - RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS))
@ -6959,8 +6962,9 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
if (header != NULL && header->rdh_ttl + rbtdb->serve_stale_ttl <
now - RBTDB_VIRTUAL)
if (header != NULL &&
header->rdh_ttl + STALE_TTL(header, rbtdb) <
now - RBTDB_VIRTUAL)
{
expire_header(rbtdb, header, tree_locked, expire_ttl);
}