]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add proper qp cleanup
authorMatthijs Mekking <matthijs@isc.org>
Wed, 17 Jan 2024 15:53:27 +0000 (16:53 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 6 Mar 2024 08:57:25 +0000 (09:57 +0100)
Fix reference counting: unreference nodes that are succesfully inserted
in the tree, detach created nodes, and cleanup the interior data in
dns_qpdata_destroy().

lib/dns/qp-zonedb.c
lib/dns/qpdb.c

index f5a14a33efbbc86c9f8a2abf86e9be1af1fbae48..b545b506bf89d2633cfe5018c71d52312e3036fe 100644 (file)
@@ -1624,10 +1624,11 @@ loadnode(dns_qpdb_t *qpdb, const dns_name_t *name, dns_qpdata_t **nodep,
        } else {
                INSIST(nsecnode == NULL);
                nsecnode = dns_qpdata_create(qpdb, name);
+               nsecnode->nsec = DNS_DB_NSEC_NSEC;
                nsecresult = dns_qp_insert(qpdb->nsec, nsecnode, 0);
                INSIST(nsecresult == ISC_R_SUCCESS);
+               dns_qpdata_detach(&nsecnode);
        }
-       nsecnode->nsec = DNS_DB_NSEC_NSEC;
        node->nsec = DNS_DB_NSEC_HAS_NSEC;
 
 done:
@@ -1695,6 +1696,7 @@ loading_addrdataset(void *arg, const dns_name_t *name,
                        node = dns_qpdata_create(qpdb, name);
                        result = dns_qp_insert(qpdb->nsec3, node, 0);
                        INSIST(result == ISC_R_SUCCESS);
+                       dns_qpdata_unref(node);
                }
                node->nsec = DNS_DB_NSEC_NSEC3;
        } else if (rdataset->type == dns_rdatatype_nsec) {
@@ -2430,6 +2432,7 @@ dns__qpzone_wildcardmagic(dns_qpdb_t *qpdb, const dns_name_t *name, bool lock) {
                node = dns_qpdata_create(qpdb, &foundname);
                result = dns_qp_insert(qpdb->tree, node, 0);
                INSIST(result == ISC_R_SUCCESS);
+               dns_qpdata_unref(node);
        }
 
        INSIST(result == ISC_R_SUCCESS);
@@ -2471,10 +2474,11 @@ dns__qpzone_addwildcards(dns_qpdb_t *qpdb, const dns_name_t *name, bool lock) {
                        if (result != ISC_R_SUCCESS) {
                                INSIST(node == NULL);
                                node = dns_qpdata_create(qpdb, name);
+                               node->nsec = DNS_DB_NSEC_NORMAL;
                                result = dns_qp_insert(qpdb->tree, node, 0);
                                INSIST(result == ISC_R_SUCCESS);
-                       }
-                       if (result == ISC_R_SUCCESS) {
+                               dns_qpdata_detach(&node);
+                       } else if (result == ISC_R_SUCCESS) {
                                node->nsec = DNS_DB_NSEC_NORMAL;
                        }
                }
index 903356a3c46b6c98c8ac903cf085c177f5f07085..b68b8ccf4d750356e621557bcf4d5c2ef9237d99 100644 (file)
@@ -600,6 +600,13 @@ dns__qpdb_destroy(dns_db_t *arg) {
        unsigned int i;
        unsigned int inactive = 0;
 
+       if (rbtdb->origin_node != NULL) {
+               dns_qpdata_detach(&rbtdb->origin_node);
+       }
+       if (rbtdb->nsec3_origin_node != NULL) {
+               dns_qpdata_detach(&rbtdb->nsec3_origin_node);
+       }
+
        /* XXX check for open versions here */
 
        if (qpdb->soanode != NULL) {
@@ -1991,6 +1998,7 @@ dns__qpdb_findnodeintree(dns_qpdb_t *qpdb, dns_qp_t *tree,
                node = dns_qpdata_create(qpdb, name);
                result = dns_qp_insert(tree, node, 0);
                INSIST(result == ISC_R_SUCCESS);
+               dns_qpdata_unref(node);
 
                if (tree == qpdb->tree) {
                        dns__qpzone_addwildcards(qpdb, name, true);
@@ -3316,6 +3324,7 @@ dns__qpdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
                        nsecnode->nsec = DNS_DB_NSEC_NSEC;
                        result = dns_qp_insert(qpdb->nsec, nsecnode, 0);
                        INSIST(result == ISC_R_SUCCESS);
+                       dns_qpdata_detach(&nsecnode);
                }
                qpnode->nsec = DNS_DB_NSEC_HAS_NSEC;
        }
@@ -4766,7 +4775,21 @@ dns_qpdata_create(dns_qpdb_t *qpdb, const dns_name_t *name) {
 
 void
 dns_qpdata_destroy(dns_qpdata_t *data) {
-       dns_name_free(data->name, data->mctx);
+       dns_slabheader_t *current = NULL, *next = NULL;
+
+       for (current = data->data; current != NULL; current = next) {
+               dns_slabheader_t *down = current->down, *down_next = NULL;
+
+               next = current->next;
+
+               for (down = current->down; down != NULL; down = down_next) {
+                       down_next = down->down;
+                       dns_slabheader_destroy(&down);
+               }
+
+               dns_slabheader_destroy(&current);
+       }
+
        isc_mem_putanddetach(&data->mctx, data, sizeof(dns_qpdata_t));
 }