From 6202492509d37dcd67e0fcbdf46e1cbecac61e11 Mon Sep 17 00:00:00 2001 From: Alessio Podda Date: Mon, 2 Mar 2026 13:52:02 +0100 Subject: [PATCH] Remove node and db pointer from dns_rdataset_t.vec Now that we track the references at the vecheader level, binding an rdataset is no longer guaranteed to keep its node alive. Therefore remove the node pointer from the rdataset, and instead decide whether glue is required by explicitely passing the owner name to addglue. --- lib/dns/db.c | 5 +-- lib/dns/db_p.h | 2 +- lib/dns/include/dns/db.h | 7 +++-- lib/dns/include/dns/rdataset.h | 2 -- lib/dns/qpzone.c | 57 ++++++++++++++-------------------- lib/ns/query.c | 4 +-- tests/dns/qpzone_test.c | 12 ++----- 7 files changed, 36 insertions(+), 53 deletions(-) diff --git a/lib/dns/db.c b/lib/dns/db.c index e86e1cba2b..0ba7f5aa1f 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -1044,7 +1044,8 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats) { } isc_result_t -dns_db_addglue(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *rdataset, +dns_db_addglue(dns_db_t *db, dns_dbversion_t *version, + const dns_name_t *owner_name, dns_rdataset_t *rdataset, dns_message_t *msg) { REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); @@ -1053,7 +1054,7 @@ dns_db_addglue(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *rdataset, REQUIRE(rdataset->type == dns_rdatatype_ns); if (db->methods->addglue != NULL) { - (db->methods->addglue)(db, version, rdataset, msg); + (db->methods->addglue)(db, version, owner_name, rdataset, msg); return ISC_R_SUCCESS; } diff --git a/lib/dns/db_p.h b/lib/dns/db_p.h index eaee9207f9..630873e6b1 100644 --- a/lib/dns/db_p.h +++ b/lib/dns/db_p.h @@ -109,7 +109,7 @@ struct dns_gluelist { typedef struct dns_glue_additionaldata_ctx { dns_db_t *db; dns_dbversion_t *version; - dns_dbnode_t *node; + const dns_name_t *owner_name; dns_glue_t *glue; } dns_glue_additionaldata_ctx_t; diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index b73c3b12b4..bd8fca23d1 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -167,7 +167,8 @@ typedef struct dns_db_methods { isc_result_t (*getservestalerefresh)(dns_db_t *db, uint32_t *interval); isc_result_t (*setgluecachestats)(dns_db_t *db, isc_stats_t *stats); void (*addglue)(dns_db_t *db, dns_dbversion_t *version, - dns_rdataset_t *rdataset, dns_message_t *msg); + const dns_name_t *owner_name, dns_rdataset_t *rdataset, + dns_message_t *msg); void (*setmaxrrperset)(dns_db_t *db, uint32_t value); void (*setmaxtypepername)(dns_db_t *db, uint32_t value); isc_result_t (*getzoneversion)(dns_db_t *db, isc_buffer_t *b); @@ -1743,7 +1744,8 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats); */ isc_result_t -dns_db_addglue(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *rdataset, +dns_db_addglue(dns_db_t *db, dns_dbversion_t *version, + const dns_name_t *owner_name, dns_rdataset_t *rdataset, dns_message_t *msg); /*%< * Add glue records for rdataset to the additional section of message in @@ -1752,6 +1754,7 @@ dns_db_addglue(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *rdataset, * Requires: * \li 'db' is a database with 'zone' semantics. * \li 'version' is the DB version. + * \li 'owner_name' name of the rdataset. * \li 'rdataset' is a valid NS rdataset. * \li 'msg' is the DNS message to which the glue should be added. * diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index 430dc0321c..187c289543 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -208,8 +208,6 @@ struct dns_rdataset { * methods; see comments in rdatavec.c for details.) */ struct { - struct dns_db *db; - dns_dbnode_t *node; dns_vecheader_t *header; rdatavec_iter_t iter; } vec; diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 2731d6b196..80dbfbc72d 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -1157,7 +1157,7 @@ unref: } static void -bindrdataset(qpzonedb_t *qpdb, qpznode_t *node, dns_vecheader_t *header, +bindrdataset(qpzonedb_t *qpdb, dns_vecheader_t *header, dns_rdataset_t *rdataset DNS__DB_FLARG) { if (rdataset == NULL) { return; @@ -1176,8 +1176,6 @@ bindrdataset(qpzonedb_t *qpdb, qpznode_t *node, dns_vecheader_t *header, rdataset->attributes.optout = true; } - rdataset->vec.db = (dns_db_t *)qpdb; - rdataset->vec.node = (dns_dbnode_t *)node; rdataset->vec.header = header; dns_vecheader_ref(header); rdataset->vec.iter.iter_pos = NULL; @@ -1724,9 +1722,9 @@ qpzone_findrdataset(dns_db_t *db, dns_dbnode_t *dbnode, } } if (found != NULL) { - bindrdataset(qpdb, node, found, rdataset DNS__DB_FLARG_PASS); + bindrdataset(qpdb, found, rdataset DNS__DB_FLARG_PASS); if (foundsig != NULL) { - bindrdataset(qpdb, node, foundsig, + bindrdataset(qpdb, foundsig, sigrdataset DNS__DB_FLARG_PASS); } } @@ -2145,7 +2143,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename, return DNS_R_CNAMEANDOTHER; } - bindrdataset(qpdb, node, newheader, addedrdataset DNS__DB_FLARG_PASS); + bindrdataset(qpdb, newheader, addedrdataset DNS__DB_FLARG_PASS); return ISC_R_SUCCESS; } @@ -2778,11 +2776,10 @@ qpzone_setup_delegation(qpz_search_t *search, dns_dbnode_t **nodep, isc_rwlocktype_t nlocktype = isc_rwlocktype_none; isc_rwlock_t *nlock = qpzone_get_lock(node); NODE_RDLOCK(nlock, &nlocktype); - bindrdataset(search->qpdb, node, search->zonecut_header, + bindrdataset(search->qpdb, search->zonecut_header, rdataset DNS__DB_FLARG_PASS); if (sigrdataset != NULL && search->zonecut_sigheader != NULL) { - bindrdataset(search->qpdb, node, - search->zonecut_sigheader, + bindrdataset(search->qpdb, search->zonecut_sigheader, sigrdataset DNS__DB_FLARG_PASS); } NODE_UNLOCK(nlock, &nlocktype); @@ -3252,11 +3249,11 @@ again: node DNS__DB_FLARG_PASS); *nodep = (dns_dbnode_t *)node; } - bindrdataset(search->qpdb, node, found, + bindrdataset(search->qpdb, found, rdataset DNS__DB_FLARG_PASS); if (foundsig != NULL) { bindrdataset( - search->qpdb, node, foundsig, + search->qpdb, foundsig, sigrdataset DNS__DB_FLARG_PASS); } } else if (found == NULL && foundsig == NULL) { @@ -3869,10 +3866,10 @@ found: *nodep = (dns_dbnode_t *)node; } if (search.version->secure && !search.version->havensec3) { - bindrdataset(search.qpdb, node, nsecheader, + bindrdataset(search.qpdb, nsecheader, rdataset DNS__DB_FLARG_PASS); if (nsecsig != NULL) { - bindrdataset(search.qpdb, node, nsecsig, + bindrdataset(search.qpdb, nsecsig, sigrdataset DNS__DB_FLARG_PASS); } } @@ -3936,10 +3933,9 @@ found: } if (type != dns_rdatatype_any) { - bindrdataset(search.qpdb, node, found, - rdataset DNS__DB_FLARG_PASS); + bindrdataset(search.qpdb, found, rdataset DNS__DB_FLARG_PASS); if (foundsig != NULL) { - bindrdataset(search.qpdb, node, foundsig, + bindrdataset(search.qpdb, foundsig, sigrdataset DNS__DB_FLARG_PASS); } } @@ -4182,7 +4178,7 @@ rdatasetiter_current(dns_rdatasetiter_t *iterator, NODE_RDLOCK(nlock, &nlocktype); - bindrdataset(qpdb, qpnode, header, rdataset DNS__DB_FLARG_PASS); + bindrdataset(qpdb, header, rdataset DNS__DB_FLARG_PASS); NODE_UNLOCK(nlock, &nlocktype); } @@ -5146,15 +5142,13 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode, } if (result == ISC_R_SUCCESS && newrdataset != NULL) { - bindrdataset(qpdb, node, newheader, - newrdataset DNS__DB_FLARG_PASS); + bindrdataset(qpdb, newheader, newrdataset DNS__DB_FLARG_PASS); } if (result == DNS_R_NXRRSET && newrdataset != NULL && (options & DNS_DBSUB_WANTOLD) != 0) { - bindrdataset(qpdb, node, header, - newrdataset DNS__DB_FLARG_PASS); + bindrdataset(qpdb, header, newrdataset DNS__DB_FLARG_PASS); } unlock: @@ -5238,7 +5232,6 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype, dns_fixedname_t fixedname_a; dns_name_t *name_a = NULL; dns_rdataset_t rdataset_a, sigrdataset_a; - const qpznode_t *node = NULL; qpznode_t *node_a = NULL; dns_fixedname_t fixedname_aaaa; dns_name_t *name_aaaa = NULL; @@ -5253,8 +5246,6 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype, ctx = (dns_glue_additionaldata_ctx_t *)arg; - node = (qpznode_t *)ctx->node; - name_a = dns_fixedname_initname(&fixedname_a); dns_rdataset_init(&rdataset_a); dns_rdataset_init(&sigrdataset_a); @@ -5314,7 +5305,7 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype, * attributes for the first rdataset associated with the first name * added to the ADDITIONAL section. */ - if (glue != NULL && dns_name_issubdomain(name, &node->name)) { + if (glue != NULL && dns_name_issubdomain(name, ctx->owner_name)) { if (dns_rdataset_isassociated(&glue->rdataset_a)) { glue->rdataset_a.attributes.required = true; } @@ -5427,13 +5418,13 @@ addglue_to_message(dns_glue_t *ge, dns_message_t *msg) { } static dns_gluelist_t * -create_gluelist(qpzonedb_t *qpdb, qpz_version_t *version, qpznode_t *node, - dns_rdataset_t *rdataset) { +create_gluelist(qpzonedb_t *qpdb, qpz_version_t *version, + const dns_name_t *owner_name, dns_rdataset_t *rdataset) { dns_vecheader_t *header = dns_vecheader_getheader(rdataset); dns_glue_additionaldata_ctx_t ctx = { .db = (dns_db_t *)qpdb, .version = (dns_dbversion_t *)version, - .node = (dns_dbnode_t *)node, + .owner_name = owner_name, }; dns_gluelist_t *gluelist = new_gluelist(ctx.db, header, ctx.version); @@ -5453,17 +5444,15 @@ create_gluelist(qpzonedb_t *qpdb, qpz_version_t *version, qpznode_t *node, } static void -addglue(dns_db_t *db, dns_dbversion_t *dbversion, dns_rdataset_t *rdataset, - dns_message_t *msg) { +addglue(dns_db_t *db, dns_dbversion_t *dbversion, const dns_name_t *owner_name, + dns_rdataset_t *rdataset, dns_message_t *msg) { qpzonedb_t *qpdb = (qpzonedb_t *)db; qpz_version_t *version = (qpz_version_t *)dbversion; - qpznode_t *node = (qpznode_t *)rdataset->vec.node; dns_vecheader_t *header = dns_vecheader_getheader(rdataset); dns_glue_t *glue = NULL; isc_statscounter_t counter = dns_gluecachestatscounter_hits_absent; REQUIRE(rdataset->type == dns_rdatatype_ns); - REQUIRE(qpdb == (qpzonedb_t *)rdataset->vec.db); REQUIRE(qpdb == version->qpdb); REQUIRE(!IS_STUB(qpdb)); @@ -5475,8 +5464,8 @@ addglue(dns_db_t *db, dns_dbversion_t *dbversion, dns_rdataset_t *rdataset, dns_gluelist_t *xchg_gluelist = gluelist; dns_gluelist_t *old_gluelist = (void *)-1; - dns_gluelist_t *new_gluelist = create_gluelist(qpdb, version, - node, rdataset); + dns_gluelist_t *new_gluelist = + create_gluelist(qpdb, version, owner_name, rdataset); while (old_gluelist != xchg_gluelist && (xchg_gluelist == NULL || diff --git a/lib/ns/query.c b/lib/ns/query.c index 4deeda6074..4853da8edb 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -2233,8 +2233,8 @@ query_additional(query_ctx_t *qctx, dns_name_t *name, goto regular; } - result = dns_db_addglue(qctx->db, dbversion->version, rdataset, - client->message); + result = dns_db_addglue(qctx->db, dbversion->version, name, + rdataset, client->message); if (result == ISC_R_SUCCESS) { return; } diff --git a/tests/dns/qpzone_test.c b/tests/dns/qpzone_test.c index 817e72105f..ebb662bc42 100644 --- a/tests/dns/qpzone_test.c +++ b/tests/dns/qpzone_test.c @@ -186,14 +186,10 @@ ownercase_test_one(const char *str1, const char *str2) { .common.methods = &qpdb_zonemethods, .common.mctx = isc_g_mctx, }; - qpznode_t node = { .methods = &qpznode_methods, .locknum = 0 }; dns_vecheader_t header = { 0 }; dns_rdataset_t rdataset = { .magic = DNS_RDATASET_MAGIC, - .vec = { .db = (dns_db_t *)qpdb, - .node = (dns_dbnode_t *)&node, - .header = &header, - }, + .vec = { .header = &header }, .methods = &dns_rdatavec_rdatasetmethods, }; isc_buffer_t b; @@ -357,14 +353,10 @@ ISC_RUN_TEST_IMPL(setownercase) { .common.methods = &qpdb_zonemethods, .common.mctx = isc_g_mctx, }; - qpznode_t node = { .methods = &qpznode_methods, .locknum = 0 }; dns_vecheader_t header = { 0 }; dns_rdataset_t rdataset = { .magic = DNS_RDATASET_MAGIC, - .vec = { .db = (dns_db_t *)qpdb, - .node = (dns_dbnode_t *)&node, - .header = &header, - }, + .vec = { .header = &header }, .methods = &dns_rdatavec_rdatasetmethods, }; const char *str1 =