]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
use a qp-trie for the keytable
authorEvan Hunt <each@isc.org>
Sat, 15 Apr 2023 21:49:45 +0000 (14:49 -0700)
committerOndřej Surý <ondrej@isc.org>
Tue, 15 Aug 2023 12:25:24 +0000 (14:25 +0200)
Instead of an RBT for the trust anchor tables, use a QP-trie.

12 files changed:
bin/delv/delv.c
bin/named/server.c
lib/dns/client.c
lib/dns/include/dns/keytable.h
lib/dns/include/dns/view.h
lib/dns/keytable.c
lib/dns/validator.c
lib/dns/view.c
lib/dns/zone.c
lib/dns/zoneverify.c
lib/ns/query.c
tests/dns/keytable_test.c

index 2e6f82c7e5e9546e985cc868d0f4d38521261a43..e947abedec6334f209d691a2683b0fc9c142ebf7 100644 (file)
@@ -2161,7 +2161,7 @@ run_server(void *arg) {
        view->qminimization = qmin;
        view->qmin_strict = qmin_strict;
 
-       CHECK(dns_view_initsecroots(view, mctx));
+       dns_view_initsecroots(view);
        CHECK(setup_dnsseckeys(NULL, view));
 
        dns_view_setdispatchmgr(view, dispatchmgr);
index 667bca425b773e46d365acfeb59a58358e4970a7..c8b1bdbf816d773c27543490a97112bd3b209a98 100644 (file)
@@ -1044,7 +1044,7 @@ keyloaded(dns_view_t *view, const dns_name_t *name) {
        result = dns_keytable_find(secroots, name, &keynode);
 
        if (keynode != NULL) {
-               dns_keytable_detachkeynode(secroots, &keynode);
+               dns_keynode_detach(&keynode);
        }
        if (secroots != NULL) {
                dns_keytable_detach(&secroots);
@@ -1062,7 +1062,7 @@ keyloaded(dns_view_t *view, const dns_name_t *name) {
 static isc_result_t
 configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
                          const cfg_obj_t *config, const cfg_obj_t *bindkeys,
-                         bool auto_root, isc_mem_t *mctx) {
+                         bool auto_root) {
        isc_result_t result = ISC_R_SUCCESS;
        const cfg_obj_t *view_keys = NULL;
        const cfg_obj_t *global_keys = NULL;
@@ -1116,14 +1116,7 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
        maps[i++] = named_g_defaults;
        maps[i] = NULL;
 
-       result = dns_view_initsecroots(view, mctx);
-       if (result != ISC_R_SUCCESS) {
-               isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
-                             NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
-                             "couldn't create keytable");
-               return (ISC_R_UNEXPECTED);
-       }
-
+       dns_view_initsecroots(view);
        dns_view_initntatable(view, named_g_loopmgr);
 
        if (auto_root && view->rdclass == dns_rdataclass_in) {
@@ -5534,7 +5527,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
         * "security roots".
         */
        CHECK(configure_view_dnsseckeys(view, vconfig, config, bindkeys,
-                                       auto_root, mctx));
+                                       auto_root));
        dns_resolver_resetmustbesecure(view->resolver);
        obj = NULL;
        result = named_config_get(maps, "dnssec-must-be-secure", &obj);
@@ -7309,7 +7302,7 @@ tat_timer_tick(void *arg) {
 
                dotat_arg.view = view;
                dotat_arg.loop = named_g_mainloop;
-               (void)dns_keytable_forall(secroots, dotat, &dotat_arg);
+               dns_keytable_forall(secroots, dotat, &dotat_arg);
                dns_keytable_detach(&secroots);
        }
 }
index e21270009796e10eb06f87562f858023393822ba..2eee2d34809d207dc6b5808d07102a758ec592da 100644 (file)
@@ -214,28 +214,18 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_loopmgr_t *loopmgr,
        dns_view_setdispatchmgr(view, dispatchmgr);
 
        /* Initialize view security roots */
-       result = dns_view_initsecroots(view, mctx);
-       if (result != ISC_R_SUCCESS) {
-               goto cleanup_view;
-       }
-
-       result = dns_view_createresolver(view, loopmgr, 1, nm, 0,
-                                        tlsctx_client_cache, dispatchv4,
-                                        dispatchv6);
-       if (result != ISC_R_SUCCESS) {
-               goto cleanup_view;
-       }
+       dns_view_initsecroots(view);
 
-       result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache,
-                              rdclass, 0, NULL, &view->cachedb);
-       if (result != ISC_R_SUCCESS) {
-               goto cleanup_view;
-       }
+       CHECK(dns_view_createresolver(view, loopmgr, 1, nm, 0,
+                                     tlsctx_client_cache, dispatchv4,
+                                     dispatchv6));
+       CHECK(dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache,
+                           rdclass, 0, NULL, &view->cachedb));
 
        *viewp = view;
        return (ISC_R_SUCCESS);
 
-cleanup_view:
+cleanup:
        dns_view_detach(&view);
        return (result);
 }
index 6095a85e3fae6e9d59303330033ba29202bc0930..b407cf2552ad7fafb983700231735120472733e6 100644 (file)
@@ -51,59 +51,15 @@ ISC_LANG_BEGINDECLS
 
 typedef void (*dns_keytable_callback_t)(const dns_name_t *name, void *fn_arg);
 
-isc_result_t
-dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep);
+void
+dns_keytable_create(dns_view_t *view, dns_keytable_t **keytablep);
 /*%<
  * Create a keytable.
  *
  * Requires:
  *
- *\li  'mctx' is a valid memory context.
- *
+ *\li  'view' is a valid memory context.
  *\li  keytablep != NULL && *keytablep == NULL
- *
- * Ensures:
- *
- *\li  On success, *keytablep is a valid, empty key table.
- *
- * Returns:
- *
- *\li  ISC_R_SUCCESS
- *
- *\li  Any other result indicates failure.
- */
-
-void
-dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp);
-/*%<
- * Attach *targetp to source.
- *
- * Requires:
- *
- *\li  'source' is a valid keytable.
- *
- *\li  'targetp' points to a NULL dns_keytable_t *.
- *
- * Ensures:
- *
- *\li  *targetp is attached to source.
- */
-
-void
-dns_keytable_detach(dns_keytable_t **keytablep);
-/*%<
- * Detach *keytablep from its keytable.
- *
- * Requires:
- *
- *\li  'keytablep' points to a valid keytable.
- *
- * Ensures:
- *
- *\li  *keytablep is NULL.
- *
- *\li  If '*keytablep' is the last reference to the keytable,
- *             all resources used by the keytable will be freed
  */
 
 isc_result_t
@@ -252,20 +208,6 @@ dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name,
  *\li  Any other result indicates an error.
  */
 
-void
-dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep);
-/*%<
- * Detach a keynode found via dns_keytable_find().
- *
- * Requires:
- *
- *\li  *keynodep is a valid keynode returned by a call to dns_keytable_find().
- *
- * Ensures:
- *
- *\li  *keynodep == NULL
- */
-
 isc_result_t
 dns_keytable_issecuredomain(dns_keytable_t *keytable, const dns_name_t *name,
                            dns_name_t *foundname, bool *wantdnssecp);
@@ -343,9 +285,15 @@ dns_keynode_trust(dns_keynode_t *keynode);
  * trusted: no longer an initializing key.
  */
 
-isc_result_t
+void
 dns_keytable_forall(dns_keytable_t *keytable,
                    void (*func)(dns_keytable_t *, dns_keynode_t *,
                                 dns_name_t *, void *),
                    void *arg);
+/*%<
+ * Call 'func' on each keynode in 'keytable'.
+ */
+
+ISC_REFCOUNT_DECL(dns_keytable);
+ISC_REFCOUNT_DECL(dns_keynode);
 ISC_LANG_ENDDECLS
index 9269e27b5675fc7346cdd5dab60d1b7f4565b5de..f22cb876a296b78b17937ad87c28331453cda99a 100644 (file)
@@ -960,8 +960,8 @@ dns_view_getntatable(dns_view_t *view, dns_ntatable_t **ntp);
  *\li  ISC_R_NOTFOUND
  */
 
-isc_result_t
-dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx);
+void
+dns_view_initsecroots(dns_view_t *view);
 /*%<
  * Initialize security roots for the view, detaching any previously
  * existing security roots first.  (Note that secroots_priv is
index aa8c66ef81edd677c3b0e75336c5f763f14c9770..99ffe5623ac868379cce3c91bc2c32c15441c92e 100644 (file)
 #include <dns/dnssec.h>
 #include <dns/fixedname.h>
 #include <dns/keytable.h>
-#include <dns/rbt.h>
+#include <dns/qp.h>
 #include <dns/rdata.h>
 #include <dns/rdatalist.h>
 #include <dns/rdataset.h>
 #include <dns/rdatastruct.h>
+#include <dns/view.h>
 
 #define KEYTABLE_MAGIC    ISC_MAGIC('K', 'T', 'b', 'l')
 #define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC)
 #define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC)
 
 struct dns_keytable {
-       /* Unlocked. */
        unsigned int magic;
        isc_mem_t *mctx;
        isc_refcount_t references;
        isc_rwlock_t rwlock;
-       /* Locked by rwlock. */
-       dns_rbt_t *table;
+       dns_qpmulti_t *table;
 };
 
 struct dns_keynode {
        unsigned int magic;
        isc_mem_t *mctx;
-       isc_refcount_t refcount;
+       isc_refcount_t references;
        isc_rwlock_t rwlock;
+       dns_fixedname_t fn;
+       dns_name_t *name;
        dns_rdatalist_t *dslist;
        dns_rdataset_t dsset;
        bool managed;
@@ -59,9 +60,27 @@ struct dns_keynode {
 };
 
 static dns_keynode_t *
-new_keynode(dns_rdata_ds_t *ds, dns_keytable_t *keytable, bool managed,
-           bool initial);
+new_keynode(const dns_name_t *name, dns_rdata_ds_t *ds,
+           dns_keytable_t *keytable, bool managed, bool initial);
+
+/* QP trie methods */
+static void
+qp_attach(void *uctx, void *pval, uint32_t ival);
+static void
+qp_detach(void *uctx, void *pval, uint32_t ival);
+static size_t
+qp_makekey(dns_qpkey_t key, void *uctx, void *pval, uint32_t ival);
+static void
+qp_triename(void *uctx, char *buf, size_t size);
+
+static dns_qpmethods_t qpmethods = {
+       qp_attach,
+       qp_detach,
+       qp_makekey,
+       qp_triename,
+};
 
+/* rdataset methods */
 static void
 keynode_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG);
 static isc_result_t
@@ -82,55 +101,33 @@ static dns_rdatasetmethods_t methods = {
 };
 
 static void
-keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
-       REQUIRE(VALID_KEYNODE(source));
-       isc_refcount_increment(&source->refcount);
-       *target = source;
-}
-
-static void
-keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynodep) {
-       REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
-       dns_keynode_t *knode = *keynodep;
-       *keynodep = NULL;
-
-       if (isc_refcount_decrement(&knode->refcount) == 1) {
-               dns_rdata_t *rdata = NULL;
-               isc_refcount_destroy(&knode->refcount);
-               isc_rwlock_destroy(&knode->rwlock);
-               if (knode->dslist != NULL) {
-                       for (rdata = ISC_LIST_HEAD(knode->dslist->rdata);
-                            rdata != NULL;
-                            rdata = ISC_LIST_HEAD(knode->dslist->rdata))
-                       {
-                               ISC_LIST_UNLINK(knode->dslist->rdata, rdata,
-                                               link);
-                               isc_mem_put(mctx, rdata->data,
-                                           DNS_DS_BUFFERSIZE);
-                               isc_mem_put(mctx, rdata, sizeof(*rdata));
-                       }
+destroy_keynode(dns_keynode_t *knode) {
+       dns_rdata_t *rdata = NULL;
 
-                       isc_mem_put(mctx, knode->dslist,
-                                   sizeof(*knode->dslist));
-                       knode->dslist = NULL;
+       isc_refcount_destroy(&knode->references);
+       isc_rwlock_destroy(&knode->rwlock);
+       if (knode->dslist != NULL) {
+               for (rdata = ISC_LIST_HEAD(knode->dslist->rdata); rdata != NULL;
+                    rdata = ISC_LIST_HEAD(knode->dslist->rdata))
+               {
+                       ISC_LIST_UNLINK(knode->dslist->rdata, rdata, link);
+                       isc_mem_put(knode->mctx, rdata->data,
+                                   DNS_DS_BUFFERSIZE);
+                       isc_mem_put(knode->mctx, rdata, sizeof(*rdata));
                }
-               isc_mem_putanddetach(&knode->mctx, knode,
-                                    sizeof(dns_keynode_t));
-       }
-}
 
-static void
-free_keynode(void *node, void *arg) {
-       dns_keynode_t *keynode = node;
-       isc_mem_t *mctx = arg;
+               isc_mem_put(knode->mctx, knode->dslist, sizeof(*knode->dslist));
+               knode->dslist = NULL;
+       }
 
-       keynode_detach(mctx, &keynode);
+       isc_mem_putanddetach(&knode->mctx, knode, sizeof(dns_keynode_t));
 }
 
-isc_result_t
-dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
-       dns_keytable_t *keytable;
-       isc_result_t result;
+ISC_REFCOUNT_IMPL(dns_keynode, destroy_keynode);
+
+void
+dns_keytable_create(dns_view_t *view, dns_keytable_t **keytablep) {
+       dns_keytable_t *keytable = NULL;
 
        /*
         * Create a keytable.
@@ -138,55 +135,40 @@ dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
 
        REQUIRE(keytablep != NULL && *keytablep == NULL);
 
-       keytable = isc_mem_get(mctx, sizeof(*keytable));
+       keytable = isc_mem_get(view->mctx, sizeof(*keytable));
+       *keytable = (dns_keytable_t){
+               .magic = KEYTABLE_MAGIC,
+       };
 
-       keytable->table = NULL;
-       result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table);
-       if (result != ISC_R_SUCCESS) {
-               goto cleanup_keytable;
-       }
-
-       isc_rwlock_init(&keytable->rwlock);
+       isc_mem_attach(view->mctx, &keytable->mctx);
+       dns_qpmulti_create(view->mctx, &qpmethods, view, &keytable->table);
        isc_refcount_init(&keytable->references, 1);
-
-       keytable->mctx = NULL;
-       isc_mem_attach(mctx, &keytable->mctx);
-       keytable->magic = KEYTABLE_MAGIC;
        *keytablep = keytable;
+}
 
-       return (ISC_R_SUCCESS);
-
-cleanup_keytable:
-       isc_mem_putanddetach(&mctx, keytable, sizeof(*keytable));
+static void
+destroy_keytable(dns_keytable_t *keytable) {
+       dns_qpread_t qpr;
+       dns_qpiter_t iter;
+       void *pval = NULL;
 
-       return (result);
-}
+       keytable->magic = 0;
 
-void
-dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
-       REQUIRE(VALID_KEYTABLE(source));
-       REQUIRE(targetp != NULL && *targetp == NULL);
+       dns_qpmulti_query(keytable->table, &qpr);
+       dns_qpiter_init(&qpr, &iter);
+       while (dns_qpiter_next(&iter, &pval, NULL) == ISC_R_SUCCESS) {
+               dns_keynode_t *n = pval;
+               dns_keynode_detach(&n);
+       }
+       dns_qpread_destroy(keytable->table, &qpr);
 
-       isc_refcount_increment(&source->references);
+       dns_qpmulti_destroy(&keytable->table);
+       isc_refcount_destroy(&keytable->references);
 
-       *targetp = source;
+       isc_mem_putanddetach(&keytable->mctx, keytable, sizeof(*keytable));
 }
 
-void
-dns_keytable_detach(dns_keytable_t **keytablep) {
-       REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep));
-       dns_keytable_t *keytable = *keytablep;
-       *keytablep = NULL;
-
-       if (isc_refcount_decrement(&keytable->references) == 1) {
-               isc_refcount_destroy(&keytable->references);
-               dns_rbt_destroy(&keytable->table);
-               isc_rwlock_destroy(&keytable->rwlock);
-               keytable->magic = 0;
-               isc_mem_putanddetach(&keytable->mctx, keytable,
-                                    sizeof(*keytable));
-       }
-}
+ISC_REFCOUNT_IMPL(dns_keytable, destroy_keytable);
 
 static void
 add_ds(dns_keynode_t *knode, dns_rdata_ds_t *ds, isc_mem_t *mctx) {
@@ -245,13 +227,15 @@ add_ds(dns_keynode_t *knode, dns_rdata_ds_t *ds, isc_mem_t *mctx) {
 }
 
 static isc_result_t
-delete_ds(dns_keytable_t *keytable, dns_rbtnode_t *node, dns_rdata_ds_t *ds) {
-       dns_keynode_t *knode = node->data;
+delete_ds(dns_qp_t *qp, dns_keytable_t *keytable, dns_keynode_t *knode,
+         dns_rdata_ds_t *ds) {
        isc_result_t result;
        dns_rdata_t dsrdata = DNS_RDATA_INIT;
        dns_rdata_t *rdata = NULL;
+       dns_keynode_t *newnode = NULL;
        unsigned char data[DNS_DS_BUFFERSIZE];
        bool found = false;
+       void *pval = NULL;
        isc_buffer_t b;
 
        RWLOCK(&knode->rwlock, isc_rwlocktype_read);
@@ -290,8 +274,8 @@ delete_ds(dns_keytable_t *keytable, dns_rbtnode_t *node, dns_rdata_ds_t *ds) {
        /*
         * Replace knode with a new instance without the DS.
         */
-       node->data = new_keynode(NULL, keytable, knode->managed,
-                                knode->initial);
+       newnode = new_keynode(knode->name, NULL, keytable, knode->managed,
+                             knode->initial);
        for (rdata = ISC_LIST_HEAD(knode->dslist->rdata); rdata != NULL;
             rdata = ISC_LIST_NEXT(rdata, link))
        {
@@ -299,13 +283,20 @@ delete_ds(dns_keytable_t *keytable, dns_rbtnode_t *node, dns_rdata_ds_t *ds) {
                        dns_rdata_ds_t ds0;
                        result = dns_rdata_tostruct(rdata, &ds0, NULL);
                        RUNTIME_CHECK(result == ISC_R_SUCCESS);
-                       add_ds(node->data, &ds0, keytable->mctx);
+                       add_ds(newnode, &ds0, keytable->mctx);
                }
        }
-       RWUNLOCK(&knode->rwlock, isc_rwlocktype_read);
 
-       keynode_detach(keytable->mctx, &knode);
+       result = dns_qp_deletename(qp, knode->name, &pval, NULL);
+       INSIST(result == ISC_R_SUCCESS);
+       INSIST(pval == knode);
+
+       result = dns_qp_insert(qp, newnode, 0);
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+       RWUNLOCK(&knode->rwlock, isc_rwlocktype_read);
 
+       dns_keynode_detach(&knode);
        return (ISC_R_SUCCESS);
 }
 
@@ -315,8 +306,8 @@ delete_ds(dns_keytable_t *keytable, dns_rbtnode_t *node, dns_rdata_ds_t *ds) {
  * to "node" in "keytable".
  */
 static dns_keynode_t *
-new_keynode(dns_rdata_ds_t *ds, dns_keytable_t *keytable, bool managed,
-           bool initial) {
+new_keynode(const dns_name_t *name, dns_rdata_ds_t *ds,
+           dns_keytable_t *keytable, bool managed, bool initial) {
        dns_keynode_t *knode = NULL;
 
        REQUIRE(VALID_KEYTABLE(keytable));
@@ -326,9 +317,12 @@ new_keynode(dns_rdata_ds_t *ds, dns_keytable_t *keytable, bool managed,
        *knode = (dns_keynode_t){ .magic = KEYNODE_MAGIC };
 
        dns_rdataset_init(&knode->dsset);
-       isc_refcount_init(&knode->refcount, 1);
+       isc_refcount_init(&knode->references, 1);
        isc_rwlock_init(&knode->rwlock);
 
+       knode->name = dns_fixedname_initname(&knode->fn);
+       dns_name_copy(name, knode->name);
+
        /*
         * If a DS was supplied, initialize an rdatalist.
         */
@@ -354,45 +348,41 @@ static isc_result_t
 insert(dns_keytable_t *keytable, bool managed, bool initial,
        const dns_name_t *keyname, dns_rdata_ds_t *ds,
        dns_keytable_callback_t callback, void *callback_arg) {
-       dns_rbtnode_t *node = NULL;
        isc_result_t result;
+       dns_keynode_t *newnode = NULL;
+       dns_qp_t *qp = NULL;
+       void *pval = NULL;
 
        REQUIRE(VALID_KEYTABLE(keytable));
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
+       dns_qpmulti_write(keytable->table, &qp);
 
-       result = dns_rbt_addnode(keytable->table, keyname, &node);
-       if (result == ISC_R_SUCCESS) {
+       result = dns_qp_getname(qp, keyname, &pval, NULL);
+       if (result != ISC_R_SUCCESS) {
                /*
-                * There was no node for "keyname" in "keytable" yet, so one
+                * There was no match for "keyname" in "keytable" yet, so one
                 * was created.  Create a new key node for the supplied
                 * trust anchor (or a null key node if "ds" is NULL)
-                * and attach it to the created node.
+                * and insert it.
                 */
-               node->data = new_keynode(ds, keytable, managed, initial);
+               newnode = new_keynode(keyname, ds, keytable, managed, initial);
+               result = dns_qp_insert(qp, newnode, 0);
                if (callback != NULL) {
                        (*callback)(keyname, callback_arg);
                }
-       } else if (result == ISC_R_EXISTS) {
+       } else {
                /*
                 * A node already exists for "keyname" in "keytable".
                 */
                if (ds != NULL) {
-                       dns_keynode_t *knode = node->data;
-                       if (knode == NULL) {
-                               node->data = new_keynode(ds, keytable, managed,
-                                                        initial);
-                               if (callback != NULL) {
-                                       (*callback)(keyname, callback_arg);
-                               }
-                       } else {
-                               add_ds(knode, ds, keytable->mctx);
-                       }
+                       dns_keynode_t *knode = pval;
+                       add_ds(knode, ds, keytable->mctx);
                }
                result = ISC_R_SUCCESS;
        }
 
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
+       dns_qp_compact(qp, DNS_QPGC_MAYBE);
+       dns_qpmulti_commit(keytable->table, &qp);
 
        return (result);
 }
@@ -417,28 +407,23 @@ isc_result_t
 dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname,
                    dns_keytable_callback_t callback, void *callback_arg) {
        isc_result_t result;
-       dns_rbtnode_t *node = NULL;
+       dns_qp_t *qp = NULL;
+       void *pval = NULL;
 
        REQUIRE(VALID_KEYTABLE(keytable));
        REQUIRE(keyname != NULL);
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
-       result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
-                                 DNS_RBTFIND_NOOPTIONS, NULL, NULL);
+       dns_qpmulti_write(keytable->table, &qp);
+       result = dns_qp_deletename(qp, keyname, &pval, NULL);
        if (result == ISC_R_SUCCESS) {
-               if (node->data != NULL) {
-                       result = dns_rbt_deletenode(keytable->table, node,
-                                                   false);
-                       if (callback != NULL) {
-                               (*callback)(keyname, callback_arg);
-                       }
-               } else {
-                       result = ISC_R_NOTFOUND;
+               dns_keynode_t *n = pval;
+               if (callback != NULL) {
+                       (*callback)(keyname, callback_arg);
                }
-       } else if (result == DNS_R_PARTIALMATCH) {
-               result = ISC_R_NOTFOUND;
+               dns_keynode_detach(&n);
        }
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
+       dns_qp_compact(qp, DNS_QPGC_MAYBE);
+       dns_qpmulti_commit(keytable->table, &qp);
 
        return (result);
 }
@@ -447,33 +432,24 @@ isc_result_t
 dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname,
                       dns_rdata_dnskey_t *dnskey) {
        isc_result_t result;
-       dns_rbtnode_t *node = NULL;
        dns_keynode_t *knode = NULL;
        dns_rdata_t rdata = DNS_RDATA_INIT;
        unsigned char data[4096], digest[DNS_DS_BUFFERSIZE];
        dns_rdata_ds_t ds;
        isc_buffer_t b;
+       dns_qp_t *qp = NULL;
+       void *pval = NULL;
 
        REQUIRE(VALID_KEYTABLE(keytable));
        REQUIRE(dnskey != NULL);
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
-       result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
-                                 DNS_RBTFIND_NOOPTIONS, NULL, NULL);
-
-       if (result == DNS_R_PARTIALMATCH) {
-               result = ISC_R_NOTFOUND;
-       }
+       dns_qpmulti_write(keytable->table, &qp);
+       result = dns_qp_getname(qp, keyname, &pval, NULL);
        if (result != ISC_R_SUCCESS) {
                goto finish;
        }
 
-       if (node->data == NULL) {
-               result = ISC_R_NOTFOUND;
-               goto finish;
-       }
-
-       knode = node->data;
+       knode = pval;
 
        RWLOCK(&knode->rwlock, isc_rwlocktype_read);
        if (knode->dslist == NULL) {
@@ -496,10 +472,12 @@ dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname,
                goto finish;
        }
 
-       result = delete_ds(keytable, node, &ds);
+       result = delete_ds(qp, keytable, knode, &ds);
 
 finish:
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
+       dns_qp_compact(qp, DNS_QPGC_MAYBE);
+       dns_qpmulti_commit(keytable->table, &qp);
+
        return (result);
 }
 
@@ -507,25 +485,20 @@ isc_result_t
 dns_keytable_find(dns_keytable_t *keytable, const dns_name_t *keyname,
                  dns_keynode_t **keynodep) {
        isc_result_t result;
-       dns_rbtnode_t *node = NULL;
+       dns_qpread_t qpr;
+       void *pval = NULL;
 
        REQUIRE(VALID_KEYTABLE(keytable));
        REQUIRE(keyname != NULL);
        REQUIRE(keynodep != NULL && *keynodep == NULL);
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-       result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
-                                 DNS_RBTFIND_NOOPTIONS, NULL, NULL);
+       dns_qpmulti_query(keytable->table, &qpr);
+       result = dns_qp_getname(&qpr, keyname, &pval, NULL);
        if (result == ISC_R_SUCCESS) {
-               if (node->data != NULL) {
-                       keynode_attach(node->data, keynodep);
-               } else {
-                       result = ISC_R_NOTFOUND;
-               }
-       } else if (result == DNS_R_PARTIALMATCH) {
-               result = ISC_R_NOTFOUND;
+               dns_keynode_t *knode = pval;
+               dns_keynode_attach(knode, keynodep);
        }
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
+       dns_qpread_destroy(keytable->table, &qpr);
 
        return (result);
 }
@@ -534,7 +507,9 @@ isc_result_t
 dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name,
                              dns_name_t *foundname) {
        isc_result_t result;
-       void *data;
+       dns_qpread_t qpr;
+       dns_keynode_t *keynode = NULL;
+       void *pval = NULL;
 
        /*
         * Search for the deepest match in 'keytable'.
@@ -544,37 +519,26 @@ dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name,
        REQUIRE(dns_name_isabsolute(name));
        REQUIRE(foundname != NULL);
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
-       data = NULL;
-       result = dns_rbt_findname(keytable->table, name, 0, foundname, &data);
+       dns_qpmulti_query(keytable->table, &qpr);
+       result = dns_qp_findname_ancestor(&qpr, name, 0, &pval, NULL);
+       keynode = pval;
 
        if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
+               dns_name_copy(keynode->name, foundname);
                result = ISC_R_SUCCESS;
        }
 
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
+       dns_qpread_destroy(keytable->table, &qpr);
        return (result);
 }
 
-void
-dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep) {
-       /*
-        * Give back a keynode found via dns_keytable_findkeynode().
-        */
-
-       REQUIRE(VALID_KEYTABLE(keytable));
-       REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
-
-       keynode_detach(keytable->mctx, keynodep);
-}
-
 isc_result_t
 dns_keytable_issecuredomain(dns_keytable_t *keytable, const dns_name_t *name,
                            dns_name_t *foundname, bool *wantdnssecp) {
        isc_result_t result;
-       dns_rbtnode_t *node = NULL;
+       dns_qpread_t qpr;
+       dns_keynode_t *keynode = NULL;
+       void *pval = NULL;
 
        /*
         * Is 'name' at or beneath a trusted key?
@@ -584,12 +548,13 @@ dns_keytable_issecuredomain(dns_keytable_t *keytable, const dns_name_t *name,
        REQUIRE(dns_name_isabsolute(name));
        REQUIRE(wantdnssecp != NULL);
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
-       result = dns_rbt_findnode(keytable->table, name, foundname, &node, NULL,
-                                 DNS_RBTFIND_NOOPTIONS, NULL, NULL);
+       dns_qpmulti_query(keytable->table, &qpr);
+       result = dns_qp_findname_ancestor(&qpr, name, 0, &pval, NULL);
        if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
-               INSIST(node->data != NULL);
+               keynode = pval;
+               if (foundname != NULL) {
+                       dns_name_copy(keynode->name, foundname);
+               }
                *wantdnssecp = true;
                result = ISC_R_SUCCESS;
        } else if (result == ISC_R_NOTFOUND) {
@@ -597,7 +562,7 @@ dns_keytable_issecuredomain(dns_keytable_t *keytable, const dns_name_t *name,
                result = ISC_R_SUCCESS;
        }
 
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
+       dns_qpread_destroy(keytable->table, &qpr);
 
        return (result);
 }
@@ -644,20 +609,19 @@ dns_keytable_dump(dns_keytable_t *keytable, FILE *fp) {
 }
 
 static isc_result_t
-keynode_dslist_totext(dns_name_t *name, dns_keynode_t *keynode,
-                     isc_buffer_t **text) {
+keynode_dslist_totext(dns_keynode_t *keynode, isc_buffer_t **text) {
        isc_result_t result;
        char namebuf[DNS_NAME_FORMATSIZE];
        char obuf[DNS_NAME_FORMATSIZE + 200];
        dns_rdataset_t dsset;
 
-       dns_name_format(name, namebuf, sizeof(namebuf));
-
        dns_rdataset_init(&dsset);
        if (!dns_keynode_dsset(keynode, &dsset)) {
                return (ISC_R_SUCCESS);
        }
 
+       dns_name_format(keynode->name, namebuf, sizeof(namebuf));
+
        for (result = dns_rdataset_first(&dsset); result == ISC_R_SUCCESS;
             result = dns_rdataset_next(&dsset))
        {
@@ -691,114 +655,57 @@ keynode_dslist_totext(dns_name_t *name, dns_keynode_t *keynode,
 
 isc_result_t
 dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
-       isc_result_t result;
-       dns_keynode_t *knode;
-       dns_rbtnode_t *node;
-       dns_rbtnodechain_t chain;
-       dns_name_t *foundname, *origin, *fullname;
-       dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname;
+       isc_result_t result = ISC_R_SUCCESS;
+       dns_qpread_t qpr;
+       dns_qpiter_t iter;
+       void *pval = NULL;
 
        REQUIRE(VALID_KEYTABLE(keytable));
        REQUIRE(text != NULL && *text != NULL);
 
-       origin = dns_fixedname_initname(&fixedorigin);
-       fullname = dns_fixedname_initname(&fixedfullname);
-       foundname = dns_fixedname_initname(&fixedfoundname);
+       dns_qpmulti_query(keytable->table, &qpr);
+       dns_qpiter_init(&qpr, &iter);
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-       dns_rbtnodechain_init(&chain);
-       result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
-       if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-               if (result == ISC_R_NOTFOUND) {
-                       result = ISC_R_SUCCESS;
-               }
-               goto cleanup;
-       }
-       for (;;) {
-               dns_rbtnodechain_current(&chain, foundname, origin, &node);
-
-               knode = node->data;
-               if (knode != NULL && knode->dslist != NULL) {
-                       result = dns_name_concatenate(foundname, origin,
-                                                     fullname, NULL);
-                       if (result != ISC_R_SUCCESS) {
-                               goto cleanup;
-                       }
-
-                       result = keynode_dslist_totext(fullname, knode, text);
+       while (dns_qpiter_next(&iter, &pval, NULL) == ISC_R_SUCCESS) {
+               dns_keynode_t *knode = pval;
+               if (knode->dslist != NULL) {
+                       result = keynode_dslist_totext(knode, text);
                        if (result != ISC_R_SUCCESS) {
-                               goto cleanup;
+                               break;
                        }
                }
-
-               result = dns_rbtnodechain_next(&chain, NULL, NULL);
-               if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-                       if (result == ISC_R_NOMORE) {
-                               result = ISC_R_SUCCESS;
-                       }
-                       break;
-               }
        }
 
-cleanup:
-       dns_rbtnodechain_invalidate(&chain);
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
+       dns_qpread_destroy(keytable->table, &qpr);
        return (result);
 }
 
-isc_result_t
+void
 dns_keytable_forall(dns_keytable_t *keytable,
                    void (*func)(dns_keytable_t *, dns_keynode_t *,
                                 dns_name_t *, void *),
                    void *arg) {
-       isc_result_t result;
-       dns_rbtnode_t *node;
-       dns_rbtnodechain_t chain;
-       dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname;
-       dns_name_t *foundname, *origin, *fullname;
+       dns_qpread_t qpr;
+       dns_qpiter_t iter;
+       void *pval = NULL;
 
        REQUIRE(VALID_KEYTABLE(keytable));
 
-       origin = dns_fixedname_initname(&fixedorigin);
-       fullname = dns_fixedname_initname(&fixedfullname);
-       foundname = dns_fixedname_initname(&fixedfoundname);
+       dns_qpmulti_query(keytable->table, &qpr);
+       dns_qpiter_init(&qpr, &iter);
 
-       RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-       dns_rbtnodechain_init(&chain);
-       result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
-       if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-               if (result == ISC_R_NOTFOUND) {
-                       result = ISC_R_SUCCESS;
-               }
-               goto cleanup;
+       while (dns_qpiter_next(&iter, &pval, NULL) == ISC_R_SUCCESS) {
+               dns_keynode_t *knode = pval;
+               (*func)(keytable, knode, knode->name, arg);
        }
 
-       for (;;) {
-               dns_rbtnodechain_current(&chain, foundname, origin, &node);
-               if (node->data != NULL) {
-                       result = dns_name_concatenate(foundname, origin,
-                                                     fullname, NULL);
-                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
-                       (*func)(keytable, node->data, fullname, arg);
-               }
-               result = dns_rbtnodechain_next(&chain, NULL, NULL);
-               if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-                       if (result == ISC_R_NOMORE) {
-                               result = ISC_R_SUCCESS;
-                       }
-                       break;
-               }
-       }
-
-cleanup:
-       dns_rbtnodechain_invalidate(&chain);
-       RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
-       return (result);
+       dns_qpread_destroy(keytable->table, &qpr);
 }
 
 bool
 dns_keynode_dsset(dns_keynode_t *keynode, dns_rdataset_t *rdataset) {
        bool result;
+
        REQUIRE(VALID_KEYNODE(keynode));
        REQUIRE(rdataset == NULL || DNS_RDATASET_VALID(rdataset));
 
@@ -853,18 +760,18 @@ dns_keynode_trust(dns_keynode_t *keynode) {
 
 static void
 keynode_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG) {
-       dns_keynode_t *keynode;
+       dns_keynode_t *keynode = NULL;
 
        rdataset->methods = NULL;
        keynode = rdataset->keytable.node;
        rdataset->keytable.node = NULL;
 
-       keynode_detach(keynode->mctx, &keynode);
+       dns_keynode_detach(&keynode);
 }
 
 static isc_result_t
 keynode_first(dns_rdataset_t *rdataset) {
-       dns_keynode_t *keynode;
+       dns_keynode_t *keynode = NULL;
 
        keynode = rdataset->keytable.node;
        RWLOCK(&keynode->rwlock, isc_rwlocktype_read);
@@ -880,8 +787,8 @@ keynode_first(dns_rdataset_t *rdataset) {
 
 static isc_result_t
 keynode_next(dns_rdataset_t *rdataset) {
-       dns_keynode_t *keynode;
-       dns_rdata_t *rdata;
+       dns_keynode_t *keynode = NULL;
+       dns_rdata_t *rdata = NULL;
 
        rdata = rdataset->keytable.iter;
        if (rdata == NULL) {
@@ -902,7 +809,7 @@ keynode_next(dns_rdataset_t *rdataset) {
 
 static void
 keynode_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
-       dns_rdata_t *list_rdata;
+       dns_rdata_t *list_rdata = NULL;
 
        list_rdata = rdataset->keytable.iter;
        INSIST(list_rdata != NULL);
@@ -912,11 +819,38 @@ keynode_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
 
 static void
 keynode_clone(dns_rdataset_t *source, dns_rdataset_t *target DNS__DB_FLARG) {
-       dns_keynode_t *keynode;
+       dns_keynode_t *keynode = NULL;
 
        keynode = source->keytable.node;
-       isc_refcount_increment(&keynode->refcount);
+       isc_refcount_increment(&keynode->references);
 
        *target = *source;
        target->keytable.iter = NULL;
 }
+
+static void
+qp_attach(void *uctx ISC_ATTR_UNUSED, void *pval,
+         uint32_t ival ISC_ATTR_UNUSED) {
+       dns_keynode_t *keynode = pval;
+       dns_keynode_ref(keynode);
+}
+
+static void
+qp_detach(void *uctx ISC_ATTR_UNUSED, void *pval,
+         uint32_t ival ISC_ATTR_UNUSED) {
+       dns_keynode_t *keynode = pval;
+       dns_keynode_detach(&keynode);
+}
+
+static size_t
+qp_makekey(dns_qpkey_t key, void *uctx ISC_ATTR_UNUSED, void *pval,
+          uint32_t ival ISC_ATTR_UNUSED) {
+       dns_keynode_t *keynode = pval;
+       return (dns_qpkey_fromname(key, keynode->name));
+}
+
+static void
+qp_triename(void *uctx, char *buf, size_t size) {
+       dns_view_t *view = uctx;
+       snprintf(buf, size, "view %s secroots table", view->name);
+}
index 0887c07ad973af370f66e847491f539594bc3096..3b9c8fc5db43716361361a6d45eb987fd0dd1cf9 100644 (file)
@@ -1715,7 +1715,7 @@ validate_dnskey(dns_validator_t *val) {
                        if (dns_keynode_dsset(keynode, &val->fdsset)) {
                                val->dsset = &val->fdsset;
                        }
-                       dns_keytable_detachkeynode(val->keytable, &keynode);
+                       dns_keynode_detach(&keynode);
                }
        }
 
index 1b307dd8d7180f02da575708d145b9d61fdde931..8f08e108d7efee914c36effd54ca2783614c73bc 100644 (file)
@@ -1574,13 +1574,13 @@ dns_view_getntatable(dns_view_t *view, dns_ntatable_t **ntp) {
        return (ISC_R_SUCCESS);
 }
 
-isc_result_t
-dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) {
+void
+dns_view_initsecroots(dns_view_t *view) {
        REQUIRE(DNS_VIEW_VALID(view));
        if (view->secroots_priv != NULL) {
                dns_keytable_detach(&view->secroots_priv);
        }
-       return (dns_keytable_create(mctx, &view->secroots_priv));
+       dns_keytable_create(view, &view->secroots_priv);
 }
 
 isc_result_t
@@ -1759,7 +1759,7 @@ finish:
                dns_rdataset_disassociate(&dsset);
        }
        if (knode != NULL) {
-               dns_keytable_detachkeynode(sr, &knode);
+               dns_keynode_detach(&knode);
        }
        dns_keytable_detach(&sr);
        return (answer);
index a99817294d81525e9401ea66676f334e71f280cf..2ecc27557cb9f431f9dd7f260b3698375023af93 100644 (file)
@@ -4594,7 +4594,7 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
                }
 
                if (keynode != NULL) {
-                       dns_keytable_detachkeynode(sr, &keynode);
+                       dns_keynode_detach(&keynode);
                }
        }
        dns_rriterator_destroy(&rrit);
@@ -4632,7 +4632,7 @@ failure:
                isc_time_settoepoch(&zone->refreshkeytime);
        }
        if (keynode != NULL) {
-               dns_keytable_detachkeynode(sr, &keynode);
+               dns_keynode_detach(&keynode);
        }
        if (sr != NULL) {
                dns_keytable_detach(&sr);
@@ -10035,7 +10035,7 @@ keyfetch_done(void *arg) {
 
 anchors_done:
        if (keynode != NULL) {
-               dns_keytable_detachkeynode(secroots, &keynode);
+               dns_keynode_detach(&keynode);
        }
 
        /*
index 7709ed8d8aeb46934a489bcfb046337e4f18f92c..f2ff9ad38bff7be58955a1f3f1f5b8fe50a02989 100644 (file)
@@ -1554,7 +1554,7 @@ check_dnskey_sigs(vctx_t *vctx, const dns_rdata_dnskey_t *dnskey,
 
 cleanup:
        if (keynode != NULL) {
-               dns_keytable_detachkeynode(vctx->secroots, &keynode);
+               dns_keynode_detach(&keynode);
        }
        if (key != NULL) {
                dst_key_free(&key);
index 1212ed16e173c9a8ad13df15a99dc082fe34cde5..e2e00b28c669495686c9e7bd629e4496f8ade920 100644 (file)
@@ -7513,7 +7513,7 @@ has_ta(query_ctx_t *qctx) {
        result = dns_keytable_find(keytable, dns_rootname, &keynode);
        if (result != ISC_R_SUCCESS) {
                if (keynode != NULL) {
-                       dns_keytable_detachkeynode(keytable, &keynode);
+                       dns_keynode_detach(&keynode);
                }
                dns_keytable_detach(&keytable);
                return (false);
@@ -7533,7 +7533,7 @@ has_ta(query_ctx_t *qctx) {
                        result = dns_rdata_tostruct(&rdata, &ds, NULL);
                        RUNTIME_CHECK(result == ISC_R_SUCCESS);
                        if (ds.key_tag == sentinel) {
-                               dns_keytable_detachkeynode(keytable, &keynode);
+                               dns_keynode_detach(&keynode);
                                dns_keytable_detach(&keytable);
                                dns_rdataset_disassociate(&dsset);
                                return (true);
@@ -7543,7 +7543,7 @@ has_ta(query_ctx_t *qctx) {
        }
 
        if (keynode != NULL) {
-               dns_keytable_detachkeynode(keytable, &keynode);
+               dns_keynode_detach(&keynode);
        }
 
        dns_keytable_detach(&keytable);
index 93e13e6cc3bf1b5836df043b356bff4723793bbb..f3657c6649b0a171c85d72b3923414ffa966b2a3 100644 (file)
@@ -173,7 +173,7 @@ create_tables(void) {
        assert_int_equal(dns_test_makeview("view", false, &view),
                         ISC_R_SUCCESS);
 
-       assert_int_equal(dns_keytable_create(mctx, &keytable), ISC_R_SUCCESS);
+       dns_keytable_create(view, &keytable);
        dns_ntatable_create(view, loopmgr, &ntatable);
 
        /* Add a normal key */
@@ -244,13 +244,13 @@ ISC_LOOP_TEST_IMPL(add) {
        assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
                                          NULL, NULL),
                         ISC_R_SUCCESS);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("example.com"), &keynode),
                ISC_R_SUCCESS);
 
        /* Add another key (different keydata) */
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
        create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
        assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
                                          NULL, NULL),
@@ -258,7 +258,7 @@ ISC_LOOP_TEST_IMPL(add) {
        assert_int_equal(
                dns_keytable_find(keytable, str2name("example.com"), &keynode),
                ISC_R_SUCCESS);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
 
        /*
         * Get the keynode for the managed.com key. Ensure the
@@ -271,7 +271,7 @@ ISC_LOOP_TEST_IMPL(add) {
        assert_int_equal(dns_keynode_initial(keynode), true);
        dns_keynode_trust(keynode);
        assert_int_equal(dns_keynode_initial(keynode), false);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
 
        /*
         * Add a different managed key for managed.com, marking it as an
@@ -287,7 +287,7 @@ ISC_LOOP_TEST_IMPL(add) {
                dns_keytable_find(keytable, str2name("managed.com"), &keynode),
                ISC_R_SUCCESS);
        assert_int_equal(dns_keynode_initial(keynode), false);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
 
        /*
         * Add the same managed key again, but this time mark it as a
@@ -302,7 +302,7 @@ ISC_LOOP_TEST_IMPL(add) {
                dns_keytable_find(keytable, str2name("managed.com"), &keynode),
                ISC_R_SUCCESS);
        assert_int_equal(dns_keynode_initial(keynode), false);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
 
        /*
         * Add a managed key at a new node, two.com, marking it as an
@@ -317,7 +317,7 @@ ISC_LOOP_TEST_IMPL(add) {
                dns_keytable_find(keytable, str2name("two.com"), &keynode),
                ISC_R_SUCCESS);
        assert_int_equal(dns_keynode_initial(keynode), true);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
 
        /*
         * Add a different managed key for two.com, marking it as a
@@ -333,7 +333,7 @@ ISC_LOOP_TEST_IMPL(add) {
                dns_keytable_find(keytable, str2name("two.com"), &keynode),
                ISC_R_SUCCESS);
        assert_int_equal(dns_keynode_initial(keynode), true);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
 
        /*
         * Add a normal key to a name that has a null key.  The null key node
@@ -351,7 +351,7 @@ ISC_LOOP_TEST_IMPL(add) {
                dns_keytable_find(keytable, str2name("null.example"), &keynode),
                ISC_R_SUCCESS);
        assert_ptr_equal(keynode, null_keynode); /* should be the same node */
-       dns_keytable_detachkeynode(keytable, &null_keynode);
+       dns_keynode_detach(&null_keynode);
 
        /*
         * Try to add a null key to a name that already has a key.  It's
@@ -366,9 +366,9 @@ ISC_LOOP_TEST_IMPL(add) {
                                           &null_keynode),
                         ISC_R_SUCCESS);
        assert_ptr_equal(keynode, null_keynode);
-       dns_keytable_detachkeynode(keytable, &null_keynode);
+       dns_keynode_detach(&null_keynode);
 
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
        destroy_tables();
 
        isc_loopmgr_shutdown(loopmgr);
@@ -500,11 +500,11 @@ ISC_LOOP_TEST_IMPL(find) {
        assert_int_equal(
                dns_keytable_find(keytable, str2name("example.com"), &keynode),
                ISC_R_SUCCESS);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("null.example"), &keynode),
                ISC_R_SUCCESS);
-       dns_keytable_detachkeynode(keytable, &keynode);
+       dns_keynode_detach(&keynode);
 
        /*
         * dns_keytable_finddeepestmatch() allows partial match.  Also match
@@ -605,8 +605,8 @@ ISC_LOOP_TEST_IMPL(nta) {
        result = dns_test_makeview("view", false, &myview);
        assert_int_equal(result, ISC_R_SUCCESS);
 
-       result = dns_view_initsecroots(myview, mctx);
-       assert_int_equal(result, ISC_R_SUCCESS);
+       dns_view_initsecroots(myview);
+
        result = dns_view_getsecroots(myview, &keytable);
        assert_int_equal(result, ISC_R_SUCCESS);