summaryrefslogtreecommitdiff
path: root/lib/dns/rbtdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/rbtdb.c')
-rw-r--r--lib/dns/rbtdb.c141
1 files changed, 78 insertions, 63 deletions
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index f6f96ab9315a..a4a5acffece4 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -1121,8 +1121,8 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) {
version->hash = rbtdb->current_version->hash;
version->salt_length =
rbtdb->current_version->salt_length;
- memcpy(version->salt, rbtdb->current_version->salt,
- version->salt_length);
+ memmove(version->salt, rbtdb->current_version->salt,
+ version->salt_length);
} else {
version->flags = 0;
version->iterations = 0;
@@ -1706,8 +1706,11 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
nodelock = &rbtdb->node_locks[bucket];
+#define KEEP_NODE(n, r) \
+ ((n)->data != NULL || (n)->down != NULL || (n) == (r)->origin_node)
+
/* Handle easy and typical case first. */
- if (!node->dirty && (node->data != NULL || node->down != NULL)) {
+ if (!node->dirty && KEEP_NODE(node, rbtdb)) {
dns_rbtnode_refdecrement(node, &nrefs);
INSIST((int)nrefs >= 0);
if (nrefs == 0) {
@@ -1776,12 +1779,11 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
isc_refcount_decrement(&nodelock->references, &refs);
INSIST((int)refs >= 0);
- /*
- * XXXDCL should this only be done for cache zones?
- */
- if (node->data != NULL || node->down != NULL)
+ if (KEEP_NODE(node, rbtdb))
goto restore_locks;
+#undef KEEP_NODE
+
if (write_locked) {
/*
* We can now delete the node.
@@ -2127,8 +2129,8 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version) {
if (nsec3param.flags != 0)
continue;
- memcpy(version->salt, nsec3param.salt,
- nsec3param.salt_length);
+ memmove(version->salt, nsec3param.salt,
+ nsec3param.salt_length);
version->hash = nsec3param.hash;
version->salt_length = nsec3param.salt_length;
version->iterations = nsec3param.iterations;
@@ -4168,7 +4170,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
header_prev = NULL;
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
- if (header->rdh_ttl <= search->now) {
+ if (header->rdh_ttl < search->now) {
/*
* This rdataset is stale. If no one else is
* using the node, we can clean it up right
@@ -4176,7 +4178,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
* the node as dirty, so it will get cleaned
* up later.
*/
- if ((header->rdh_ttl <= search->now - RBTDB_VIRTUAL) &&
+ if ((header->rdh_ttl < search->now - RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
/*
@@ -4292,7 +4294,7 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
header != NULL;
header = header_next) {
header_next = header->next;
- if (header->rdh_ttl <= search->now) {
+ if (header->rdh_ttl < search->now) {
/*
* This rdataset is stale. If no one else is
* using the node, we can clean it up right
@@ -4300,7 +4302,7 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
* the node as dirty, so it will get cleaned
* up later.
*/
- if ((header->rdh_ttl <= search->now -
+ if ((header->rdh_ttl < search->now -
RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
@@ -4469,7 +4471,7 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
header != NULL;
header = header_next) {
header_next = header->next;
- if (header->rdh_ttl <= now) {
+ if (header->rdh_ttl < now) {
/*
* This rdataset is stale. If no one else is
* using the node, we can clean it up right
@@ -4477,7 +4479,7 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
* node as dirty, so it will get cleaned up
* later.
*/
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
+ if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
/*
@@ -4625,12 +4627,12 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
switch (rdata.type) {
case dns_rdatatype_a:
INSIST(rdata.length == 4);
- memcpy(&ina.s_addr, rdata.data, 4);
+ memmove(&ina.s_addr, rdata.data, 4);
isc_netaddr_fromin(&netaddr, &ina);
break;
case dns_rdatatype_aaaa:
INSIST(rdata.length == 16);
- memcpy(in6a.s6_addr, rdata.data, 16);
+ memmove(in6a.s6_addr, rdata.data, 16);
isc_netaddr_fromin6(&netaddr, &in6a);
break;
default:
@@ -4875,14 +4877,14 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
header_prev = NULL;
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
- if (header->rdh_ttl <= now) {
+ if (header->rdh_ttl < now) {
/*
* This rdataset is stale. If no one else is using the
* node, we can clean it up right now, otherwise we
* mark it as stale, and the node as dirty, so it will
* get cleaned up later.
*/
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
+ if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
/*
@@ -5182,14 +5184,14 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
header_prev = NULL;
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
- if (header->rdh_ttl <= now) {
+ if (header->rdh_ttl < now) {
/*
* This rdataset is stale. If no one else is using the
* node, we can clean it up right now, otherwise we
* mark it as stale, and the node as dirty, so it will
* get cleaned up later.
*/
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
+ if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
/*
@@ -5671,8 +5673,8 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
for (header = rbtnode->data; header != NULL; header = header_next) {
header_next = header->next;
- if (header->rdh_ttl <= now) {
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
+ if (header->rdh_ttl < now) {
+ if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
/*
@@ -5980,7 +5982,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
}
}
if (topheader != NULL && EXISTS(topheader) &&
- topheader->rdh_ttl > now) {
+ topheader->rdh_ttl >= now) {
/*
* Found one.
*/
@@ -6046,7 +6048,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* has no effect, provided that the cache data isn't stale.
*/
if (rbtversion == NULL && trust < header->trust &&
- (header->rdh_ttl > now || header_nx)) {
+ (header->rdh_ttl >= now || header_nx)) {
free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
if (addedrdataset != NULL)
bind_rdataset(rbtdb, rbtnode, header, now,
@@ -6116,7 +6118,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* Don't lower trust of existing record if the
* update is forced.
*/
- if (IS_CACHE(rbtdb) && header->rdh_ttl > now &&
+ if (IS_CACHE(rbtdb) && header->rdh_ttl >= now &&
header->type == dns_rdatatype_ns &&
!header_nx && !newheader_nx &&
header->trust >= newheader->trust &&
@@ -6152,7 +6154,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* to be no more than the current NS RRset's TTL. This
* ensures the delegations that are withdrawn are honoured.
*/
- if (IS_CACHE(rbtdb) && header->rdh_ttl > now &&
+ if (IS_CACHE(rbtdb) && header->rdh_ttl >= now &&
header->type == dns_rdatatype_ns &&
!header_nx && !newheader_nx &&
header->trust <= newheader->trust) {
@@ -6160,7 +6162,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
newheader->rdh_ttl = header->rdh_ttl;
}
}
- if (IS_CACHE(rbtdb) && header->rdh_ttl > now &&
+ if (IS_CACHE(rbtdb) && header->rdh_ttl >= now &&
(header->type == dns_rdatatype_a ||
header->type == dns_rdatatype_aaaa ||
header->type == dns_rdatatype_ds ||
@@ -6563,7 +6565,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
cleanup_dead_nodes(rbtdb, rbtnode->locknum);
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
- if (header && header->rdh_ttl <= now - RBTDB_VIRTUAL)
+ if (header && header->rdh_ttl < now - RBTDB_VIRTUAL)
expire_header(rbtdb, header, tree_locked);
/*
@@ -6867,28 +6869,21 @@ static isc_result_t
loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
isc_boolean_t hasnsec)
{
- isc_result_t noderesult, nsecresult;
- dns_rbtnode_t *nsecnode;
-
- noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep);
-
-#ifdef BIND9
- if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL)
- dns_rpz_cidr_addip(rbtdb->rpz_cidr, name);
-#endif
+ isc_result_t noderesult, nsecresult, tmpresult;
+ dns_rbtnode_t *nsecnode = NULL, *node = NULL;
+ noderesult = dns_rbt_addnode(rbtdb->tree, name, &node);
if (!hasnsec)
- return (noderesult);
+ goto done;
if (noderesult == ISC_R_EXISTS) {
/*
* Add a node to the auxiliary NSEC tree for an old node
* just now getting an NSEC record.
*/
- if ((*nodep)->nsec == DNS_RBT_NSEC_HAS_NSEC)
- return (noderesult);
- } else if (noderesult != ISC_R_SUCCESS) {
- return (noderesult);
- }
+ if (node->nsec == DNS_RBT_NSEC_HAS_NSEC)
+ goto done;
+ } else if (noderesult != ISC_R_SUCCESS)
+ goto done;
/*
* Build the auxiliary tree for NSECs as we go.
@@ -6898,12 +6893,11 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
* Add nodes to the auxiliary tree after corresponding nodes have
* been added to the main tree.
*/
- nsecnode = NULL;
nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode);
if (nsecresult == ISC_R_SUCCESS) {
nsecnode->nsec = DNS_RBT_NSEC_NSEC;
- (*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC;
- return (noderesult);
+ node->nsec = DNS_RBT_NSEC_HAS_NSEC;
+ goto done;
}
if (nsecresult == ISC_R_EXISTS) {
@@ -6914,21 +6908,41 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
ISC_LOG_WARNING,
"addnode: NSEC node already exists");
#endif
- (*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC;
- return (noderesult);
+ node->nsec = DNS_RBT_NSEC_HAS_NSEC;
+ goto done;
}
- nsecresult = dns_rbt_deletenode(rbtdb->tree, *nodep, ISC_FALSE);
- if (nsecresult != ISC_R_SUCCESS)
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE,
- ISC_LOG_WARNING,
- "loading_addrdataset: "
- "dns_rbt_deletenode: %s after "
- "dns_rbt_addnode(NSEC): %s",
- isc_result_totext(nsecresult),
- isc_result_totext(noderesult));
+ if (noderesult == ISC_R_SUCCESS) {
+ /*
+ * Remove the node we just added above.
+ */
+ tmpresult = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
+ if (tmpresult != ISC_R_SUCCESS)
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE,
+ ISC_LOG_WARNING,
+ "loading_addrdataset: "
+ "dns_rbt_deletenode: %s after "
+ "dns_rbt_addnode(NSEC): %s",
+ isc_result_totext(tmpresult),
+ isc_result_totext(noderesult));
+
+ }
+
+ /*
+ * Set the error condition to be returned.
+ */
+ noderesult = nsecresult;
+
+ done:
+#ifdef BIND9
+ if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL)
+ dns_rpz_cidr_addip(rbtdb->rpz_cidr, name);
+#endif
+ if (noderesult == ISC_R_SUCCESS || noderesult == ISC_R_EXISTS)
+ *nodep = node;
+
return (noderesult);
}
@@ -7265,7 +7279,8 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
*hash = rbtversion->hash;
if (salt != NULL && salt_length != NULL) {
REQUIRE(*salt_length >= rbtversion->salt_length);
- memcpy(salt, rbtversion->salt, rbtversion->salt_length);
+ memmove(salt, rbtversion->salt,
+ rbtversion->salt_length);
}
if (salt_length != NULL)
*salt_length = rbtversion->salt_length;
@@ -9284,7 +9299,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
isc_rwlocktype_write);
header = isc_heap_element(rbtdb->heaps[locknum], 1);
- if (header && header->rdh_ttl <= now - RBTDB_VIRTUAL) {
+ if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) {
expire_header(rbtdb, header, tree_locked);
purgecount--;
}