diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c
index 025f5703ff..496cfbfeee 100644
--- a/bin/dnssec/dnssec-signzone.c
+++ b/bin/dnssec/dnssec-signzone.c
@@ -3826,8 +3826,7 @@ main(int argc, char *argv[]) {
bool answer;
hash_length = dns_nsec3_hashlength(dns_hash_sha1);
- hashlist_init(&hashlist,
- dns_db_nodecount(gdb, dns_dbtree_main) * 2,
+ hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2,
hash_length);
result = dns_nsec_nseconly(gdb, gversion, NULL, &answer);
if (result == ISC_R_NOTFOUND) {
diff --git a/bin/named/server.c b/bin/named/server.c
index 8448b3d715..3ae0d826ed 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -14824,7 +14824,7 @@ named_server_zonestatus(named_server_t *server, isc_lex_t *lex,
}
/* Database node count */
- nodes = dns_db_nodecount(hasraw ? rawdb : db, dns_dbtree_main);
+ nodes = dns_db_nodecount(hasraw ? rawdb : db);
snprintf(nodebuf, sizeof(nodebuf), "%u", nodes);
/* Security */
diff --git a/bin/tests/system/dyndb/driver/db.c b/bin/tests/system/dyndb/driver/db.c
index f23e0793c8..c108bc3183 100644
--- a/bin/tests/system/dyndb/driver/db.c
+++ b/bin/tests/system/dyndb/driver/db.c
@@ -249,12 +249,12 @@ issecure(dns_db_t *db) {
}
static unsigned int
-nodecount(dns_db_t *db, dns_dbtree_t tree) {
+nodecount(dns_db_t *db) {
sampledb_t *sampledb = (sampledb_t *)db;
REQUIRE(VALID_SAMPLEDB(sampledb));
- return dns_db_nodecount(sampledb->db, tree);
+ return dns_db_nodecount(sampledb->db);
}
static isc_result_t
diff --git a/bin/tests/system/synthfromdnssec/tests.sh b/bin/tests/system/synthfromdnssec/tests.sh
index b2427ec09d..0ce3046f9f 100644
--- a/bin/tests/system/synthfromdnssec/tests.sh
+++ b/bin/tests/system/synthfromdnssec/tests.sh
@@ -683,21 +683,6 @@ for ns in 2 4 5 6; do
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
- echo_i "check 'rndc stats' output for 'cache NSEC auxiliary database nodes' (synth-from-dnssec ${description};) ($n)"
- ret=0
- # 2 views, _bind should always be '0 cache NSEC auxiliary database nodes'
- count=$(grep "cache NSEC auxiliary database nodes" ns${ns}/named.stats | wc -l)
- test $count = 2 || ret=1
- zero=$(grep "0 cache NSEC auxiliary database nodes" ns${ns}/named.stats | wc -l)
- if [ ${ad} = yes ]; then
- test $zero = 1 || ret=1
- else
- test $zero = 2 || ret=1
- fi
- n=$((n + 1))
- if [ $ret != 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
for synthesized in NXDOMAIN no-data wildcard; do
case $synthesized in
NXDOMAIN) count=2 ;;
@@ -740,21 +725,6 @@ for ns in 2 4 5 6; do
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
- echo_i "check XML for 'CacheNSECNodes' with (synth-from-dnssec ${description};) ($n)"
- ret=0
- counter=$(sed -n 's;.*.*\([0-9]*\).*0<" | wc -l)
- if [ ${ad} = yes ]; then
- test $zero = 0 || ret=1
- else
- test $zero = 1 || ret=1
- fi
- n=$((n + 1))
- if [ $ret != 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
for synthesized in SynthNXDOMAIN SynthNODATA SynthWILDCARD; do
case $synthesized in
SynthNXDOMAIN) count=2 ;;
@@ -800,20 +770,6 @@ for ns in 2 4 5 6; do
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
- echo_i "check JSON for 'CacheNSECNodes' with (synth-from-dnssec ${description};) ($n)"
- ret=0
- count=$(grep '"CacheNSECNodes":' $json | wc -l)
- test $count = 2 || ret=1
- zero=$(grep '"CacheNSECNodes":0' $json | wc -l)
- if [ ${ad} = yes ]; then
- test $zero = 1 || ret=1
- else
- test $zero = 2 || ret=1
- fi
- n=$((n + 1))
- if [ $ret != 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
for synthesized in SynthNXDOMAIN SynthNODATA SynthWILDCARD; do
case $synthesized in
SynthNXDOMAIN) count=2 ;;
diff --git a/lib/dns/cache.c b/lib/dns/cache.c
index 69267ea4d4..0fbce6c372 100644
--- a/lib/dns/cache.c
+++ b/lib/dns/cache.c
@@ -618,10 +618,8 @@ dns_cache_dumpstats(dns_cache_t *cache, FILE *fp) {
fprintf(fp, "%20" PRIu64 " %s\n",
values[dns_cachestatscounter_coveringnsec],
"covering nsec returned");
- fprintf(fp, "%20u %s\n", dns_db_nodecount(cache->db, dns_dbtree_main),
+ fprintf(fp, "%20u %s\n", dns_db_nodecount(cache->db),
"cache database nodes");
- fprintf(fp, "%20u %s\n", dns_db_nodecount(cache->db, dns_dbtree_nsec),
- "cache NSEC auxiliary database nodes");
fprintf(fp, "%20" PRIu64 " %s\n", (uint64_t)isc_mem_inuse(cache->tmctx),
"cache tree memory in use");
@@ -677,10 +675,7 @@ dns_cache_renderxml(dns_cache_t *cache, void *writer0) {
TRY0(renderstat("CoveringNSEC",
values[dns_cachestatscounter_coveringnsec], writer));
- TRY0(renderstat("CacheNodes",
- dns_db_nodecount(cache->db, dns_dbtree_main), writer));
- TRY0(renderstat("CacheNSECNodes",
- dns_db_nodecount(cache->db, dns_dbtree_nsec), writer));
+ TRY0(renderstat("CacheNodes", dns_db_nodecount(cache->db), writer));
TRY0(renderstat("TreeMemInUse", isc_mem_inuse(cache->tmctx), writer));
@@ -740,16 +735,10 @@ dns_cache_renderjson(dns_cache_t *cache, void *cstats0) {
CHECKMEM(obj);
json_object_object_add(cstats, "CoveringNSEC", obj);
- obj = json_object_new_int64(
- dns_db_nodecount(cache->db, dns_dbtree_main));
+ obj = json_object_new_int64(dns_db_nodecount(cache->db));
CHECKMEM(obj);
json_object_object_add(cstats, "CacheNodes", obj);
- obj = json_object_new_int64(
- dns_db_nodecount(cache->db, dns_dbtree_nsec));
- CHECKMEM(obj);
- json_object_object_add(cstats, "CacheNSECNodes", obj);
-
obj = json_object_new_int64(isc_mem_inuse(cache->tmctx));
CHECKMEM(obj);
json_object_object_add(cstats, "TreeMemInUse", obj);
diff --git a/lib/dns/db.c b/lib/dns/db.c
index 9200352024..2ab84644c9 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -734,11 +734,11 @@ freenode:
}
unsigned int
-dns_db_nodecount(dns_db_t *db, dns_dbtree_t tree) {
+dns_db_nodecount(dns_db_t *db) {
REQUIRE(DNS_DB_VALID(db));
if (db->methods->nodecount != NULL) {
- return (db->methods->nodecount)(db, tree);
+ return (db->methods->nodecount)(db);
}
return 0;
}
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index 7ebeeb2253..8f0de40c5c 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -127,7 +127,7 @@ typedef struct dns_db_methods {
dns_rdatatype_t type,
dns_rdatatype_t covers DNS__DB_FLARG);
bool (*issecure)(dns_db_t *db);
- unsigned int (*nodecount)(dns_db_t *db, dns_dbtree_t);
+ unsigned int (*nodecount)(dns_db_t *db);
isc_result_t (*getoriginnode)(dns_db_t *db,
dns_dbnode_t **nodep DNS__DB_FLARG);
isc_result_t (*getnsec3parameters)(dns_db_t *db,
@@ -1366,9 +1366,9 @@ dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, uint32_t *serialp);
*/
unsigned int
-dns_db_nodecount(dns_db_t *db, dns_dbtree_t tree);
+dns_db_nodecount(dns_db_t *db);
/*%<
- * Count the number of nodes in 'db' or its auxiliary trees.
+ * Count the number of nodes in 'db'.
*
* Requires:
*
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index 931910f9a8..ba1fd98a3d 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -202,12 +202,6 @@ typedef enum {
dns_dbtype_stub = 3
} dns_dbtype_t;
-typedef enum {
- dns_dbtree_main = 0,
- dns_dbtree_nsec = 1,
- dns_dbtree_nsec3 = 2
-} dns_dbtree_t;
-
typedef enum {
dns_checkdstype_no = 0,
dns_checkdstype_yes = 1,
diff --git a/lib/dns/qp.c b/lib/dns/qp.c
index d27726d74f..625e4675b3 100644
--- a/lib/dns/qp.c
+++ b/lib/dns/qp.c
@@ -1494,6 +1494,8 @@ dns_qpsnap_destroy(dns_qpmulti_t *multi, dns_qpsnap_t **qpsp) {
void
dns_qp_create(isc_mem_t *mctx, const dns_qpmethods_t *methods, void *uctx,
dns_qp_t **qptp) {
+ REQUIRE(mctx != NULL);
+ REQUIRE(methods != NULL);
REQUIRE(qptp != NULL && *qptp == NULL);
dns_qp_t *qp = isc_mem_get(mctx, sizeof(*qp));
diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c
index 06d9a91b04..efc987c12c 100644
--- a/lib/dns/qpcache.c
+++ b/lib/dns/qpcache.c
@@ -252,7 +252,6 @@ struct qpcache {
/* Locked by tree_lock. */
dns_qp_t *tree;
- dns_qp_t *nsec;
isc_mem_t *hmctx; /* Memory context for the heaps */
@@ -407,12 +406,11 @@ static dns_dbiteratormethods_t dbiterator_methods = {
};
/*
- * Note that the QP cache database only needs a single QP iterator, because
- * unlike the QP zone database, NSEC3 records are cached in the main tree.
- *
- * If we ever implement synth-from-dnssec using NSEC3 records, we'll need
- * to have a separate tree for NSEC3 records, and to copy in the more complex
- * iterator implementation from qpzone.c.
+ * In the cache, NSEC3 records are currently stored in the NORMAL
+ * namespace. If we ever implement synth-from-dnssec using NSEC3 records,
+ * they'll need be moved into the NSEC3 namespace for efficiency, and
+ * the iterator implementation will need to be more complex, as in
+ * qpzone.
*/
typedef struct qpc_dbit {
dns_dbiterator_t common;
@@ -629,7 +627,7 @@ delete_node(qpcache_t *qpdb, qpcnode_t *node) {
* Delete the corresponding node from the auxiliary NSEC
* tree before deleting from the main tree.
*/
- result = dns_qp_deletename(qpdb->nsec, &node->name,
+ result = dns_qp_deletename(qpdb->tree, &node->name,
DNS_DBNAMESPACE_NSEC, NULL,
NULL);
if (result != ISC_R_SUCCESS) {
@@ -645,7 +643,7 @@ delete_node(qpcache_t *qpdb, qpcnode_t *node) {
node->nspace, NULL, NULL);
break;
case DNS_DBNAMESPACE_NSEC:
- result = dns_qp_deletename(qpdb->nsec, &node->name,
+ result = dns_qp_deletename(qpdb->tree, &node->name,
node->nspace, NULL, NULL);
break;
}
@@ -1427,9 +1425,9 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name,
dns_slabheader_t *found = NULL, *foundsig = NULL;
/*
- * Look for the node in the auxilary tree.
+ * Look for the node in the auxiliary NSEC namespace.
*/
- result = dns_qp_lookup(search->qpdb->nsec, name, DNS_DBNAMESPACE_NSEC,
+ result = dns_qp_lookup(search->qpdb->tree, name, DNS_DBNAMESPACE_NSEC,
NULL, &iter, NULL, (void **)&node, NULL);
/*
* When DNS_R_PARTIALMATCH or ISC_R_NOTFOUND is returned from
@@ -1453,7 +1451,7 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name,
}
/*
- * Lookup the predecessor in the main tree.
+ * Lookup the predecessor in the normal namespace.
*/
node = NULL;
result = dns_qp_getname(search->qpdb->tree, predecessor,
@@ -2269,23 +2267,8 @@ static void
qpcache__destroy(qpcache_t *qpdb) {
unsigned int i;
char buf[DNS_NAME_FORMATSIZE];
- dns_qp_t **treep = NULL;
- for (;;) {
- /*
- * pick the next tree to (start to) destroy
- */
- treep = &qpdb->tree;
- if (*treep == NULL) {
- treep = &qpdb->nsec;
- if (*treep == NULL) {
- break;
- }
- }
-
- dns_qp_destroy(treep);
- INSIST(*treep == NULL);
- }
+ dns_qp_destroy(&qpdb->tree);
if (dns_name_dynamic(&qpdb->common.origin)) {
dns_name_format(&qpdb->common.origin, buf, sizeof(buf));
@@ -3147,13 +3130,13 @@ qpcache_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
if (newnsec && !qpnode->havensec) {
qpcnode_t *nsecnode = NULL;
- result = dns_qp_getname(qpdb->nsec, name, DNS_DBNAMESPACE_NSEC,
+ result = dns_qp_getname(qpdb->tree, name, DNS_DBNAMESPACE_NSEC,
(void **)&nsecnode, NULL);
if (result != ISC_R_SUCCESS) {
INSIST(nsecnode == NULL);
nsecnode = new_qpcnode(qpdb, name,
DNS_DBNAMESPACE_NSEC);
- result = dns_qp_insert(qpdb->nsec, nsecnode, 0);
+ result = dns_qp_insert(qpdb->tree, nsecnode, 0);
INSIST(result == ISC_R_SUCCESS);
qpcnode_detach(&nsecnode);
}
@@ -3235,7 +3218,7 @@ qpcache_deleterdataset(dns_db_t *db, dns_dbnode_t *node,
}
static unsigned int
-nodecount(dns_db_t *db, dns_dbtree_t tree) {
+nodecount(dns_db_t *db) {
qpcache_t *qpdb = (qpcache_t *)db;
dns_qp_memusage_t mu;
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
@@ -3243,16 +3226,7 @@ nodecount(dns_db_t *db, dns_dbtree_t tree) {
REQUIRE(VALID_QPDB(qpdb));
TREE_RDLOCK(&qpdb->tree_lock, &tlocktype);
- switch (tree) {
- case dns_dbtree_main:
- mu = dns_qp_memusage(qpdb->tree);
- break;
- case dns_dbtree_nsec:
- mu = dns_qp_memusage(qpdb->nsec);
- break;
- default:
- UNREACHABLE();
- }
+ mu = dns_qp_memusage(qpdb->tree);
TREE_UNLOCK(&qpdb->tree_lock, &tlocktype);
return mu.leaves;
@@ -3324,10 +3298,9 @@ dns__qpcache_create(isc_mem_t *mctx, const dns_name_t *origin,
dns_name_dup(origin, mctx, &qpdb->common.origin);
/*
- * Make the qp tries.
+ * Make the qp trie.
*/
dns_qp_create(mctx, &qpmethods, qpdb, &qpdb->tree);
- dns_qp_create(mctx, &qpmethods, qpdb, &qpdb->nsec);
qpdb->common.magic = DNS_DB_MAGIC;
qpdb->common.impmagic = QPDB_MAGIC;
@@ -3520,9 +3493,9 @@ resume_iteration(qpc_dbit_t *qpdbiter, bool continuing) {
TREE_RDLOCK(&qpdb->tree_lock, &qpdbiter->tree_locked);
/*
- * If we're being called from dbiterator_next or _prev,
- * then we may need to reinitialize the iterator to the current
- * name. The tree could have changed while it was unlocked,
+ * If we're being called from dbiterator_next, we may need
+ * to reinitialize the iterator to the current name. The
+ * tree could have changed while it was unlocked, which
* would make the iterator traversal inconsistent.
*
* As long as the iterator is holding a reference to
@@ -3586,11 +3559,17 @@ dbiterator_first(dns_dbiterator_t *iterator DNS__DB_FLARG) {
result = dns_qpiter_next(&qpdbiter->iter, NULL,
(void **)&qpdbiter->node, NULL);
- if (result == ISC_R_SUCCESS) {
+ if (result == ISC_R_SUCCESS &&
+ qpdbiter->node->nspace == DNS_DBNAMESPACE_NORMAL)
+ {
dns_name_copy(&qpdbiter->node->name, qpdbiter->name);
reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
+ } else if (result == ISC_R_SUCCESS) {
+ result = ISC_R_NOMORE;
+ qpdbiter->node = NULL;
} else {
- INSIST(result == ISC_R_NOMORE); /* The tree is empty. */
+ /* The tree is empty. */
+ INSIST(result == ISC_R_NOMORE);
qpdbiter->node = NULL;
}
@@ -3604,39 +3583,8 @@ dbiterator_first(dns_dbiterator_t *iterator DNS__DB_FLARG) {
}
static isc_result_t
-dbiterator_last(dns_dbiterator_t *iterator DNS__DB_FLARG) {
- isc_result_t result;
- qpc_dbit_t *qpdbiter = (qpc_dbit_t *)iterator;
- qpcache_t *qpdb = (qpcache_t *)iterator->db;
-
- if (qpdbiter->result != ISC_R_SUCCESS &&
- qpdbiter->result != ISC_R_NOTFOUND &&
- qpdbiter->result != DNS_R_PARTIALMATCH &&
- qpdbiter->result != ISC_R_NOMORE)
- {
- return qpdbiter->result;
- }
-
- if (qpdbiter->paused) {
- resume_iteration(qpdbiter, false);
- }
-
- dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
-
- dns_qpiter_init(qpdb->tree, &qpdbiter->iter);
- result = dns_qpiter_prev(&qpdbiter->iter, NULL,
- (void **)&qpdbiter->node, NULL);
-
- if (result == ISC_R_SUCCESS) {
- dns_name_copy(&qpdbiter->node->name, qpdbiter->name);
- reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- } else {
- INSIST(result == ISC_R_NOMORE); /* The tree is empty. */
- qpdbiter->node = NULL;
- }
-
- qpdbiter->result = result;
- return result;
+dbiterator_last(dns_dbiterator_t *iterator ISC_ATTR_UNUSED DNS__DB_FLARG) {
+ return ISC_R_NOTIMPLEMENTED;
}
static isc_result_t
@@ -3677,35 +3625,8 @@ dbiterator_seek(dns_dbiterator_t *iterator,
}
static isc_result_t
-dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG) {
- isc_result_t result;
- qpc_dbit_t *qpdbiter = (qpc_dbit_t *)iterator;
-
- REQUIRE(qpdbiter->node != NULL);
-
- if (qpdbiter->result != ISC_R_SUCCESS) {
- return qpdbiter->result;
- }
-
- if (qpdbiter->paused) {
- resume_iteration(qpdbiter, true);
- }
-
- dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
-
- result = dns_qpiter_prev(&qpdbiter->iter, NULL,
- (void **)&qpdbiter->node, NULL);
-
- if (result == ISC_R_SUCCESS) {
- dns_name_copy(&qpdbiter->node->name, qpdbiter->name);
- reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- } else {
- INSIST(result == ISC_R_NOMORE);
- qpdbiter->node = NULL;
- }
-
- qpdbiter->result = result;
- return result;
+dbiterator_prev(dns_dbiterator_t *iterator ISC_ATTR_UNUSED DNS__DB_FLARG) {
+ return ISC_R_NOTIMPLEMENTED;
}
static isc_result_t
@@ -3728,9 +3649,14 @@ dbiterator_next(dns_dbiterator_t *iterator DNS__DB_FLARG) {
result = dns_qpiter_next(&qpdbiter->iter, NULL,
(void **)&qpdbiter->node, NULL);
- if (result == ISC_R_SUCCESS) {
+ if (result == ISC_R_SUCCESS &&
+ qpdbiter->node->nspace == DNS_DBNAMESPACE_NORMAL)
+ {
dns_name_copy(&qpdbiter->node->name, qpdbiter->name);
reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
+ } else if (result == ISC_R_SUCCESS) {
+ result = ISC_R_NOMORE;
+ qpdbiter->node = NULL;
} else {
INSIST(result == ISC_R_NOMORE);
qpdbiter->node = NULL;
diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c
index e081f15c26..9eaf4f28e7 100644
--- a/lib/dns/qpzone.c
+++ b/lib/dns/qpzone.c
@@ -2880,7 +2880,7 @@ find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname,
}
/*
- * Find node of the NSEC/NSEC3 record that is 'name'.
+ * Find node of the NSEC/NSEC3 record preceding 'name'.
*/
static isc_result_t
previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
@@ -2903,8 +2903,8 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
for (;;) {
if (*firstp) {
/*
- * Construct the name of the second node to check.
- * It is the first node sought in the NSEC tree.
+ * This is the first attempt to find 'name' in the
+ * NSEC namespace.
*/
*firstp = false;
result = dns_qp_lookup(&qpr, name, DNS_DBNAMESPACE_NSEC,
@@ -2912,27 +2912,31 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
INSIST(result != ISC_R_NOTFOUND);
if (result == ISC_R_SUCCESS) {
/*
- * Since this was the first loop, finding the
- * name in the NSEC tree implies that the first
- * node checked in the main tree had an
- * unacceptable NSEC record.
- * Try the previous node in the NSEC tree.
+ * If we find an exact match in the NSEC
+ * namespace on our first attempt, it
+ * implies that the corresponding node in
+ * the normal namespace had an unacceptable
+ * NSEC record; we want the previous node
+ * in the NSEC tree.
*/
result = dns_qpiter_prev(nit, name, NULL, NULL);
} else if (result == DNS_R_PARTIALMATCH) {
/*
- * The iterator is already where we want it.
+ * This was a partial match, so the
+ * iterator is already at the previous
+ * node in the NSEC namespace, which is
+ * what we want.
*/
dns_qpiter_current(nit, name, NULL, NULL);
result = ISC_R_SUCCESS;
}
} else {
/*
- * This is a second or later trip through the auxiliary
- * tree for the name of a third or earlier NSEC node in
- * the main tree. Previous trips through the NSEC tree
- * must have found nodes in the main tree with NSEC
- * records. Perhaps they lacked signature records.
+ * We've taken at least two steps back through the
+ * NSEC namespace. The previous steps must have
+ * found nodes with NSEC records, but they didn't
+ * work; perhaps they lacked signature records.
+ * Keep searching.
*/
result = dns_qpiter_prev(nit, name, NULL, NULL);
}
@@ -2949,9 +2953,10 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
}
/*
- * There should always be a node in the main tree with the
- * same name as the node in the auxiliary NSEC tree, except for
- * nodes in the auxiliary tree that are awaiting deletion.
+ * There should always be a node in the normal namespace
+ * with the same name as the node in the NSEC namespace,
+ * except when nodes in the NSEC namespace are awaiting
+ * deletion.
*/
if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) {
isc_log_write(DNS_LOGCATEGORY_DATABASE,
@@ -2968,8 +2973,8 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
}
/*
- * Find the NSEC/NSEC3 which is or before the current point on the
- * search chain. For NSEC3 records only NSEC3 records that match the
+ * Find the NSEC/NSEC3 which is at or before the name being sought.
+ * For NSEC3 records only NSEC3 records that match the
* current NSEC3PARAM record are considered.
*/
static isc_result_t
@@ -2992,8 +2997,12 @@ find_closest_nsec(qpz_search_t *search, dns_dbnode_t **nodep,
bool need_sig = secure;
/*
- * Use the auxiliary tree only starting with the second node in the
- * hope that the original node will be right much of the time.
+ * When a lookup is unsuccessful, the QP iterator will already
+ * be pointing at the node preceding the searched-for name in
+ * the normal namespace. We'll check there first, assuming it will
+ * be right much of the time. If we don't find an NSEC there,
+ * then we start using the auxiliary NSEC namespace to find
+ * the next predecessor.
*/
result = dns_qpiter_current(&search->iter, name, (void **)&node, NULL);
if (result != ISC_R_SUCCESS) {
@@ -3858,12 +3867,10 @@ qpzone_detachnode(dns_dbnode_t **nodep DNS__DB_FLARG) {
}
static unsigned int
-nodecount(dns_db_t *db, dns_dbtree_t tree ISC_ATTR_UNUSED) {
- qpzonedb_t *qpdb = NULL;
+nodecount(dns_db_t *db) {
+ qpzonedb_t *qpdb = qpdb = (qpzonedb_t *)db;
dns_qp_memusage_t mu;
- qpdb = (qpzonedb_t *)db;
-
REQUIRE(VALID_QPZONE(qpdb));
mu = dns_qpmulti_memusage(qpdb->tree);
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index e12ecae892..68685dcad2 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -5413,8 +5413,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
}
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
- "number of nodes in database: %u",
- dns_db_nodecount(db, dns_dbtree_main));
+ "number of nodes in database: %u", dns_db_nodecount(db));
if (result == DNS_R_SEENINCLUDE) {
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
diff --git a/tests/dns/qp_test.c b/tests/dns/qp_test.c
index e93d20040d..e6729056e9 100644
--- a/tests/dns/qp_test.c
+++ b/tests/dns/qp_test.c
@@ -40,6 +40,10 @@
#include
#include
+#define DONT_REORDER
+
+#include "../qp.c"
+
bool verbose = false;
ISC_RUN_TEST_IMPL(qpkey_name) {
@@ -2059,7 +2063,39 @@ ISC_RUN_TEST_IMPL(qpkey_delete) {
dns_qp_destroy(&qp);
}
+ISC_RUN_TEST_IMPL(qp_basics) {
+ dns_qp_t *qp = NULL;
+ expect_assert_failure(
+ dns_qp_create(isc_g_mctx, &string_methods, NULL, NULL));
+ expect_assert_failure(dns_qp_create(NULL, &string_methods, NULL, &qp));
+ expect_assert_failure(dns_qp_create(isc_g_mctx, NULL, NULL, &qp));
+
+ qp = NULL;
+ dns_qp_create(isc_g_mctx, &string_methods, NULL, &qp);
+ assert_non_null(qp);
+
+ dns_qp_destroy(&qp);
+ assert_null(qp);
+}
+
+ISC_RUN_TEST_IMPL(qp_memusage) {
+ dns_qp_t *qp = NULL;
+ dns_qp_memusage_t mu;
+
+ dns_qp_create(isc_g_mctx, &string_methods, NULL, &qp);
+ assert_non_null(qp);
+
+ mu = dns_qp_memusage(qp);
+ assert_int_equal(mu.leaves, 0);
+ assert_int_equal(mu.used, 0);
+
+ dns_qp_destroy(&qp);
+ assert_null(qp);
+}
+
ISC_TEST_LIST_START
+ISC_TEST_ENTRY(qp_basics)
+ISC_TEST_ENTRY(qp_memusage)
ISC_TEST_ENTRY(qpkey_name)
ISC_TEST_ENTRY(qpkey_sort)
ISC_TEST_ENTRY(qpiter)