keytable.c revision 15a44745412679c30a6d022733925af70a38b715
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Copyright (C) 2000 Internet Software Consortium.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * Permission to use, copy, modify, and distribute this software for any
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * purpose with or without fee is hereby granted, provided that the above
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * copyright notice and this permission notice appear in all copies.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* $Id: keytable.c,v 1.20 2000/07/27 09:46:09 tale Exp $ */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <config.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <isc/mem.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <isc/rwlock.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <isc/string.h> /* Required for HP/UX (and others?) */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <isc/util.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <dns/keytable.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <dns/fixedname.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <dns/rbt.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <dns/result.h>
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntstruct dns_keytable {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /* Unlocked. */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt unsigned int magic;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mem_t *mctx;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mutex_t lock;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_rwlock_t rwlock;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /* Locked by lock. */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_uint32_t active_nodes;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /* Locked by rwlock. */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_uint32_t references;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_rbt_t *table;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt};
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt#define KEYTABLE_MAGIC 0x4b54626cU /* KTbl */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt#define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntstruct dns_keynode {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt unsigned int magic;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dst_key_t * key;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt struct dns_keynode * next;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt};
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt#define KEYNODE_MAGIC 0x4b4e6f64U /* KNod */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt#define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntstatic void
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntfree_keynode(void *node, void *arg) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_keynode_t *keynode = node;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mem_t *mctx = arg;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(VALID_KEYNODE(keynode));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dst_key_free(&keynode->key);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (keynode->next != NULL)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt free_keynode(keynode->next, mctx);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mem_put(mctx, keynode, sizeof(dns_keynode_t));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt}
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntisc_result_t
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntdns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_keytable_t *keytable;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_result_t result;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /*
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Create a keytable.
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(keytablep != NULL && *keytablep == NULL);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable = isc_mem_get(mctx, sizeof *keytable);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (keytable == NULL)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt return (ISC_R_NOMEMORY);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->table = NULL;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (result != ISC_R_SUCCESS)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt goto cleanup_keytable;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt result = isc_mutex_init(&keytable->lock);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (result != ISC_R_SUCCESS) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt UNEXPECTED_ERROR(__FILE__, __LINE__,
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt "isc_mutex_init() failed: %s",
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_result_totext(result));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt result = ISC_R_UNEXPECTED;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt goto cleanup_rbt;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt }
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt result = isc_rwlock_init(&keytable->rwlock, 0, 0);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (result != ISC_R_SUCCESS) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt UNEXPECTED_ERROR(__FILE__, __LINE__,
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt "isc_rwlock_init() failed: %s",
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_result_totext(result));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt result = ISC_R_UNEXPECTED;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt goto cleanup_lock;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt }
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->mctx = mctx;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->active_nodes = 0;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->references = 1;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->magic = KEYTABLE_MAGIC;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt *keytablep = keytable;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt return (ISC_R_SUCCESS);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews cleanup_lock:
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews isc_mutex_destroy(&keytable->lock);
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews cleanup_rbt:
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews dns_rbt_destroy(&keytable->table);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt cleanup_keytable:
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mem_put(mctx, keytable, sizeof *keytable);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt return (result);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt}
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntvoid
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntdns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /*
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Attach *targetp to source.
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(VALID_KEYTABLE(source));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(targetp != NULL && *targetp == NULL);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt RWLOCK(&source->rwlock, isc_rwlocktype_write);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt INSIST(source->references > 0);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt source->references++;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt INSIST(source->references != 0);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt *targetp = source;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt}
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntvoid
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntdns_keytable_detach(dns_keytable_t **keytablep) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_boolean_t destroy = ISC_FALSE;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_keytable_t *keytable;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /*
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Detach *keytablep from its keytable.
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable = *keytablep;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt INSIST(keytable->references > 0);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->references--;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt LOCK(&keytable->lock);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (keytable->references == 0 && keytable->active_nodes == 0)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt destroy = ISC_TRUE;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt UNLOCK(&keytable->lock);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (destroy) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_rbt_destroy(&keytable->table);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_rwlock_destroy(&keytable->rwlock);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mutex_destroy(&keytable->lock);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->magic = 0;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mem_put(keytable->mctx, keytable, sizeof *keytable);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt }
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt *keytablep = NULL;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt}
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntisc_result_t
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntdns_keytable_add(dns_keytable_t *keytable, dst_key_t **keyp) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_result_t result;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_keynode_t *knode;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_rbtnode_t *node;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_name_t *keyname;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /*
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Add '*keyp' to 'keytable'.
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt */
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(VALID_KEYTABLE(keytable));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(keyp != NULL);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keyname = dst_key_name(*keyp);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt knode = isc_mem_get(keytable->mctx, sizeof *knode);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (knode == NULL)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt return (ISC_R_NOMEMORY);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt node = NULL;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt result = dns_rbt_addnode(keytable->table, keyname, &node);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt knode->magic = KEYNODE_MAGIC;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt knode->key = *keyp;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt knode->next = node->data;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt node->data = knode;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt *keyp = NULL;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt knode = NULL;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt result = ISC_R_SUCCESS;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt }
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt if (knode != NULL)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_mem_put(keytable->mctx, knode, sizeof *knode);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt return (result);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt}
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntisc_result_t
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntdns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_secalg_t algorithm, dns_keytag_t tag,
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_keynode_t **keynodep)
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt{
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt isc_result_t result;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_keynode_t *knode;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt void *data;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt /*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Search for a key named 'name', matching 'algorithm' and 'tag' in
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * 'keytable'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(VALID_KEYTABLE(keytable));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(dns_name_isabsolute(name));
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt REQUIRE(keynodep != NULL && *keynodep == NULL);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt knode = NULL;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt data = NULL;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (result == ISC_R_SUCCESS) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt INSIST(data != NULL);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt for (knode = data; knode != NULL; knode = knode->next) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (algorithm == (dns_secalg_t)dst_key_alg(knode->key)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt && tag == (dns_keytag_t)dst_key_id(knode->key))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews if (knode != NULL) {
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews LOCK(&keytable->lock);
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt keytable->active_nodes++;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt UNLOCK(&keytable->lock);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *keynodep = knode;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt result = ISC_R_NOTFOUND;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else if (result == DNS_R_PARTIALMATCH)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt result = ISC_R_NOTFOUND;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return (result);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntisc_result_t
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntdns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt dns_keynode_t **nextnodep)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt isc_result_t result;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt dns_keynode_t *knode;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Search for the next key with the same properties as 'keynode' in
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * 'keytable'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(VALID_KEYTABLE(keytable));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(VALID_KEYNODE(keynode));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(nextnodep != NULL && *nextnodep == NULL);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt for (knode = keynode->next; knode != NULL; knode = knode->next) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (dst_key_alg(keynode->key) == dst_key_alg(knode->key) &&
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt dst_key_id(keynode->key) == dst_key_id(knode->key))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (knode != NULL) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt LOCK(&keytable->lock);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt keytable->active_nodes++;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt UNLOCK(&keytable->lock);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt result = ISC_R_SUCCESS;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *nextnodep = knode;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt result = ISC_R_NOTFOUND;
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return (result);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntisc_result_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt dns_name_t *foundname)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt isc_result_t result;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt void *data;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /*
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt * Search for the deepest match in 'keytable'.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(VALID_KEYTABLE(keytable));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(dns_name_isabsolute(name));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(foundname != NULL);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data = NULL;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt result = dns_rbt_findname(keytable->table, name, 0, foundname, &data);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt result = ISC_R_SUCCESS;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return (result);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntvoid
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Give back a keynode found via dns_keytable_findkeynode().
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(VALID_KEYTABLE(keytable));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt LOCK(&keytable->lock);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt INSIST(keytable->active_nodes > 0);
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews keytable->active_nodes--;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt UNLOCK(&keytable->lock);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
*keynodep = NULL;
}
isc_result_t
dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
isc_boolean_t *wantdnssecp)
{
isc_result_t result;
void *data;
/*
* Is 'name' at or beneath a trusted key?
*/
REQUIRE(VALID_KEYTABLE(keytable));
REQUIRE(dns_name_isabsolute(name));
REQUIRE(wantdnssecp != NULL);
RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
data = NULL;
result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
INSIST(data != NULL);
*wantdnssecp = ISC_TRUE;
result = ISC_R_SUCCESS;
} else if (result == ISC_R_NOTFOUND) {
*wantdnssecp = ISC_FALSE;
result = ISC_R_SUCCESS;
}
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
return (result);
}
dst_key_t *
dns_keynode_key(dns_keynode_t *keynode) {
/*
* Get the DST key associated with keynode.
*/
REQUIRE(VALID_KEYNODE(keynode));
return (keynode->key);
}