]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove node and db pointer from dns_rdataset_t.vec
authorAlessio Podda <alessio@isc.org>
Mon, 2 Mar 2026 12:52:02 +0000 (13:52 +0100)
committerAlessio Podda <alessio@isc.org>
Tue, 31 Mar 2026 14:22:56 +0000 (16:22 +0200)
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
lib/dns/db_p.h
lib/dns/include/dns/db.h
lib/dns/include/dns/rdataset.h
lib/dns/qpzone.c
lib/ns/query.c
tests/dns/qpzone_test.c

index e86e1cba2b92fd8b7f49c24f9b631b10ba13c9b2..0ba7f5aa1f3ec6f5fe48983930435fe03a63829e 100644 (file)
@@ -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;
        }
index eaee9207f9d35674c3f0cf3d8a542442545a26e7..630873e6b1e9092a0e44e7cf68afe0365fd1264e 100644 (file)
@@ -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;
index b73c3b12b4e725391ae9ddaa65db3c6552adc7b9..bd8fca23d14008ff6d2d4f3baf2bde4ae4722efb 100644 (file)
@@ -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.
  *
index 430dc0321ca1ca4cf82aaa612c9a760b58129e03..187c289543b9a2fba272466ed72a5137add4e7d5 100644 (file)
@@ -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;
index 2731d6b196aae04d9a715235d9529d09370daa6e..80dbfbc72d10bc9d11cffe14358376d9a4e82ed3 100644 (file)
@@ -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 ||
index 4deeda60742c20987b0da36ad99ce8d3b1e0246e..4853da8edba9288b7810313dbf392aa68eee148b 100644 (file)
@@ -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;
                }
index 817e72105f6200ee7b12ca65e8af23f6daf0f0b2..ebb662bc4259d3d5a3fd9d7d9e3493cf65f4ae10 100644 (file)
@@ -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 =