From: Ondřej Surý Date: Tue, 23 Sep 2025 07:54:45 +0000 (+0200) Subject: Expire related headers at the same time X-Git-Tag: v9.21.14~31^2~1 X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=0f13d7f2faffc14279cff7362cf545809e31fe4b;p=thirdparty%2Fbind9.git Expire related headers at the same time Previously, the slabtops for "type" and its signature was only loosely coupled and the headers could expire at different time (both TTL and LRU based expiry). This commit expires the headers in both related headers. Co-authored-by: Matthijs Mekking --- diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index c3ee91f5a49..62ad3e0775f 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -502,12 +502,22 @@ expire_lru_headers(qpcache_t *qpdb, uint32_t idx, size_t requested, return; } + dns_slabtop_t *related = top->related; + ISC_SIEVE_UNLINK(qpdb->buckets[idx].sieve, top, link); dns_slabheader_t *header = first_header(top); - expired += expireheader(header, nlocktypep, tlocktypep, dns_expire_lru DNS__DB_FLARG_PASS); + + if (related != NULL) { + header = first_header(related); + + expired += + expireheader(header, nlocktypep, tlocktypep, + dns_expire_lru DNS__DB_FLARG_PASS); + } + } while (expired < requested); } @@ -598,6 +608,11 @@ clean_cache_node(qpcache_t *qpdb, qpcnode_t *node) { * If current slabtop is empty, we can clean it up. */ if (header == NULL) { + if (top->related != NULL) { + top->related->related = NULL; + top->related = NULL; + } + cds_list_del(&top->types_link); if (ISC_LINK_LINKED(top, link)) { @@ -927,6 +942,7 @@ static size_t expireheader(dns_slabheader_t *header, isc_rwlocktype_t *nlocktypep, isc_rwlocktype_t *tlocktypep, dns_expire_t reason DNS__DB_FLARG) { size_t expired = rdataset_size(header); + mark_ancient(header); if (isc_refcount_current(&HEADERNODE(header)->erefs) == 0) { @@ -2182,14 +2198,23 @@ qpcnode_expiredata(dns_dbnode_t *node, void *data) { qpcnode_t *qpnode = (qpcnode_t *)node; qpcache_t *qpdb = (qpcache_t *)qpnode->qpdb; + dns_slabtop_t *related = NULL; dns_slabheader_t *header = data; isc_rwlocktype_t nlocktype = isc_rwlocktype_none; isc_rwlocktype_t tlocktype = isc_rwlocktype_none; isc_rwlock_t *nlock = &qpdb->buckets[qpnode->locknum].lock; NODE_WRLOCK(nlock, &nlocktype); + related = header->top->related; + (void)expireheader(header, &nlocktype, &tlocktype, dns_expire_flush DNS__DB_FILELINE); + if (related != NULL) { + header = first_header(related); + (void)expireheader(header, &nlocktype, &tlocktype, + dns_expire_flush DNS__DB_FILELINE); + } + NODE_UNLOCK(nlock, &nlocktype); INSIST(tlocktype == isc_rwlocktype_none); }