From: Ondřej Surý Date: Thu, 18 Jun 2026 09:23:37 +0000 (+0200) Subject: Split the slabheader and slabheader_proof methods X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3079386aefa5b9423d90f69e9864051d30623316;p=thirdparty%2Fbind9.git Split the slabheader and slabheader_proof methods The noqname/closest proof pseudo-rdatasets share the slab data layout but have a different lifecycle: they reference a bare proof slab owned by the parent header and are torn down via dns_slabheader_freeproof(), not the rdataset's own teardown. Give them a dedicated dns_rdataslab_proof_rdatasetmethods table with their own disassociate/clone so the proof path can diverge from the real bound-rdataset path -- a prerequisite for reference counting the real headers without it ever reaching the proof slabs. --- diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index 187c289543..0d2681b610 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -192,7 +192,6 @@ struct dns_rdataset { * comments in rdataslab.c for details.) */ struct { - struct dns_db *db; dns_dbnode_t *node; unsigned char *raw; unsigned char *iter_pos; diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index baa6f8ef0c..85ceb537e0 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -1050,8 +1050,7 @@ bindrdataset(qpcache_t *qpdb, qpcnode_t *node, dns_slabheader_t *header, rdataset->ttl = 0; } - rdataset->slab.db = (dns_db_t *)qpdb; - rdataset->slab.node = (dns_dbnode_t *)node; + rdataset->slab.node = NULL; rdataset->slab.raw = header->raw; rdataset->slab.iter_pos = NULL; rdataset->slab.iter_count = 0; diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index 6bbb0cd971..d0d45a3325 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -95,6 +95,27 @@ dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods = { .getownercase = rdataset_getownercase, }; +static void +slabheader_proof_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG); +static void +slabheader_proof_clone(const dns_rdataset_t *source, + dns_rdataset_t *target DNS__DB_FLARG); + +dns_rdatasetmethods_t dns_rdataslab_proof_rdatasetmethods = { + .disassociate = slabheader_proof_disassociate, + .first = rdataset_first, + .next = rdataset_next, + .current = rdataset_current, + .clone = slabheader_proof_clone, + .count = rdataset_count, + .getnoqname = NULL, + .getclosest = NULL, + .settrust = NULL, + .expire = NULL, + .clearprefetch = NULL, + .getownercase = NULL, +}; + /*% Note: the "const void *" are just to make qsort happy. */ static int compare_rdata(const void *p1, const void *p2) { @@ -540,7 +561,8 @@ dns_slabheader_freeproof(isc_mem_t *mctx, dns_slabheader_proof_t **proofp) { static void rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG) { - dns_dbnode_t *node = rdataset->slab.node; + dns_slabheader_t *header = rdataset_getheader(rdataset); + dns_dbnode_t *node = header->node; dns__db_detachnode(&node DNS__DB_FLARG_PASS); } @@ -622,10 +644,11 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { static void rdataset_clone(const dns_rdataset_t *source, dns_rdataset_t *target DNS__DB_FLARG) { - dns_dbnode_t *node = source->slab.node; - dns_dbnode_t *cloned_node = NULL; + dns_slabheader_t *header = rdataset_getheader(source); + + dns__db_attachnode(header->node, + &(dns_dbnode_t *){ NULL } DNS__DB_FLARG_PASS); - dns__db_attachnode(node, &cloned_node DNS__DB_FLARG_PASS); INSIST(!ISC_LINK_LINKED(target, link)); *target = *source; ISC_LINK_INIT(target, link); @@ -645,8 +668,8 @@ static isc_result_t rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig DNS__DB_FLARG) { - dns_db_t *db = rdataset->slab.db; - dns_dbnode_t *node = rdataset->slab.node; + dns_slabheader_t *header = rdataset_getheader(rdataset); + dns_dbnode_t *node = header->node; const dns_slabheader_proof_t *noqname = rdataset->slab.noqname; /* @@ -661,12 +684,11 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, */ dns__db_attachnode(node, &(dns_dbnode_t *){ NULL } DNS__DB_FLARG_PASS); *nsec = (dns_rdataset_t){ - .methods = &dns_rdataslab_rdatasetmethods, - .rdclass = db->rdclass, + .methods = &dns_rdataslab_proof_rdatasetmethods, + .rdclass = rdataset->rdclass, .type = noqname->type, .ttl = rdataset->ttl, .trust = rdataset->trust, - .slab.db = db, .slab.node = node, .slab.raw = noqname->neg, .link = nsec->link, @@ -677,13 +699,12 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns__db_attachnode(node, &(dns_dbnode_t *){ NULL } DNS__DB_FLARG_PASS); *nsecsig = (dns_rdataset_t){ - .methods = &dns_rdataslab_rdatasetmethods, - .rdclass = db->rdclass, + .methods = &dns_rdataslab_proof_rdatasetmethods, + .rdclass = rdataset->rdclass, .type = dns_rdatatype_rrsig, .covers = noqname->type, .ttl = rdataset->ttl, .trust = rdataset->trust, - .slab.db = db, .slab.node = node, .slab.raw = noqname->negsig, .link = nsecsig->link, @@ -701,8 +722,8 @@ static isc_result_t rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig DNS__DB_FLARG) { - dns_db_t *db = rdataset->slab.db; - dns_dbnode_t *node = rdataset->slab.node; + dns_slabheader_t *header = rdataset_getheader(rdataset); + dns_dbnode_t *node = header->node; const dns_slabheader_proof_t *closest = rdataset->slab.closest; /* @@ -717,12 +738,11 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, */ dns__db_attachnode(node, &(dns_dbnode_t *){ NULL } DNS__DB_FLARG_PASS); *nsec = (dns_rdataset_t){ - .methods = &dns_rdataslab_rdatasetmethods, - .rdclass = db->rdclass, + .methods = &dns_rdataslab_proof_rdatasetmethods, + .rdclass = rdataset->rdclass, .type = closest->type, .ttl = rdataset->ttl, .trust = rdataset->trust, - .slab.db = db, .slab.node = node, .slab.raw = closest->neg, .link = nsec->link, @@ -733,13 +753,12 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns__db_attachnode(node, &(dns_dbnode_t *){ NULL } DNS__DB_FLARG_PASS); *nsecsig = (dns_rdataset_t){ - .methods = &dns_rdataslab_rdatasetmethods, - .rdclass = db->rdclass, + .methods = &dns_rdataslab_proof_rdatasetmethods, + .rdclass = rdataset->rdclass, .type = dns_rdatatype_rrsig, .covers = closest->type, .ttl = rdataset->ttl, .trust = rdataset->trust, - .slab.db = db, .slab.node = node, .slab.raw = closest->negsig, .link = nsecsig->link, @@ -809,6 +828,32 @@ rdataset_getheader(const dns_rdataset_t *rdataset) { return (dns_slabheader_t *)(rawbuf - offsetof(dns_slabheader_t, raw)); } +/* Fixed Proof helper macros */ + +static void +slabheader_proof_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG) { + dns_dbnode_t *node = rdataset->slab.node; + + dns__db_detachnode(&node DNS__DB_FLARG_PASS); +} + +static void +slabheader_proof_clone(const dns_rdataset_t *source, + dns_rdataset_t *target DNS__DB_FLARG) { + INSIST(!ISC_LINK_LINKED(target, link)); + INSIST(target->slab.node == NULL); + + *target = *source; + + ISC_LINK_INIT(target, link); + target->slab.node = NULL; + dns__db_attachnode(source->slab.node, + &target->slab.node DNS__DB_FLARG_PASS); + + target->slab.iter_pos = NULL; + target->slab.iter_count = 0; +} + dns_slabtop_t * dns_slabtop_new(isc_mem_t *mctx, dns_typepair_t typepair) { dns_slabtop_t *top = isc_mem_get(mctx, sizeof(*top));