6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews/*
6fb9b25791778f69002eb72be6235e20d98ec452Tinderbox User * Copyright (C) 2000, 2001, 2004, 2005, 2007, 2009, 2010, 2013-2016, 2018 Internet Systems Consortium, Inc. ("ISC")
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id: keytable.c,v 1.41 2010/06/25 23:46:51 tbox Exp $ */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews/*! \file */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <config.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <isc/mem.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <isc/print.h>
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews#include <isc/refcount.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <isc/rwlock.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <isc/string.h> /* Required for HP/UX (and others?) */
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt#include <isc/util.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <dns/keytable.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <dns/fixedname.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <dns/rbt.h>
8d31dd9ab62d91b5f23ac687657c966d44074a3fMark Andrews#include <dns/result.h>
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l')
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews#define KEYNODE_MAGIC ISC_MAGIC('K', 'N', 'o', 'd')
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstruct dns_keytable {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* Unlocked. */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int magic;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_mem_t *mctx;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_t active_nodes;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_t references;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_rwlock_t rwlock;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* Locked by rwlock. */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbt_t *table;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews};
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstruct dns_keynode {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int magic;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_t refcount;
79ce3a9e82384cc31fd6b86be8f3d1474fcfd9f4Evan Hunt dst_key_t * key;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_boolean_t managed;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews struct dns_keynode * next;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews};
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstatic void
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsfree_keynode(void *node, void *arg) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *keynode = node;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_mem_t *mctx = arg;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_detachall(mctx, &keynode);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
ad127d839d2e7aa542939a8a336691407e23397eMark Andrewsdns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keytable_t *keytable;
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews isc_result_t result;
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Create a keytable.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(keytablep != NULL && *keytablep == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
dd14c953a8a42b60ea86a2a630529014fc3d14ddMark Andrews keytable = isc_mem_get(mctx, sizeof(*keytable));
dd14c953a8a42b60ea86a2a630529014fc3d14ddMark Andrews if (keytable == NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOMEMORY);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews keytable->table = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS) {
3398334b3acda24b086957286288ca9852662b12Automatic Updater goto cleanup_keytable;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = isc_rwlock_init(&keytable->rwlock, 0, 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto cleanup_rbt;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = isc_refcount_init(&keytable->active_nodes, 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto cleanup_rwlock;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = isc_refcount_init(&keytable->references, 1);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews if (result != ISC_R_SUCCESS) {
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt goto cleanup_active_nodes;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews keytable->mctx = NULL;
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt isc_mem_attach(mctx, &keytable->mctx);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews keytable->magic = KEYTABLE_MAGIC;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *keytablep = keytable;
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews cleanup_active_nodes:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_destroy(&keytable->active_nodes);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews cleanup_rwlock:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_rwlock_destroy(&keytable->rwlock);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews cleanup_rbt:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbt_destroy(&keytable->table);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews cleanup_keytable:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_mem_putanddetach(&mctx, keytable, sizeof(*keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Attach *targetp to source.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(source));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(targetp != NULL && *targetp == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews isc_refcount_increment(&source->references, NULL);
126dce8ebf94ba4084befd82dd75e19b0c1d3f69Automatic Updater
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews *targetp = source;
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews}
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrewsvoid
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrewsdns_keytable_detach(dns_keytable_t **keytablep) {
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews dns_keytable_t *keytable;
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews unsigned int refs;
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews /*
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews * Detach *keytablep from its keytable.
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews */
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep));
126dce8ebf94ba4084befd82dd75e19b0c1d3f69Automatic Updater
e7ba4d8dc4559ff47f7f8298dad1469275ed0f1eMark Andrews keytable = *keytablep;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *keytablep = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_decrement(&keytable->references, &refs);
554d22d2deb8889bb16434176b5716ab79d15c50Mark Andrews if (refs == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(isc_refcount_current(&keytable->active_nodes) == 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_destroy(&keytable->active_nodes);
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews isc_refcount_destroy(&keytable->references);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbt_destroy(&keytable->table);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_rwlock_destroy(&keytable->rwlock);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews keytable->magic = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_mem_putanddetach(&keytable->mctx,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews keytable, sizeof(*keytable));
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews }
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
ad127d839d2e7aa542939a8a336691407e23397eMark Andrewsstatic isc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsinsert(dns_keytable_t *keytable, isc_boolean_t managed,
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews dns_name_t *keyname, dst_key_t **keyp)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *knode = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnode_t *node;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(keyp == NULL || *keyp != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews result = dns_keynode_create(keytable->mctx, &knode);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->managed = managed;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews node = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_addnode(keytable->table, keyname, &node);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (keyp != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_EXISTS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* Key already in table? */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *k;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (k = node->data; k != NULL; k = k->next) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (k->key == NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews k->key = *keyp;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *keyp = NULL; /* transfer ownership */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
3398334b3acda24b086957286288ca9852662b12Automatic Updater if (dst_key_compare(k->key, *keyp) == ISC_TRUE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (k == NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews else if (*keyp != NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dst_key_free(keyp);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->key = *keyp;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->next = node->data;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *keyp = NULL;
ad127d839d2e7aa542939a8a336691407e23397eMark Andrews }
6d5f928b26f51e51817248f7b28472eb6973a710Tinderbox User }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews node->data = knode;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* Key was already there? That's the same as a success */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_EXISTS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode != NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_detach(keytable->mctx, &knode);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dst_key_t **keyp)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(keyp != NULL && *keyp != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (insert(keytable, managed, dst_key_name(*keyp), keyp));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (insert(keytable, ISC_TRUE, name, NULL));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrewsisc_result_t
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrewsdns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
dd14c953a8a42b60ea86a2a630529014fc3d14ddMark Andrews dns_rbtnode_t *node = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(keyname != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews DNS_RBTFIND_NOOPTIONS, NULL, NULL);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews if (result == ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (node->data != NULL)
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews result = dns_rbt_deletenode(keytable->table,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews node, ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews else
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if (result == DNS_R_PARTIALMATCH)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrewsdns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey) {
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_t *keyname;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnode_t *node = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *knode = NULL, **kprev = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(dstkey != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews keyname = dst_key_name(dstkey);
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews DNS_RBTFIND_NOOPTIONS, NULL, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == DNS_R_PARTIALMATCH)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto finish;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (node->data == NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto finish;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
3398334b3acda24b086957286288ca9852662b12Automatic Updater knode = node->data;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode->next == NULL && knode->key != NULL &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dst_key_compare(knode->key, dstkey) == ISC_TRUE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_deletenode(keytable->table, node, ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto finish;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews kprev = (dns_keynode_t **) &node->data;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (knode != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode->key != NULL &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dst_key_compare(knode->key, dstkey) == ISC_TRUE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews kprev = &knode->next;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode = knode->next;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode->key != NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dst_key_free(&knode->key);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * This is equivalent to:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * dns_keynode_attach(knode->next, &tmp);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * dns_keynode_detach(kprev);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * dns_keynode_attach(tmp, &kprev);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * dns_keynode_detach(&tmp);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *kprev = knode->next;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->next = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_detach(keytable->mctx, &knode);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = DNS_R_PARTIALMATCH;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews finish:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
3398334b3acda24b086957286288ca9852662b12Automatic Updaterisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname,
3398334b3acda24b086957286288ca9852662b12Automatic Updater dns_keynode_t **keynodep)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnode_t *node = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(keyname != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(keynodep != NULL && *keynodep == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews DNS_RBTFIND_NOOPTIONS, NULL, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (node->data != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_increment0(&keytable->active_nodes, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_attach(node->data, keynodep);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if (result == DNS_R_PARTIALMATCH)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t **nextnodep)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Return the next key after 'keynode', regardless of
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * properties.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
3398334b3acda24b086957286288ca9852662b12Automatic Updater REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(keynode));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(nextnodep != NULL && *nextnodep == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (keynode->next == NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOTFOUND);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_attach(keynode->next, nextnodep);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_increment(&keytable->active_nodes, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns_secalg_t algorithm, dns_keytag_t tag,
6fb9b25791778f69002eb72be6235e20d98ec452Tinderbox User dns_keynode_t **keynodep)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *knode;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews void *data;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Search for a key named 'name', matching 'algorithm' and 'tag' in
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * 'keytable'.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(dns_name_isabsolute(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(keynodep != NULL && *keynodep == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
3398334b3acda24b086957286288ca9852662b12Automatic Updater
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Note we don't want the DNS_R_PARTIALMATCH from dns_rbt_findname()
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * as that indicates that 'name' was not found.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * DNS_R_PARTIALMATCH indicates that the name was found but we
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * didn't get a match on algorithm and key id arguments.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews data = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(data != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (knode = data; knode != NULL; knode = knode->next) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode->key == NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
3398334b3acda24b086957286288ca9852662b12Automatic Updater if (algorithm == dst_key_alg(knode->key)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews && tag == dst_key_id(knode->key))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_increment0(&keytable->active_nodes, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_attach(knode, keynodep);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = DNS_R_PARTIALMATCH;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if (result == DNS_R_PARTIALMATCH)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t **nextnodep)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *knode;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Search for the next key with the same properties as 'keynode' in
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * 'keytable'.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(keynode));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(nextnodep != NULL && *nextnodep == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (knode = keynode->next; knode != NULL; knode = knode->next) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode->key == NULL) {
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews knode = NULL;
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews break;
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews }
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews if (dst_key_alg(keynode->key) == dst_key_alg(knode->key) &&
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews dst_key_id(keynode->key) == dst_key_id(knode->key))
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews break;
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews }
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews if (knode != NULL) {
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews isc_refcount_increment(&keytable->active_nodes, NULL);
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews result = ISC_R_SUCCESS;
15bbb8a1298a61e401ba16c944dc06049abb81bfAutomatic Updater dns_keynode_attach(knode, nextnodep);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_NOTFOUND;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_t *foundname)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews void *data;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Search for the deepest match in 'keytable'.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(dns_name_isabsolute(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(foundname != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews data = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_findname(keytable->table, name, 0, foundname, &data);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t **target)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Give back a keynode found via dns_keytable_findkeynode().
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(source));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(target != NULL && *target == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_increment(&keytable->active_nodes, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_attach(source, target);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Give back a keynode found via dns_keytable_findkeynode().
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews REQUIRE(VALID_KEYTABLE(keytable));
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_decrement(&keytable->active_nodes, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_detach(keytable->mctx, keynodep);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_t *foundname, isc_boolean_t *wantdnssecp)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
f66ac0c85848ebc77148e06f42dc4e1796bf86cbEvan Hunt isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnode_t *node = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Is 'name' at or beneath a trusted key?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(dns_name_isabsolute(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(wantdnssecp != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbt_findnode(keytable->table, name, foundname, &node,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews NULL, DNS_RBTFIND_NOOPTIONS, NULL, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(node->data != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *wantdnssecp = ISC_TRUE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if (result == ISC_R_NOTFOUND) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *wantdnssecp = ISC_FALSE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstatic isc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsputstr(isc_buffer_t **b, const char *str) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = isc_buffer_reserve(b, strlen(str));
b16d99bac1d100735224ab3eaa84632537ff21b5Mark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_putstr(*b, str);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_dump(dns_keytable_t *keytable, FILE *fp) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_t *text = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(fp != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = isc_buffer_allocate(keytable->mctx, &text, 4096);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_keytable_totext(keytable, &text);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (isc_buffer_usedlength(text) != 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (void) putstr(&text, "\n");
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if (result == ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (void) putstr(&text, "none");
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews else {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (void) putstr(&text, "could not dump key table: ");
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt (void) putstr(&text, isc_result_totext(result));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews fprintf(fp, "%.*s", (int) isc_buffer_usedlength(text),
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (char *) isc_buffer_base(text));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_free(&text);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Huntdns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt isc_result_t result;
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt dns_keynode_t *knode;
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt dns_rbtnode_t *node;
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt dns_rbtnodechain_t chain;
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(text != NULL && *text != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnodechain_init(&chain, keytable->mctx);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_NOTFOUND)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto cleanup;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (;;) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews char pbuf[DST_KEY_FORMATSIZE];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnodechain_current(&chain, NULL, NULL, &node);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (knode = node->data; knode != NULL; knode = knode->next) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews char obuf[DNS_NAME_FORMATSIZE + 200];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode->key == NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dst_key_format(knode->key, pbuf, sizeof(pbuf));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews snprintf(obuf, sizeof(obuf), "%s ; %s\n", pbuf,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->managed ? "managed" : "trusted");
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = putstr(text, obuf);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbtnodechain_next(&chain, NULL, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_NOMORE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews cleanup:
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt dns_rbtnodechain_invalidate(&chain);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt}
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Huntisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keytable_forall(dns_keytable_t *keytable,
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt void (*func)(dns_keytable_t *, dns_keynode_t *, void *),
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews void *arg)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnode_t *node;
d3a6cd7c7e13707d0c26e1af0e026dd6c22c5e99Evan Hunt dns_rbtnodechain_t chain;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYTABLE(keytable));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnodechain_init(&chain, keytable->mctx);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_NOTFOUND)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto cleanup;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_increment0(&keytable->active_nodes, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (;;) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnodechain_current(&chain, NULL, NULL, &node);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (node->data != NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (*func)(keytable, node->data, arg);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rbtnodechain_next(&chain, NULL, NULL);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_NOMORE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews isc_refcount_decrement(&keytable->active_nodes, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews cleanup:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rbtnodechain_invalidate(&chain);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdst_key_t *
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Huntdns_keynode_key(dns_keynode_t *keynode) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Get the DST key associated with keynode.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(keynode));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (keynode->key);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_boolean_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keynode_managed(dns_keynode_t *keynode) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Is this a managed key?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(keynode));
3398334b3acda24b086957286288ca9852662b12Automatic Updater
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (keynode->managed);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *knode;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(target != NULL && *target == NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode = isc_mem_get(mctx, sizeof(dns_keynode_t));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (knode == NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOMEMORY);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->magic = KEYNODE_MAGIC;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->managed = ISC_FALSE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->key = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews knode->next = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = isc_refcount_init(&knode->refcount, 1);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *target = knode;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(source));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_increment(&source->refcount, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *target = source;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynode) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int refs;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *node = *keynode;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(node));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_decrement(&node->refcount, &refs);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (refs == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (node->key != NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dst_key_free(&node->key);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_refcount_destroy(&node->refcount);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_mem_put(mctx, node, sizeof(dns_keynode_t));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *keynode = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **keynode) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_t *next = NULL, *node = *keynode;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_KEYNODE(node));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (node != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews next = node->next;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_keynode_detach(mctx, &node);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews node = next;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *keynode = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews