isc_result_t dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], dns_db_t **dbp) { dns_dbimplementation_t *impinfo; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); /* * Create a new database using implementation 'db_type'. */ REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(dns_name_isabsolute(origin)); RWLOCK(&implock, isc_rwlocktype_read); impinfo = impfind(db_type); if (impinfo != NULL) { isc_result_t result; result = ((impinfo->create)(mctx, origin, type, rdclass, argc, argv, impinfo->driverarg, dbp)); RWUNLOCK(&implock, isc_rwlocktype_read); return (result); } RWUNLOCK(&implock, isc_rwlocktype_read); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DB, ISC_LOG_ERROR, "unsupported database type '%s'", db_type); return (ISC_R_NOTFOUND); }
/* * A supplemental routine just to add a key to ring. Note that reference * counter should be counted separately because we may be adding the key * as part of creation of the key, in which case the reference counter was * already initialized. Also note we don't need RWLOCK for the reference * counter: it's protected by a separate lock. */ static isc_result_t keyring_add(dns_tsig_keyring_t *ring, dns_name_t *name, dns_tsigkey_t *tkey) { isc_result_t result; RWLOCK(&ring->lock, isc_rwlocktype_write); ring->writecount++; /* * Do on the fly cleaning. Find some nodes we might not * want around any more. */ if (ring->writecount > 10) { cleanup_ring(ring); ring->writecount = 0; } result = dns_rbt_addname(ring->keys, name, tkey); if (result == ISC_R_SUCCESS && tkey->generated) { /* * Add the new key to the LRU list and remove the least * recently used key if there are too many keys on the list. */ ISC_LIST_APPEND(ring->lru, tkey, link); if (ring->generated++ > ring->maxgenerated) remove_fromring(ISC_LIST_HEAD(ring->lru)); } RWUNLOCK(&ring->lock, isc_rwlocktype_write); return (result); }
isc_result_t dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) { isc_result_t result; static dns_zt_zoneloaded_t dl = doneloading; int pending; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->loads_pending == 0); result = dns_zt_apply2(zt, ISC_FALSE, NULL, asyncload, &dl); pending = zt->loads_pending; if (pending != 0) { zt->loaddone = alldone; zt->loaddone_arg = arg; } RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (pending == 0) alldone(arg); return (result); }
isc_result_t dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name, dns_name_t *foundname) { isc_result_t result; void *data; /* * Search for the deepest match in 'keytable'. */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(foundname != NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); data = NULL; result = dns_rbt_findname(keytable->table, name, 0, foundname, &data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) result = ISC_R_SUCCESS; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); }
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); }
isc_result_t dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname, dns_keynode_t **keynodep) { isc_result_t result; dns_rbtnode_t *node = NULL; REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(keyname != NULL); REQUIRE(keynodep != NULL && *keynodep == NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == ISC_R_SUCCESS) { if (node->data != NULL) { LOCK(&keytable->lock); keytable->active_nodes++; UNLOCK(&keytable->lock); dns_keynode_attach(node->data, keynodep); } else result = ISC_R_NOTFOUND; } else if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); }
static void zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) { isc_boolean_t destroy = ISC_FALSE; dns_zt_t *zt; REQUIRE(ztp != NULL && VALID_ZT(*ztp)); zt = *ztp; RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->references > 0); zt->references--; if (zt->references == 0) destroy = ISC_TRUE; if (need_flush) zt->flush = ISC_TRUE; RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (destroy) zt_destroy(zt); *ztp = NULL; }
void dns_keytable_detach(dns_keytable_t **keytablep) { isc_boolean_t destroy = ISC_FALSE; dns_keytable_t *keytable; /* * Detach *keytablep from its keytable. */ REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep)); keytable = *keytablep; RWLOCK(&keytable->rwlock, isc_rwlocktype_write); INSIST(keytable->references > 0); keytable->references--; LOCK(&keytable->lock); if (keytable->references == 0 && keytable->active_nodes == 0) destroy = ISC_TRUE; UNLOCK(&keytable->lock); RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); if (destroy) { dns_rbt_destroy(&keytable->table); isc_rwlock_destroy(&keytable->rwlock); DESTROYLOCK(&keytable->lock); keytable->magic = 0; isc_mem_putanddetach(&keytable->mctx, keytable, sizeof(*keytable)); } *keytablep = NULL; }
/* * Decrement the loads_pending counter; when counter reaches * zero, call the loaddone callback that was initially set by * dns_zt_asyncload(). */ static isc_result_t doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { isc_boolean_t destroy = ISC_FALSE; dns_zt_allloaded_t alldone = NULL; void *arg = NULL; UNUSED(zone); UNUSED(task); REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->loads_pending != 0); INSIST(zt->references != 0); zt->references--; if (zt->references == 0) destroy = ISC_TRUE; zt->loads_pending--; if (zt->loads_pending == 0) { alldone = zt->loaddone; arg = zt->loaddone_arg; zt->loaddone = NULL; zt->loaddone_arg = NULL; } RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (alldone != NULL) alldone(arg); if (destroy) zt_destroy(zt); return (ISC_R_SUCCESS); }
static void zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) { isc_boolean_t destroy = ISC_FALSE; dns_zt_t *zt; REQUIRE(ztp != NULL && VALID_ZT(*ztp)); zt = *ztp; RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->references > 0); zt->references--; if (zt->references == 0) destroy = ISC_TRUE; RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (destroy) { if (need_flush) (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL); dns_rbt_destroy(&zt->table); isc_rwlock_destroy(&zt->rwlock); zt->magic = 0; isc_mem_put(zt->mctx, zt, sizeof(*zt)); } *ztp = NULL; }
isc_result_t dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name, unsigned int options, dns_db_t **dbp) { dns_db_t *stored_data = NULL; isc_result_t result; unsigned int rbtoptions = 0; REQUIRE(dbp != NULL && *dbp == NULL); if ((options & DNS_DBTABLEFIND_NOEXACT) != 0) rbtoptions |= DNS_RBTFIND_NOEXACT; RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read); result = dns_rbt_findname(dbtable->rbt, name, rbtoptions, NULL, (void **) (void *)&stored_data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) dns_db_attach(stored_data, dbp); else if (dbtable->default_db != NULL) { dns_db_attach(dbtable->default_db, dbp); result = DNS_R_PARTIALMATCH; } else result = ISC_R_NOTFOUND; RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read); return (result); }
void dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db) { dns_db_t *stored_data = NULL; isc_result_t result; dns_name_t *name; REQUIRE(VALID_DBTABLE(dbtable)); name = dns_db_origin(db); /* * There is a requirement that the association of name with db * be verified. With the current rbt.c this is expensive to do, * because effectively two find operations are being done, but * deletion is relatively infrequent. * XXXDCL ... this could be cheaper now with dns_rbt_deletenode. */ RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); result = dns_rbt_findname(dbtable->rbt, name, 0, NULL, (void **) (void *)&stored_data); if (result == ISC_R_SUCCESS) { INSIST(stored_data == db); (void)dns_rbt_deletename(dbtable->rbt, name, ISC_FALSE); } RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); }
isc_result_t dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) { isc_result_t result; dns_rbtnodechain_t chain; dns_name_t foundname; dns_fixedname_t fixedorigin; dns_name_t *origin; isc_stdtime_t now; dns_rbtnode_t *node; dns_tsigkey_t *tkey; dns_tsig_keyring_t *ring; unsigned int references; REQUIRE(ringp != NULL && *ringp != NULL); ring = *ringp; *ringp = NULL; RWLOCK(&ring->lock, isc_rwlocktype_write); INSIST(ring->references > 0); ring->references--; references = ring->references; RWUNLOCK(&ring->lock, isc_rwlocktype_write); if (references != 0) return (DNS_R_CONTINUE); isc_stdtime_get(&now); dns_name_init(&foundname, NULL); dns_fixedname_init(&fixedorigin); origin = dns_fixedname_name(&fixedorigin); dns_rbtnodechain_init(&chain, ring->mctx); result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); goto destroy; } for (;;) { node = NULL; dns_rbtnodechain_current(&chain, &foundname, origin, &node); tkey = node->data; if (tkey != NULL && tkey->generated && tkey->expire >= now) dump_key(tkey, fp); result = dns_rbtnodechain_next(&chain, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; goto destroy; } } destroy: destroyring(ring); return (result); }
static int find_i(T *thiz, mkey_t *key, mval_t *v, mkv_t *tkv) { int r, i; hdr_block_t *hdr; off_t off; fkv_t fkv; fkv.kv = tkv; RWLOCK_READ(LOCK); r = krange_cmp(thiz, key); if (r != 0) { r = RC_NOT_FOUND; goto _out; } hdr = thiz->hdr; off = (hdr->node_cnt - 1) * BTR_INDEX_BLK_SIZE; /* root off */ for (i = 0; i < hdr->tree_heigh; i++) { off = find_in_index(thiz, off, key, NULL); if (off <= 0) { r = RC_NOT_FOUND; goto _out; } off = off - (off_t)(hdr->leaf_off); } r = find_in_leaf(thiz, off, key, &fkv, NULL); if (r != 0) { r = RC_NOT_FOUND; goto _out; } if (v != NULL) { v->len = tkv->v.len; v->data = MY_Malloc(v->len); r = read_val(thiz->rfd, fkv.blkoff, fkv.voff, v); if (r != 0) { r = RC_ERR; MY_Free(v->data); goto _out; } tkv->v.data = v->data; check_fval(thiz->rfd, tkv); } r = RC_FOUND; DEBUG("hit %.*s in %s", (int)key->len, key->data, thiz->file); _out: RWUNLOCK(LOCK); return r; }
void dns_tsigkey_setdeleted(dns_tsigkey_t *key) { REQUIRE(VALID_TSIG_KEY(key)); REQUIRE(key->ring != NULL); RWLOCK(&key->ring->lock, isc_rwlocktype_write); (void)dns_rbt_deletename(key->ring->keys, &key->name, ISC_FALSE); RWUNLOCK(&key->ring->lock, isc_rwlocktype_write); }
void dns_tsigkey_setdeleted(dns_tsigkey_t *key) { REQUIRE(VALID_TSIG_KEY(key)); REQUIRE(key->ring != NULL); RWLOCK(&key->ring->lock, isc_rwlocktype_write); remove_fromring(key); RWUNLOCK(&key->ring->lock, isc_rwlocktype_write); }
isc_result_t dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, dns_secalg_t algorithm, dns_keytag_t tag, dns_keynode_t **keynodep) { isc_result_t result; dns_keynode_t *knode; void *data; /* * Search for a key named 'name', matching 'algorithm' and 'tag' in * 'keytable'. */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(keynodep != NULL && *keynodep == NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); /* * Note we don't want the DNS_R_PARTIALMATCH from dns_rbt_findname() * as that indicates that 'name' was not found. * * DNS_R_PARTIALMATCH indicates that the name was found but we * didn't get a match on algorithm and key id arguments. */ knode = NULL; data = NULL; result = dns_rbt_findname(keytable->table, name, 0, NULL, &data); if (result == ISC_R_SUCCESS) { INSIST(data != NULL); for (knode = data; knode != NULL; knode = knode->next) { if (knode->key == NULL) { knode = NULL; break; } if (algorithm == dst_key_alg(knode->key) && tag == dst_key_id(knode->key)) break; } if (knode != NULL) { LOCK(&keytable->lock); keytable->active_nodes++; UNLOCK(&keytable->lock); dns_keynode_attach(knode, keynodep); } else result = DNS_R_PARTIALMATCH; } else if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); }
void dns_dbtable_removedefault(dns_dbtable_t *dbtable) { REQUIRE(VALID_DBTABLE(dbtable)); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); dns_db_detach(&dbtable->default_db); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); }
void dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **dbp) { REQUIRE(VALID_DBTABLE(dbtable)); REQUIRE(dbp != NULL && *dbp == NULL); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read); dns_db_attach(dbtable->default_db, dbp); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read); }
isc_result_t dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze) { isc_result_t result, tresult; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_read); result = dns_zt_apply2(zt, ISC_FALSE, &tresult, freezezones, &freeze); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); return ((result == ISC_R_SUCCESS) ? tresult : result); }
isc_result_t dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop) { isc_result_t result; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_read); result = dns_zt_apply(zt, stop, loadnew, NULL); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); return (result); }
isc_result_t dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name, dns_name_t *algorithm, dns_tsig_keyring_t *ring) { dns_tsigkey_t *key; isc_stdtime_t now; isc_result_t result; REQUIRE(tsigkey != NULL); REQUIRE(*tsigkey == NULL); REQUIRE(name != NULL); REQUIRE(ring != NULL); isc_stdtime_get(&now); RWLOCK(&ring->lock, isc_rwlocktype_read); key = NULL; result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key); if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } if (key->inception != key->expire && key->expire < now) { /* * The key has expired. */ RWUNLOCK(&ring->lock, isc_rwlocktype_read); RWLOCK(&ring->lock, isc_rwlocktype_write); (void) dns_rbt_deletename(ring->keys, name, ISC_FALSE); RWUNLOCK(&ring->lock, isc_rwlocktype_write); return (ISC_R_NOTFOUND); } isc_refcount_increment(&key->refs, NULL); RWUNLOCK(&ring->lock, isc_rwlocktype_read); *tsigkey = key; return (ISC_R_SUCCESS); }
isc_result_t dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name, dns_name_t *algorithm, dns_tsig_keyring_t *ring) { dns_tsigkey_t *key; isc_stdtime_t now; isc_result_t result; REQUIRE(tsigkey != NULL); REQUIRE(*tsigkey == NULL); REQUIRE(name != NULL); REQUIRE(ring != NULL); RWLOCK(&ring->lock, isc_rwlocktype_write); cleanup_ring(ring); RWUNLOCK(&ring->lock, isc_rwlocktype_write); isc_stdtime_get(&now); RWLOCK(&ring->lock, isc_rwlocktype_read); key = NULL; result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key); if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } if (key->inception != key->expire && isc_serial_lt(key->expire, now)) { /* * The key has expired. */ RWUNLOCK(&ring->lock, isc_rwlocktype_read); RWLOCK(&ring->lock, isc_rwlocktype_write); remove_fromring(key); RWUNLOCK(&ring->lock, isc_rwlocktype_write); return (ISC_R_NOTFOUND); } #if 0 /* * MPAXXX We really should look at the inception time. */ if (key->inception != key->expire && isc_serial_lt(key->inception, now)) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); adjust_lru(key); return (ISC_R_NOTFOUND); } #endif isc_refcount_increment(&key->refs, NULL); RWUNLOCK(&ring->lock, isc_rwlocktype_read); adjust_lru(key); *tsigkey = key; return (ISC_R_SUCCESS); }
void dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db) { REQUIRE(VALID_DBTABLE(dbtable)); REQUIRE(dbtable->default_db == NULL); REQUIRE(dns_name_compare(dns_db_origin(db), dns_rootname) == 0); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); dbtable->default_db = NULL; dns_db_attach(db, &dbtable->default_db); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); }
void dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target) { REQUIRE(source != NULL); REQUIRE(target != NULL && *target == NULL); RWLOCK(&source->lock, isc_rwlocktype_write); INSIST(source->references > 0); source->references++; INSIST(source->references > 0); *target = source; RWUNLOCK(&source->lock, isc_rwlocktype_write); }
isc_result_t dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name, isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy) { isc_result_t result; dns_forwarders_t *forwarders; dns_forwarder_t *fwd; isc_sockaddr_t *sa; REQUIRE(VALID_FWDTABLE(fwdtable)); forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t)); if (forwarders == NULL) return (ISC_R_NOMEMORY); ISC_LIST_INIT(forwarders->fwdrs); for (sa = ISC_LIST_HEAD(*addrs); sa != NULL; sa = ISC_LIST_NEXT(sa, link)) { fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t)); if (fwd == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } fwd->addr = *sa; fwd->dscp = -1; ISC_LINK_INIT(fwd, link); ISC_LIST_APPEND(forwarders->fwdrs, fwd, link); } forwarders->fwdpolicy = fwdpolicy; RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); result = dns_rbt_addname(fwdtable->table, name, forwarders); RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); if (result != ISC_R_SUCCESS) goto cleanup; return (ISC_R_SUCCESS); cleanup: while (!ISC_LIST_EMPTY(forwarders->fwdrs)) { fwd = ISC_LIST_HEAD(forwarders->fwdrs); ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link); isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t)); } isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); return (result); }
isc_result_t dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg, isc_mem_t *mctx, dns_dbimplementation_t **dbimp) { dns_dbimplementation_t *imp; REQUIRE(name != NULL); REQUIRE(dbimp != NULL && *dbimp == NULL); RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); RWLOCK(&implock, isc_rwlocktype_write); imp = impfind(name); if (imp != NULL) { RWUNLOCK(&implock, isc_rwlocktype_write); return (ISC_R_EXISTS); } imp = isc_mem_get(mctx, sizeof(dns_dbimplementation_t)); if (imp == NULL) { RWUNLOCK(&implock, isc_rwlocktype_write); return (ISC_R_NOMEMORY); } imp->name = name; imp->create = create; imp->mctx = NULL; imp->driverarg = driverarg; isc_mem_attach(mctx, &imp->mctx); ISC_LINK_INIT(imp, link); ISC_LIST_APPEND(implementations, imp, link); RWUNLOCK(&implock, isc_rwlocktype_write); *dbimp = imp; return (ISC_R_SUCCESS); }
static void adjust_lru(dns_tsigkey_t *tkey) { if (tkey->generated) { RWLOCK(&tkey->ring->lock, isc_rwlocktype_write); /* * We may have been removed from the LRU list between * removing the read lock and aquiring the write lock. */ if (ISC_LINK_LINKED(tkey, link)) { ISC_LIST_UNLINK(tkey->ring->lru, tkey, link); ISC_LIST_APPEND(tkey->ring->lru, tkey, link); } RWUNLOCK(&tkey->ring->lock, isc_rwlocktype_write); } }
isc_result_t dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name) { isc_result_t result; REQUIRE(VALID_FWDTABLE(fwdtable)); RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); result = dns_rbt_deletename(fwdtable->table, name, ISC_FALSE); RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; return (result); }
void dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp) { REQUIRE(VALID_ZT(zt)); REQUIRE(ztp != NULL && *ztp == NULL); RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->references > 0); zt->references++; INSIST(zt->references != 0); RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); *ztp = zt; }