From: Alessio Podda Date: Mon, 2 Mar 2026 12:52:02 +0000 (+0100) Subject: Remove node and db pointer from dns_rdataset_t.vec X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6202492509d37dcd67e0fcbdf46e1cbecac61e11;p=thirdparty%2Fbind9.git 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. --- diff --git a/lib/dns/db.c b/lib/dns/db.c index e86e1cba2b9..0ba7f5aa1f3 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 eaee9207f9d..630873e6b1e 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 b73c3b12b4e..bd8fca23d14 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 430dc0321ca..187c289543b 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 2731d6b196a..80dbfbc72d1 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 4deeda60742..4853da8edba 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 817e72105f6..ebb662bc425 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 =