]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
convert TSIG keyring storage from RBT to hash table
authorEvan Hunt <each@isc.org>
Wed, 12 Apr 2023 07:14:04 +0000 (00:14 -0700)
committerEvan Hunt <each@isc.org>
Wed, 14 Jun 2023 08:14:38 +0000 (08:14 +0000)
since it is not necessary to find partial matches when looking
up names in a TSIG keyring, we can use a hash table instead of
an RBT to store them.

the tsigkey object now stores the key name as a dns_fixedname
rather than allocating memory for it.

the `name` parameter to dns_tsigkeyring_add() has been removed;
it was unneeded since the tsigkey object already contains a copy
of the name.

the opportunistic cleanup_ring() function has been removed;
it was only slowing down lookups.

15 files changed:
bin/named/server.c
bin/named/tsigconf.c
bin/named/zoneconf.c
bin/nsupdate/nsupdate.c
fuzz/dns_message_checksig.c
lib/dns/include/dns/tsig.h
lib/dns/message.c
lib/dns/tkey.c
lib/dns/tsig.c
lib/dns/view.c
lib/dns/zone.c
lib/ns/client.c
lib/ns/notify.c
lib/ns/xfrout.c
tests/dns/tsig_test.c

index ea45def9d44904270b6e9473af9d84cd551886c8..a4dc7215fb6f0bf57cc1fc7b1dc97ed47fde1479 100644 (file)
@@ -5049,8 +5049,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                        named_g_server->sessionkey, false, false, NULL, 0, 0,
                        mctx, &tsigkey);
                if (result == ISC_R_SUCCESS) {
-                       result = dns_tsigkeyring_add(
-                               ring, named_g_server->session_keyname, tsigkey);
+                       result = dns_tsigkeyring_add(ring, tsigkey);
                        dns_tsigkey_detach(&tsigkey);
                }
                CHECK(result);
index a1ed24ef9388f7822c5192b2f105df78313bbc50..dfeadfd99f41a6a648dbdd1f4c76987b2788f37e 100644 (file)
@@ -108,7 +108,7 @@ add_initial_keys(const cfg_obj_t *list, dns_tsigkeyring_t *ring,
                isc_mem_put(mctx, secret, secretalloc);
                secret = NULL;
                if (ret == ISC_R_SUCCESS) {
-                       ret = dns_tsigkeyring_add(ring, &keyname, tsigkey);
+                       ret = dns_tsigkeyring_add(ring, tsigkey);
                }
                if (ret != ISC_R_SUCCESS) {
                        if (tsigkey != NULL) {
@@ -154,10 +154,7 @@ named_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
        }
        maps[i] = NULL;
 
-       result = dns_tsigkeyring_create(mctx, &ring);
-       if (result != ISC_R_SUCCESS) {
-               return (result);
-       }
+       dns_tsigkeyring_create(mctx, &ring);
 
        for (i = 0;; i++) {
                if (maps[i] == NULL) {
index 8b1cd97f8d39a4a7ed2b3404af76a782ce45c095..867be2369c71f1e038a4ae48c690eefe31446cc5 100644 (file)
@@ -809,7 +809,7 @@ isself(dns_view_t *myview, dns_tsigkey_t *mykey, const isc_sockaddr_t *srcaddr,
                        bool match;
                        isc_result_t result;
 
-                       result = dns_view_gettsig(view, &mykey->name, &key);
+                       result = dns_view_gettsig(view, mykey->name, &key);
                        if (result != ISC_R_SUCCESS) {
                                continue;
                        }
index eaf74b39a4f990b9607d82a0a68b3cc2a973afc1..f733682c16682e1a75eadecc74f44da0087202b0 100644 (file)
@@ -3028,11 +3028,7 @@ start_gssrequest(dns_name_t *primary) {
                dns_tsigkeyring_detach(&gssring);
        }
 
-       result = dns_tsigkeyring_create(gmctx, &gssring);
-       if (result != ISC_R_SUCCESS) {
-               fatal("dns_tsigkeyring_create failed: %s",
-                     isc_result_totext(result));
-       }
+       dns_tsigkeyring_create(gmctx, &gssring);
 
        dns_name_format(primary, namestr, sizeof(namestr));
        if (kserver == NULL) {
index 1f4417eb7728c04667bbc9fecf4ec0233a1f4d73..15a61995e166dc215be55bbcfe325a3626703e65 100644 (file)
@@ -243,19 +243,8 @@ LLVMFuzzerInitialize(int *argc ISC_ATTR_UNUSED, char ***argv ISC_ATTR_UNUSED) {
                return (1);
        }
 
-       result = dns_tsigkeyring_create(mctx, &ring);
-       if (result != ISC_R_SUCCESS) {
-               fprintf(stderr, "dns_tsigkeyring_create failed: %s\n",
-                       isc_result_totext(result));
-               return (1);
-       }
-
-       result = dns_tsigkeyring_create(mctx, &emptyring);
-       if (result != ISC_R_SUCCESS) {
-               fprintf(stderr, "dns_tsigkeyring_create failed: %s\n",
-                       isc_result_totext(result));
-               return (1);
-       }
+       dns_tsigkeyring_create(mctx, &ring);
+       dns_tsigkeyring_create(mctx, &emptyring);
 
        result = dns_name_fromstring(name, "tsig-key", 0, NULL);
        if (result != ISC_R_SUCCESS) {
@@ -271,7 +260,7 @@ LLVMFuzzerInitialize(int *argc ISC_ATTR_UNUSED, char ***argv ISC_ATTR_UNUSED) {
                        isc_result_totext(result));
                return (1);
        }
-       result = dns_tsigkeyring_add(ring, name, tsigkey);
+       result = dns_tsigkeyring_add(ring, tsigkey);
        if (result != ISC_R_SUCCESS) {
                fprintf(stderr, "dns_tsigkeyring_add failed: %s\n",
                        isc_result_totext(result));
index c975c236ed3ad675e0da5c73b75030ee9d3fa565..c4bf46a6225573d3c7d355f9c94bb3cd0eced407 100644 (file)
 
 #include <stdbool.h>
 
+#include <isc/hashmap.h>
 #include <isc/lang.h>
 #include <isc/refcount.h>
 #include <isc/rwlock.h>
 #include <isc/stdio.h>
 #include <isc/stdtime.h>
 
+#include <dns/fixedname.h>
 #include <dns/name.h>
 #include <dns/types.h>
 
@@ -62,11 +64,11 @@ extern const dns_name_t *dns_tsig_hmacsha512_name;
 #endif /* ifndef DNS_TSIG_MAXGENERATEDKEYS */
 
 struct dns_tsigkeyring {
-       unsigned int magic; /*%< Magic number. */
-       dns_rbt_t   *keys;
-       unsigned int writecount;
-       isc_rwlock_t lock;
-       isc_mem_t   *mctx;
+       unsigned int   magic; /*%< Magic number. */
+       isc_hashmap_t *keys;
+       unsigned int   writecount;
+       isc_rwlock_t   lock;
+       isc_mem_t     *mctx;
        /*
         * LRU list of generated key along with a count of the keys on the
         * list and a maximum size.
@@ -80,8 +82,9 @@ struct dns_tsigkey {
        /* Unlocked */
        unsigned int       magic; /*%< Magic number. */
        isc_mem_t         *mctx;
-       dst_key_t         *key;           /*%< Key */
-       dns_name_t         name;          /*%< Key name */
+       dst_key_t         *key; /*%< Key */
+       dns_fixedname_t    fn;
+       dns_name_t        *name;          /*%< Key name */
        const dns_name_t  *algorithm;     /*%< Algorithm name */
        dns_name_t        *creator;       /*%< name that created secret */
        bool               generated : 1; /*%< key was auto-generated */
@@ -238,7 +241,7 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkeyp, const dns_name_t *name,
  *\li          #ISC_R_NOTFOUND
  */
 
-isc_result_t
+void
 dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsigkeyring_t **ringp);
 /*%<
  *     Create an empty TSIG key ring.
@@ -246,15 +249,10 @@ dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsigkeyring_t **ringp);
  *     Requires:
  *\li          'mctx' is not NULL
  *\li          'ringp' is not NULL, and '*ringp' is NULL
- *
- *     Returns:
- *\li          #ISC_R_SUCCESS
- *\li          #ISC_R_NOMEMORY
  */
 
 isc_result_t
-dns_tsigkeyring_add(dns_tsigkeyring_t *ring, const dns_name_t *name,
-                   dns_tsigkey_t *tkey);
+dns_tsigkeyring_add(dns_tsigkeyring_t *ring, dns_tsigkey_t *tkey);
 /*%<
  *      Place a TSIG key onto a key ring.
  *
index 120e3680e9cb5fee08b00a13f8ed0f9e7f603b8a..a86724a07453a1bb68f42bd36294fe09c5f5e46f 100644 (file)
@@ -689,7 +689,7 @@ spacefortsig(dns_tsigkey_t *key, int otherlen) {
         *     26 + n1 + n2 + x + y bytes
         */
 
-       dns_name_toregion(&key->name, &r1);
+       dns_name_toregion(key->name, &r1);
        dns_name_toregion(key->algorithm, &r2);
        if (key->key == NULL) {
                x = 0;
@@ -3074,7 +3074,7 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) {
                                if (result == ISC_R_SUCCESS) {
                                        result = DNS_R_NOIDENTITY;
                                }
-                               identity = &msg->tsigkey->name;
+                               identity = msg->tsigkey->name;
                        }
                        dns_name_clone(identity, signer);
                }
index 1ec1898e7a70105f5e32cda02377cf54f7cd6207..83eafa71ff8a39e1e6949d1445a697f00c15b231 100644 (file)
@@ -268,7 +268,7 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin,
                        name, dns__tsig_algfromname(&tkeyin->algorithm), dstkey,
                        true, false, principal, now, expire, ring->mctx,
                        &tsigkey));
-               RETERR(dns_tsigkeyring_add(ring, name, tsigkey));
+               RETERR(dns_tsigkeyring_add(ring, tsigkey));
                dst_key_free(&dstkey);
                tkeyout->inception = now;
                tkeyout->expire = expire;
@@ -819,7 +819,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
        RETERR(dns_tsigkey_createfromkey(tkeyname, DST_ALG_GSSAPI, dstkey, true,
                                         false, NULL, rtkey.inception,
                                         rtkey.expire, ring->mctx, &tsigkey));
-       RETERR(dns_tsigkeyring_add(ring, tkeyname, tsigkey));
+       RETERR(dns_tsigkeyring_add(ring, tsigkey));
        if (outkey == NULL) {
                dns_tsigkey_detach(&tsigkey);
        } else {
index c75caff365b57e2bf51fcf988c451929511c187e..01e22a45c4006e90f40bbf1fb4a245c87dc2bcec 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 
 #include <isc/buffer.h>
+#include <isc/hashmap.h>
 #include <isc/mem.h>
 #include <isc/refcount.h>
 #include <isc/result.h>
@@ -30,7 +31,6 @@
 #include <dns/keyvalues.h>
 #include <dns/log.h>
 #include <dns/message.h>
-#include <dns/rbt.h>
 #include <dns/rdata.h>
 #include <dns/rdatalist.h>
 #include <dns/rdataset.h>
@@ -110,9 +110,6 @@ static void
 tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...)
        ISC_FORMAT_PRINTF(3, 4);
 
-static void
-cleanup_ring(dns_tsigkeyring_t *ring);
-
 bool
 dns__tsig_algvalid(unsigned int alg) {
        return (alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 ||
@@ -131,7 +128,7 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
                return;
        }
        if (key != NULL) {
-               dns_name_format(&key->name, namestr, sizeof(namestr));
+               dns_name_format(key->name, namestr, sizeof(namestr));
        } else {
                strlcpy(namestr, "<null>", sizeof(namestr));
        }
@@ -158,7 +155,17 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
 }
 
 static void
-remove_fromring(dns_tsigkey_t *tkey) {
+rm_hashmap(dns_tsigkey_t *tkey) {
+       REQUIRE(VALID_TSIGKEY(tkey));
+       REQUIRE(VALID_TSIGKEYRING(tkey->ring));
+
+       (void)isc_hashmap_delete(tkey->ring->keys, NULL, tkey->name->ndata,
+                                tkey->name->length);
+       dns_tsigkey_detach(&tkey);
+}
+
+static void
+rm_lru(dns_tsigkey_t *tkey) {
        REQUIRE(VALID_TSIGKEY(tkey));
        REQUIRE(VALID_TSIGKEYRING(tkey->ring));
 
@@ -167,7 +174,6 @@ remove_fromring(dns_tsigkey_t *tkey) {
                tkey->ring->generated--;
                dns_tsigkey_unref(tkey);
        }
-       (void)dns_rbt_deletename(tkey->ring->keys, &tkey->name, false);
 }
 
 static void
@@ -228,12 +234,12 @@ dns_tsigkey_createfromkey(const dns_name_t *name, dst_algorithm_t algorithm,
                .restored = restored,
                .inception = inception,
                .expire = expire,
-               .name = DNS_NAME_INITEMPTY,
                .link = ISC_LINK_INITIALIZER,
        };
 
-       dns_name_dup(name, mctx, &tkey->name);
-       (void)dns_name_downcase(&tkey->name, &tkey->name, NULL);
+       tkey->name = dns_fixedname_initname(&tkey->fn);
+       dns_name_copy(name, tkey->name);
+       (void)dns_name_downcase(tkey->name, tkey->name, NULL);
 
        if (algorithm != DST_ALG_UNKNOWN) {
                if (dstkey != NULL && dst_key_alg(dstkey) != algorithm) {
@@ -290,70 +296,33 @@ dns_tsigkey_createfromkey(const dns_name_t *name, dst_algorithm_t algorithm,
        return (ISC_R_SUCCESS);
 
 cleanup_name:
-       dns_name_free(&tkey->name, mctx);
        isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t));
 
        return (ret);
 }
 
-/*
- * Find a few nodes to destroy if possible.
- */
 static void
-cleanup_ring(dns_tsigkeyring_t *ring) {
+destroyring(dns_tsigkeyring_t *ring) {
        isc_result_t result;
-       dns_rbtnodechain_t chain;
-       dns_name_t foundname;
-       dns_fixedname_t fixedorigin;
-       dns_name_t *origin = NULL;
-       isc_stdtime_t now = isc_stdtime_now();
+       isc_hashmap_iter_t *it = NULL;
 
-       /*
-        * Start up a new iterator each time.
-        */
-       dns_name_init(&foundname, NULL);
-       origin = dns_fixedname_initname(&fixedorigin);
-
-again:
-       dns_rbtnodechain_init(&chain);
-       result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin);
-       if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-               dns_rbtnodechain_invalidate(&chain);
-               return;
-       }
-
-       for (;;) {
-               dns_rbtnode_t *node = NULL;
+       RWLOCK(&ring->lock, isc_rwlocktype_write);
+       isc_hashmap_iter_create(ring->keys, &it);
+       for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS;
+            result = isc_hashmap_iter_delcurrent_next(it))
+       {
                dns_tsigkey_t *tkey = NULL;
-
-               dns_rbtnodechain_current(&chain, &foundname, origin, &node);
-               tkey = node->data;
-               if (tkey != NULL) {
-                       if (tkey->generated &&
-                           isc_refcount_current(&tkey->references) == 1 &&
-                           tkey->inception != tkey->expire &&
-                           tkey->expire < now)
-                       {
-                               tsig_log(tkey, 2, "tsig expire: deleting");
-                               /* delete the key */
-                               dns_rbtnodechain_invalidate(&chain);
-                               remove_fromring(tkey);
-                               goto again;
-                       }
-               }
-               result = dns_rbtnodechain_next(&chain, &foundname, origin);
-               if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-                       dns_rbtnodechain_invalidate(&chain);
-                       return;
-               }
+               isc_hashmap_iter_current(it, (void **)&tkey);
+               rm_lru(tkey);
+               dns_tsigkey_detach(&tkey);
        }
-}
+       isc_hashmap_iter_destroy(&it);
+       isc_hashmap_destroy(&ring->keys);
+       RWUNLOCK(&ring->lock, isc_rwlocktype_write);
 
-static void
-destroyring(dns_tsigkeyring_t *ring) {
        ring->magic = 0;
+
        isc_refcount_destroy(&ring->references);
-       dns_rbt_destroy(&ring->keys);
        isc_rwlock_destroy(&ring->lock);
        isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsigkeyring_t));
 }
@@ -447,7 +416,7 @@ restore_key(dns_tsigkeyring_t *ring, isc_stdtime_t now, FILE *fp) {
                                           creator, inception, expire,
                                           ring->mctx, &tkey);
        if (result == ISC_R_SUCCESS) {
-               result = dns_tsigkeyring_add(ring, name, tkey);
+               result = dns_tsigkeyring_add(ring, tkey);
        }
        dns_tsigkey_detach(&tkey);
        if (dstkey != NULL) {
@@ -468,7 +437,7 @@ dump_key(dns_tsigkey_t *tkey, FILE *fp) {
        REQUIRE(tkey != NULL);
        REQUIRE(fp != NULL);
 
-       dns_name_format(&tkey->name, namestr, sizeof(namestr));
+       dns_name_format(tkey->name, namestr, sizeof(namestr));
        dns_name_format(tkey->creator, creatorstr, sizeof(creatorstr));
        dns_name_format(tkey->algorithm, algorithmstr, sizeof(algorithmstr));
        result = dst_key_dump(tkey->key, tkey->mctx, &buffer, &length);
@@ -485,44 +454,27 @@ dump_key(dns_tsigkey_t *tkey, FILE *fp) {
 isc_result_t
 dns_tsigkeyring_dump(dns_tsigkeyring_t *ring, FILE *fp) {
        isc_result_t result;
-       dns_rbtnodechain_t chain;
-       dns_name_t foundname;
-       dns_fixedname_t fixedorigin;
-       dns_name_t *origin = NULL;
        isc_stdtime_t now = isc_stdtime_now();
+       isc_hashmap_iter_t *it = NULL;
+       bool found = false;
 
        REQUIRE(VALID_TSIGKEYRING(ring));
 
-       dns_name_init(&foundname, NULL);
-       origin = dns_fixedname_initname(&fixedorigin);
-       dns_rbtnodechain_init(&chain);
-       result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin);
-       if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-               dns_rbtnodechain_invalidate(&chain);
-               goto destroy;
-       }
-
-       for (;;) {
-               dns_rbtnode_t *node = NULL;
+       isc_hashmap_iter_create(ring->keys, &it);
+       for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS;
+            result = isc_hashmap_iter_next(it))
+       {
                dns_tsigkey_t *tkey = NULL;
+               isc_hashmap_iter_current(it, (void **)&tkey);
 
-               dns_rbtnodechain_current(&chain, &foundname, origin, &node);
-               tkey = node->data;
-               if (tkey != NULL && tkey->generated && tkey->expire >= now) {
+               if (tkey->generated && tkey->expire >= now) {
                        dump_key(tkey, fp);
-               }
-               result = dns_rbtnodechain_next(&chain, &foundname, origin);
-               if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
-                       dns_rbtnodechain_invalidate(&chain);
-                       if (result == ISC_R_NOMORE) {
-                               result = ISC_R_SUCCESS;
-                       }
-                       goto destroy;
+                       found = true;
                }
        }
+       isc_hashmap_iter_destroy(&it);
 
-destroy:
-       return (result);
+       return (found ? ISC_R_SUCCESS : ISC_R_NOTFOUND);
 }
 
 const dns_name_t *
@@ -535,7 +487,7 @@ dns_tsigkey_identity(const dns_tsigkey_t *tsigkey) {
        if (tsigkey->generated) {
                return (tsigkey->creator);
        } else {
-               return (&tsigkey->name);
+               return (tsigkey->name);
        }
 }
 
@@ -582,7 +534,6 @@ destroy_tsigkey(dns_tsigkey_t *key) {
        REQUIRE(VALID_TSIGKEY(key));
 
        key->magic = 0;
-       dns_name_free(&key->name, key->mctx);
        if (key->key != NULL) {
                dst_key_free(&key->key);
        }
@@ -604,7 +555,8 @@ dns_tsigkey_delete(dns_tsigkey_t *key) {
        REQUIRE(VALID_TSIGKEY(key));
 
        RWLOCK(&key->ring->lock, isc_rwlocktype_write);
-       remove_fromring(key);
+       rm_lru(key);
+       rm_hashmap(key);
        RWUNLOCK(&key->ring->lock, isc_rwlocktype_write);
 }
 
@@ -756,7 +708,7 @@ dns_tsig_sign(dns_message_t *msg) {
                        /*
                         * Digest the name, class, ttl, alg.
                         */
-                       dns_name_toregion(&key->name, &r);
+                       dns_name_toregion(key->name, &r);
                        ret = dst_context_adddata(ctx, &r);
                        if (ret != ISC_R_SUCCESS) {
                                goto cleanup_context;
@@ -863,7 +815,7 @@ dns_tsig_sign(dns_message_t *msg) {
        }
 
        dns_message_gettempname(msg, &owner);
-       dns_name_copy(&key->name, owner);
+       dns_name_copy(key->name, owner);
 
        dns_message_gettemprdatalist(msg, &datalist);
 
@@ -982,7 +934,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
         * Do the key name and algorithm match that of the query?
         */
        if (response &&
-           (!dns_name_equal(keyname, &tsigkey->name) ||
+           (!dns_name_equal(keyname, tsigkey->name) ||
             !dns_name_equal(&tsig.algorithm, &querytsig.algorithm)))
        {
                msg->tsigstatus = dns_tsigerror_badkey;
@@ -1126,7 +1078,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
                /*
                 * Digest the key name.
                 */
-               dns_name_toregion(&tsigkey->name, &r);
+               dns_name_toregion(tsigkey->name, &r);
                ret = dst_context_adddata(ctx, &r);
                if (ret != ISC_R_SUCCESS) {
                        goto cleanup_context;
@@ -1322,7 +1274,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
                /*
                 * Do the key name and algorithm match that of the query?
                 */
-               if (!dns_name_equal(keyname, &tsigkey->name) ||
+               if (!dns_name_equal(keyname, tsigkey->name) ||
                    !dns_name_equal(&tsig.algorithm, &querytsig.algorithm))
                {
                        msg->tsigstatus = dns_tsigerror_badkey;
@@ -1583,15 +1535,12 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
        REQUIRE(VALID_TSIGKEYRING(ring));
        REQUIRE(tsigkey != NULL && *tsigkey == NULL);
 
-       RWLOCK(&ring->lock, isc_rwlocktype_write);
-       cleanup_ring(ring);
-       RWUNLOCK(&ring->lock, isc_rwlocktype_write);
-
        RWLOCK(&ring->lock, isc_rwlocktype_read);
-       result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key);
-       if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) {
+       result = isc_hashmap_find(ring->keys, NULL, name->ndata, name->length,
+                                 (void **)&key);
+       if (result == ISC_R_NOTFOUND) {
                RWUNLOCK(&ring->lock, isc_rwlocktype_read);
-               return (ISC_R_NOTFOUND);
+               return (result);
        }
        if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) {
                RWUNLOCK(&ring->lock, isc_rwlocktype_read);
@@ -1603,7 +1552,8 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
                 */
                RWUNLOCK(&ring->lock, isc_rwlocktype_read);
                RWLOCK(&ring->lock, isc_rwlocktype_write);
-               remove_fromring(key);
+               rm_lru(key);
+               rm_hashmap(key);
                RWUNLOCK(&ring->lock, isc_rwlocktype_write);
                return (ISC_R_NOTFOUND);
        }
@@ -1614,22 +1564,8 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
        return (ISC_R_SUCCESS);
 }
 
-static void
-free_tsignode(void *node, void *arg ISC_ATTR_UNUSED) {
-       dns_tsigkey_t *key = node;
-
-       REQUIRE(key != NULL);
-
-       if (key->ring != NULL && key->generated && ISC_LINK_LINKED(key, link)) {
-               ISC_LIST_UNLINK(key->ring->lru, key, link);
-               dns_tsigkey_unref(key);
-       }
-       dns_tsigkey_detach(&key);
-}
-
-isc_result_t
+void
 dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsigkeyring_t **ringp) {
-       isc_result_t result;
        dns_tsigkeyring_t *ring = NULL;
 
        REQUIRE(mctx != NULL);
@@ -1640,45 +1576,26 @@ dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsigkeyring_t **ringp) {
                .lru = ISC_LIST_INITIALIZER,
        };
 
-       result = dns_rbt_create(mctx, free_tsignode, NULL, &ring->keys);
-       if (result != ISC_R_SUCCESS) {
-               isc_rwlock_destroy(&ring->lock);
-               isc_mem_put(mctx, ring, sizeof(dns_tsigkeyring_t));
-               return (result);
-       }
-
+       isc_hashmap_create(mctx, 12, ISC_HASHMAP_CASE_INSENSITIVE, &ring->keys);
        isc_rwlock_init(&ring->lock);
        isc_mem_attach(mctx, &ring->mctx);
        isc_refcount_init(&ring->references, 1);
        ring->magic = TSIGKEYRING_MAGIC;
 
        *ringp = ring;
-       return (ISC_R_SUCCESS);
 }
 
 isc_result_t
-dns_tsigkeyring_add(dns_tsigkeyring_t *ring, const dns_name_t *name,
-                   dns_tsigkey_t *tkey) {
+dns_tsigkeyring_add(dns_tsigkeyring_t *ring, dns_tsigkey_t *tkey) {
        isc_result_t result;
 
        REQUIRE(VALID_TSIGKEY(tkey));
        REQUIRE(VALID_TSIGKEYRING(ring));
        REQUIRE(tkey->ring == NULL);
-       REQUIRE(name != NULL);
 
        RWLOCK(&ring->lock, isc_rwlocktype_write);
-       ring->writecount++;
-
-       /*
-        * Do on the fly cleaning.  Find some nodes we might not
-        * want around any more.
-        */
-       if (ring->writecount > 10) {
-               cleanup_ring(ring);
-               ring->writecount = 0;
-       }
-
-       result = dns_rbt_addname(ring->keys, name, tkey);
+       result = isc_hashmap_add(ring->keys, NULL, tkey->name->ndata,
+                                tkey->name->length, tkey);
        if (result == ISC_R_SUCCESS) {
                dns_tsigkey_ref(tkey);
                tkey->ring = ring;
@@ -1693,7 +1610,9 @@ dns_tsigkeyring_add(dns_tsigkeyring_t *ring, const dns_name_t *name,
                        ISC_LIST_APPEND(ring->lru, tkey, link);
                        dns_tsigkey_ref(tkey);
                        if (ring->generated++ > DNS_TSIG_MAXGENERATEDKEYS) {
-                               remove_fromring(ISC_LIST_HEAD(ring->lru));
+                               dns_tsigkey_t *key = ISC_LIST_HEAD(ring->lru);
+                               rm_lru(key);
+                               rm_hashmap(key);
                        }
                }
 
index 7f1cc7ce8c73c88874b9e1ad7c953d12dacacde3..35c788e82bd6d840a37289f758348656c0a45a5f 100644 (file)
@@ -144,10 +144,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
                goto cleanup_zt;
        }
 
-       result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
-       if (result != ISC_R_SUCCESS) {
-               goto cleanup_weakrefs;
-       }
+       dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
 
        result = dns_badcache_init(view->mctx, DNS_VIEW_FAILCACHESIZE,
                                   &view->failcache);
@@ -196,7 +193,6 @@ cleanup_dynkeys:
                dns_tsigkeyring_detach(&view->dynamickeys);
        }
 
-cleanup_weakrefs:
        isc_refcount_decrementz(&view->weakrefs);
        isc_refcount_destroy(&view->weakrefs);
 
index d448fe3ffec9cf40ad58fa8df7d253b9c170e040..6be05191edf4cb31007e390b461d5deaae7a5e6c 100644 (file)
@@ -12273,7 +12273,7 @@ notify_send_toaddr(void *arg) {
        if (key != NULL) {
                char namebuf[DNS_NAME_FORMATSIZE];
 
-               dns_name_format(&key->name, namebuf, sizeof(namebuf));
+               dns_name_format(key->name, namebuf, sizeof(namebuf));
                notify_log(notify->zone, ISC_LOG_INFO,
                           "sending notify to %s : TSIG (%s)", addrbuf,
                           namebuf);
@@ -17350,7 +17350,7 @@ again:
                        char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
                        if (zone->tsigkey != NULL) {
                                char namebuf[DNS_NAME_FORMATSIZE];
-                               dns_name_format(&zone->tsigkey->name, namebuf,
+                               dns_name_format(zone->tsigkey->name, namebuf,
                                                sizeof(namebuf));
                                snprintf(buf, sizeof(buf), ": TSIG '%s'",
                                         namebuf);
@@ -20484,7 +20484,7 @@ checkds_send_toaddr(void *arg) {
        if (key != NULL) {
                char namebuf[DNS_NAME_FORMATSIZE];
 
-               dns_name_format(&key->name, namebuf, sizeof(namebuf));
+               dns_name_format(key->name, namebuf, sizeof(namebuf));
                dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
                             "checkds: sending DS query to %s : TSIG (%s)",
                             addrbuf, namebuf);
index d4bd311766315b6d5d775ffc6dbaa36d654aeb62..7c56c5f4a44e500ac0f2dd1e952620b012d2895f 100644 (file)
@@ -533,7 +533,7 @@ ns_client_send(ns_client_t *client) {
 
                isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
                if (client->message->tsigkey != NULL) {
-                       name = &client->message->tsigkey->name;
+                       name = client->message->tsigkey->name;
                }
 
                if (client->view->nocasecompress == NULL ||
index 633ed96b8b5b3e00a737557d4ebe727437b7783e..f2ae6e5f8406d567914cf4f110c62342c76e7687 100644 (file)
@@ -129,7 +129,7 @@ ns_notify_start(ns_client_t *client, isc_nmhandle_t *handle) {
 
        tsigkey = dns_message_gettsigkey(request);
        if (tsigkey != NULL) {
-               dns_name_format(&tsigkey->name, namebuf, sizeof(namebuf));
+               dns_name_format(tsigkey->name, namebuf, sizeof(namebuf));
 
                if (tsigkey->generated) {
                        char cnamebuf[DNS_NAME_FORMATSIZE];
index cad24d21700a11e9df7025ac05920fd877adf72d..b83a6dcec184c53d12e5a1d0f2ebd3d04a9ee7a9 100644 (file)
@@ -1105,7 +1105,7 @@ have_stream:
        CHECK(xfr->stream->methods->first(xfr->stream));
 
        if (xfr->tsigkey != NULL) {
-               dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname));
+               dns_name_format(xfr->tsigkey->name, keyname, sizeof(keyname));
        } else {
                keyname[0] = '\0';
        }
index 88632b921ae22b510d46658909e86608e526eb82..6c6935e7c9380fbf2faa0434a20a144c61913c5b 100644 (file)
@@ -148,7 +148,7 @@ add_tsig(dst_context_t *tsigctx, dns_tsigkey_t *key, isc_buffer_t *target) {
        ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
        dns_rdataset_init(&rdataset);
        dns_rdatalist_tordataset(&rdatalist, &rdataset);
-       CHECK(dns_rdataset_towire(&rdataset, &key->name, &cctx, target, 0,
+       CHECK(dns_rdataset_towire(&rdataset, key->name, &cctx, target, 0,
                                  &count));
 
        /*
@@ -290,13 +290,13 @@ ISC_RUN_TEST_IMPL(tsig_tcp) {
        result = dns_name_fromstring(keyname, "test", 0, NULL);
        assert_int_equal(result, ISC_R_SUCCESS);
 
-       result = dns_tsigkeyring_create(mctx, &ring);
-       assert_int_equal(result, ISC_R_SUCCESS);
+       dns_tsigkeyring_create(mctx, &ring);
+       assert_non_null(ring);
 
        result = dns_tsigkey_create(keyname, DST_ALG_HMACSHA256, secret,
                                    sizeof(secret), mctx, &key);
        assert_int_equal(result, ISC_R_SUCCESS);
-       result = dns_tsigkeyring_add(ring, keyname, key);
+       result = dns_tsigkeyring_add(ring, key);
        assert_int_equal(result, ISC_R_SUCCESS);
        assert_non_null(key);