keytable.c revision dafcb997e390efa4423883dafd100c975c4095d6
9eb24f1f84885d5c2e51a7f675264db398c31af7Tinderbox User * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * Copyright (C) 2000, 2001 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * copyright notice and this permission notice appear in all copies.
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * PERFORMANCE OF THIS SOFTWARE.
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont/* $Id: keytable.c,v 1.28 2004/03/05 05:09:20 marka Exp $ */
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont#include <isc/string.h> /* Required for HP/UX (and others?) */
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont /* Unlocked. */
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont unsigned int magic;
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt /* Locked by lock. */
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt /* Locked by rwlock. */
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont#define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l')
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont#define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC)
d1f39121a69b6afa6c0c9e44eceb60910d1d7f81Evan Hunt unsigned int magic;
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews#define KEYNODE_MAGIC ISC_MAGIC('K', 'N', 'o', 'd')
78608b0a454246d0e1e0169f1d671b8427e48199Francis Dupont#define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC)
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont isc_mem_put(mctx, keynode, sizeof(dns_keynode_t));
2a31bd531072824ef252c18303859d6af7451b00Francis Dupontdns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
8b78c993cb475cc94e88560941b28c37684789d9Francis Dupont * Create a keytable.
8b78c993cb475cc94e88560941b28c37684789d9Francis Dupont result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table);
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont "isc_mutex_init() failed: %s",
8b78c993cb475cc94e88560941b28c37684789d9Francis Dupont result = isc_rwlock_init(&keytable->rwlock, 0, 0);
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont "isc_rwlock_init() failed: %s",
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont isc_mem_put(mctx, keytable, sizeof(*keytable));
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupontdns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
8b78c993cb475cc94e88560941b28c37684789d9Francis Dupont * Attach *targetp to source.
8b78c993cb475cc94e88560941b28c37684789d9Francis Dupont REQUIRE(targetp != NULL && *targetp == NULL);
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont RWLOCK(&source->rwlock, isc_rwlocktype_write);
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
2a31bd531072824ef252c18303859d6af7451b00Francis Dupontdns_keytable_detach(dns_keytable_t **keytablep) {
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * Detach *keytablep from its keytable.
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep));
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont if (keytable->references == 0 && keytable->active_nodes == 0)
8a198fa776a09beb4dabf40b73a54d9c7bd70ac9Evan Hunt RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont isc_mem_put(keytable->mctx, keytable, sizeof(*keytable));
2a31bd531072824ef252c18303859d6af7451b00Francis Dupontdns_keytable_add(dns_keytable_t *keytable, dst_key_t **keyp) {
a60bf97f9f7dcde6f4ca6e8188245fb0866200dbEvan Hunt * Add '*keyp' to 'keytable'.
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont knode = isc_mem_get(keytable->mctx, sizeof(*knode));
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
8b78c993cb475cc94e88560941b28c37684789d9Francis Dupont result = dns_rbt_addnode(keytable->table, keyname, &node);
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
553ead32ff5b00284e574dcabc39115d4d74ec66Evan Hunt RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
8f0502e922120f27207fbf6b6dda18f1112e486cEvan Hunt isc_mem_put(keytable->mctx, knode, sizeof(*knode));
2a31bd531072824ef252c18303859d6af7451b00Francis Dupontdns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * Search for a key named 'name', matching 'algorithm' and 'tag' in
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont * 'keytable'.
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont REQUIRE(keynodep != NULL && *keynodep == NULL);
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
8a198fa776a09beb4dabf40b73a54d9c7bd70ac9Evan Hunt for (knode = data; knode != NULL; knode = knode->next) {
e939674d53a127ddeeaf4b41fd72933f0b493308Mark Andrews RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupontdns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont * Search for the next key with the same properties as 'keynode' in
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont * 'keytable'.
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont REQUIRE(nextnodep != NULL && *nextnodep == NULL);
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont for (knode = keynode->next; knode != NULL; knode = knode->next) {
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont if (dst_key_alg(keynode->key) == dst_key_alg(knode->key) &&
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont dst_key_id(keynode->key) == dst_key_id(knode->key))
e939674d53a127ddeeaf4b41fd72933f0b493308Mark Andrewsdns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
e939674d53a127ddeeaf4b41fd72933f0b493308Mark Andrews * Search for the deepest match in 'keytable'.
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
1f821c10583d9cddbaf3626a96ff8cf10cdb645bFrancis Dupont result = dns_rbt_findname(keytable->table, name, 0, foundname, &data);
a60bf97f9f7dcde6f4ca6e8188245fb0866200dbEvan Hunt if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
2a31bd531072824ef252c18303859d6af7451b00Francis Dupontdns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
ddac1a2b9822b00aa936ef24c6d971f4a1407532Francis Dupont * Give back a keynode found via dns_keytable_findkeynode().
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
2a31bd531072824ef252c18303859d6af7451b00Francis Dupontdns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
8b78c993cb475cc94e88560941b28c37684789d9Francis Dupont * Is 'name' at or beneath a trusted key?
a60bf97f9f7dcde6f4ca6e8188245fb0866200dbEvan Hunt result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
7d769b7ba79707d51e241813fdafa79f74eb7f17Evan Hunt if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
a60bf97f9f7dcde6f4ca6e8188245fb0866200dbEvan Hunt * Get the DST key associated with keynode.