dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
- unsigned int i;
isc_result_t result = ISC_R_NOTFOUND;
- dns_name_t name;
dns_qpdb_t *qpdb = NULL;
- bool done;
/*
* Caller must be holding the tree lock.
*/
qpdb = search->qpdb;
- i = search->chain.level_matches;
- done = false;
- do {
+
+ for (int i = dns_qpchain_length(&search->chain) - 1; i >= 0; i--) {
dns_slabheader_t *header = NULL;
dns_slabheader_t *header_prev = NULL, *header_next = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
- isc_rwlock_t *lock = &qpdb->node_locks[node->locknum].lock;
+ isc_rwlock_t *lock = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+ dns_qpchain_node(&search->chain, i, NULL, (void **)&node, NULL);
+ lock = &qpdb->node_locks[node->locknum].lock;
+
NODE_RDLOCK(lock, &nlocktype);
/*
if (found != NULL) {
/*
* If we have to set foundname, we do it before
- * anything else. If we were to set foundname after
- * we had set nodep or bound the rdataset, then we'd
- * have to undo that work if dns_name_concatenate()
- * failed. By setting foundname first, there's
- * nothing to undo if we have trouble.
+ * anything else.
*/
if (foundname != NULL) {
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(node, &name);
- dns_name_copy(&name, foundname);
- while (i > 0) {
- dns_rbtnode_t *level_node =
- search->chain.levels[--i];
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(level_node, &name);
- result = dns_name_concatenate(
- foundname, &name, foundname,
- NULL);
- if (result != ISC_R_SUCCESS) {
- if (nodep != NULL) {
- *nodep = NULL;
- }
- goto node_exit;
- }
- }
+ dns_name_copy(node->name, foundname);
}
result = DNS_R_DELEGATION;
if (nodep != NULL) {
}
}
- node_exit:
NODE_UNLOCK(lock, &nlocktype);
- if (found == NULL && i > 0) {
- i--;
- node = search->chain.levels[i];
- } else {
- done = true;
+ if (found != NULL) {
+ break;
}
- } while (!done);
+ }
return (result);
}
dns_dbnode_t **nodep, isc_stdtime_t now,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
- dns_fixedname_t fprefix, forigin, ftarget, fixed;
- dns_name_t *prefix = NULL, *origin = NULL;
- dns_name_t *target = NULL, *fname = NULL;
+ dns_fixedname_t fpredecessor, fixed;
+ dns_name_t *predecessor = NULL, *fname = NULL;
dns_rbtnode_t *node = NULL;
- dns_rbtnodechain_t chain;
+ dns_qpiter_t iter;
isc_result_t result;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *lock = NULL;
/*
* Look for the node in the auxilary tree.
*/
- dns_rbtnodechain_init(&chain);
- target = dns_fixedname_initname(&ftarget);
- result = dns_qp_lookup(search->qpdb->nsec, name, target, NULL, &chain,
+ result = dns_qp_lookup(search->qpdb->nsec, name, NULL, &iter, NULL,
(void **)&node, NULL);
if (result != DNS_R_PARTIALMATCH) {
- dns_rbtnodechain_reset(&chain);
return (ISC_R_NOTFOUND);
}
- prefix = dns_fixedname_initname(&fprefix);
- origin = dns_fixedname_initname(&forigin);
- target = dns_fixedname_initname(&ftarget);
fname = dns_fixedname_initname(&fixed);
-
+ predecessor = dns_fixedname_initname(&fpredecessor);
matchtype = DNS_TYPEPAIR_VALUE(dns_rdatatype_nsec, 0);
sigmatchtype = DNS_SIGTYPE(dns_rdatatype_nsec);
/*
- * Extract predecessor from chain.
+ * Extract predecessor from iterator.
*/
- result = dns_rbtnodechain_current(&chain, prefix, origin, NULL);
- dns_rbtnodechain_reset(&chain);
+ result = dns_qpiter_current(&iter, predecessor, NULL, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
return (ISC_R_NOTFOUND);
}
- result = dns_name_concatenate(prefix, origin, target, NULL);
- if (result != ISC_R_SUCCESS) {
- return (ISC_R_NOTFOUND);
- }
-
/*
* Lookup the predecessor in the main tree.
*/
node = NULL;
- result = dns_qp_lookup(search->qpdb->tree, target, fname, NULL, NULL,
- (void **)&node, NULL);
+ result = dns_qp_lookup(search->qpdb->tree, predecessor, fname, NULL,
+ NULL, (void **)&node, NULL);
if (result != ISC_R_SUCCESS) {
return (ISC_R_NOTFOUND);
}
.now = now,
};
dns_fixedname_init(&search.zonecut_name);
- dns_rbtnodechain_init(&search.chain);
TREE_RDLOCK(&search.qpdb->tree_lock, &tlocktype);
INSIST(tlocktype == isc_rwlocktype_none);
}
- dns_rbtnodechain_reset(&search.chain);
-
update_cachestats(search.qpdb, result);
return (result);
}
.now = now,
};
dns_fixedname_init(&search.zonecut_name);
- dns_rbtnodechain_init(&search.chain);
if (dcnull) {
dcname = foundname;
INSIST(!search.need_cleanup);
- dns_rbtnodechain_reset(&search.chain);
-
if (result == DNS_R_DELEGATION) {
result = ISC_R_SUCCESS;
}
* Return true if we found a predecessor or successor.
*/
static bool
-step(qpdb_search_t *search, dns_rbtnodechain_t *chain, direction_t direction,
+step(qpdb_search_t *search, dns_qpiter_t *iter, direction_t direction,
dns_name_t *nextname) {
- dns_fixedname_t forigin;
- dns_name_t *origin = NULL;
- dns_name_t prefix;
+ dns_fixedname_t fnodename;
+ dns_name_t *nodename = dns_fixedname_initname(&fnodename);
dns_qpdb_t *qpdb = NULL;
dns_rbtnode_t *node = NULL;
isc_result_t result = ISC_R_SUCCESS;
qpdb = search->qpdb;
- dns_name_init(&prefix, NULL);
- origin = dns_fixedname_initname(&forigin);
+ result = dns_qpiter_current(iter, nodename, (void **)&node, NULL);
while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
- node = NULL;
- result = dns_rbtnodechain_current(chain, &prefix, origin,
- &node);
- if (result != ISC_R_SUCCESS) {
- break;
- }
+
NODE_RDLOCK(&(qpdb->node_locks[node->locknum].lock),
&nlocktype);
for (header = node->data; header != NULL; header = header->next)
if (header != NULL) {
break;
}
+
if (direction == FORWARD) {
- result = dns_rbtnodechain_next(chain, NULL, NULL);
+ result = dns_qpiter_next(iter, nodename, (void **)&node,
+ NULL);
} else {
- result = dns_rbtnodechain_prev(chain, NULL, NULL);
+ result = dns_qpiter_prev(iter, nodename, (void **)&node,
+ NULL);
}
};
if (result == ISC_R_SUCCESS) {
- result = dns_name_concatenate(&prefix, origin, nextname, NULL);
- }
- if (result == ISC_R_SUCCESS) {
+ if (nextname != NULL) {
+ dns_name_copy(nodename, nextname);
+ }
return (true);
}
return (false);
* of the database.
*/
static bool
-activeempty(qpdb_search_t *search, dns_rbtnodechain_t *chain,
+activeempty(qpdb_search_t *search, dns_qpiter_t *iter,
const dns_name_t *current) {
isc_result_t result;
dns_fixedname_t fnext;
dns_name_t *next = dns_fixedname_initname(&fnext);
- result = dns_rbtnodechain_next(chain, NULL, NULL);
+ result = dns_qpiter_next(iter, NULL, NULL, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
return (false);
}
- return (step(search, chain, FORWARD, next) &&
+ return (step(search, iter, FORWARD, next) &&
dns_name_issubdomain(next, current));
}
dns_name_t name;
dns_name_t rname;
dns_name_t tname;
- dns_rbtnodechain_t chain;
+ dns_qpiter_t iter;
bool check_next = false;
bool check_prev = false;
unsigned int n;
* need to find out if there's an empty nonterminal node
* between the wildcard level and the qname.
*
- * search->chain should now be pointing at the predecessor
+ * search->iter should now be pointing at the predecessor
* of the searched-for name. We are using a local copy of the
- * chain so as not to change the state of search->chain.
+ * iterator so as not to change the state of search->iter.
* step() will walk backward until we find a predecessor with
* data.
*/
- chain = search->chain;
- check_prev = step(search, &chain, BACK, prev);
+ iter = search->iter;
+ check_prev = step(search, &iter, BACK, prev);
- /* Now reset the chain and look for a successor with data. */
- chain = search->chain;
- result = dns_rbtnodechain_next(&chain, NULL, NULL);
+ /* Now reset the iterator and look for a successor with data. */
+ iter = search->iter;
+ result = dns_qpiter_next(&iter, NULL, NULL, NULL);
if (result == ISC_R_SUCCESS) {
- check_next = step(search, &chain, FORWARD, next);
+ check_next = step(search, &iter, FORWARD, next);
}
if (!check_prev && !check_next) {
static isc_result_t
find_wildcard(qpdb_search_t *search, dns_rbtnode_t **nodep,
const dns_name_t *qname) {
- unsigned int i, j;
- dns_rbtnode_t *node = NULL, *level_node = NULL;
dns_slabheader_t *header = NULL;
isc_result_t result = ISC_R_NOTFOUND;
dns_qpdb_t *qpdb = NULL;
- bool done, wild, active;
+ bool wild, active;
/*
* Caller must be holding the tree lock and MUST NOT be holding
*/
qpdb = search->qpdb;
- i = search->chain.level_matches;
- done = false;
- node = *nodep;
- do {
- isc_rwlock_t *lock = &qpdb->node_locks[node->locknum].lock;
+ for (int i = dns_qpchain_length(&search->chain) - 1; i >= 0; i--) {
+ dns_rbtnode_t *node = NULL;
+ isc_rwlock_t *lock = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
- NODE_RDLOCK(lock, &nlocktype);
+ dns_qpchain_node(&search->chain, i, NULL, (void **)&node, NULL);
+ lock = &qpdb->node_locks[node->locknum].lock;
+
+ NODE_RDLOCK(lock, &nlocktype);
/*
* First we try to figure out if this node is active in
* the search's version. We do this now, even though we
break;
}
}
- if (header != NULL) {
- active = true;
- } else {
- active = false;
- }
-
- if (node->wild) {
- wild = true;
- } else {
- wild = false;
- }
-
+ active = (header != NULL);
+ wild = node->wild;
NODE_UNLOCK(lock, &nlocktype);
if (wild) {
- dns_name_t *wname = NULL;
- dns_fixedname_t fwname;
dns_rbtnode_t *wnode = NULL;
- dns_qpiter_t wchain;
+ dns_fixedname_t fwname;
+ dns_name_t *wname = NULL;
+ dns_qpiter_t witer;
/*
* Construct the wildcard name for this level.
*/
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(node, &name);
wname = dns_fixedname_initname(&fwname);
- result = dns_name_concatenate(dns_wildcardname, &name,
- wname, NULL);
- j = i;
- while (result == ISC_R_SUCCESS && j != 0) {
- j--;
- level_node = search->chain.levels[j];
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(level_node, &name);
- result = dns_name_concatenate(wname, &name,
- wname, NULL);
- }
+ result = dns_name_concatenate(dns_wildcardname,
+ node->name, wname, NULL);
if (result != ISC_R_SUCCESS) {
break;
}
wnode = NULL;
- dns_rbtnodechain_init(&wchain);
-
- result = dns_qp_lookup(qpdb->tree, wname, NULL, NULL,
- &wchain, (void **)&wnode, NULL);
+ result = dns_qp_lookup(qpdb->tree, wname, NULL, &witer,
+ NULL, (void **)&wnode, NULL);
if (result == ISC_R_SUCCESS) {
/*
* We have found the wildcard node. If it
}
NODE_UNLOCK(lock, &nlocktype);
if (header != NULL ||
- activeempty(search, &wchain, wname))
+ activeempty(search, &witer, wname))
{
if (wildcard_blocked(search, qname,
wname))
result = ISC_R_NOTFOUND;
break;
}
-
- if (i > 0) {
- i--;
- node = search->chain.levels[i];
- } else {
- done = true;
- }
- } while (!done);
+ }
return (result);
}
static isc_result_t
previous_closest_nsec(dns_rdatatype_t type, qpdb_search_t *search,
dns_name_t *name, dns_name_t *origin,
- dns_rbtnode_t **nodep, dns_rbtnodechain_t *nsecchain,
+ dns_rbtnode_t **nodep, dns_qpiter_t *nseciter,
bool *firstp) {
dns_fixedname_t ftarget;
dns_name_t *target = NULL;
REQUIRE(type == dns_rdatatype_nsec3 || firstp != NULL);
if (type == dns_rdatatype_nsec3) {
- result = dns_rbtnodechain_prev(&search->chain, NULL, NULL);
- if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
- return (result);
- }
- result = dns_rbtnodechain_current(&search->chain, name, origin,
- nodep);
- return (result);
+ return (dns_qpiter_prev(&search->iter, name, (void **)nodep,
+ NULL));
}
target = dns_fixedname_initname(&ftarget);
* It is the first node sought in the NSEC tree.
*/
*firstp = false;
- dns_rbtnodechain_init(nsecchain);
result = dns_name_concatenate(name, origin, target,
NULL);
if (result != ISC_R_SUCCESS) {
}
nsecnode = NULL;
result = dns_qp_lookup(search->qpdb->nsec, name, NULL,
- NULL, nsecchain,
+ nseciter, NULL,
(void **)&nsecnode, NULL);
if (result == ISC_R_SUCCESS) {
/*
* unacceptable NSEC record.
* Try the previous node in the NSEC tree.
*/
- result = dns_rbtnodechain_prev(nsecchain, name,
- origin);
+ result = dns_qpiter_prev(nseciter, name, NULL,
+ NULL);
if (result == DNS_R_NEWORIGIN) {
result = ISC_R_SUCCESS;
}
result == DNS_R_PARTIALMATCH)
{
/* The iterator is already where we want it */
- result = dns_rbtnodechain_current(
- nsecchain, name, origin, NULL);
- if (result == ISC_R_NOTFOUND) {
- result = ISC_R_NOMORE;
- }
+ result = dns_qpiter_current(nseciter, name,
+ NULL, NULL);
}
} else {
/*
* must have found nodes in the main tree with NSEC
* records. Perhaps they lacked signature records.
*/
- result = dns_rbtnodechain_prev(nsecchain, name, origin);
+ result = dns_qpiter_prev(nseciter, name, NULL, NULL);
if (result == DNS_R_NEWORIGIN) {
result = ISC_R_SUCCESS;
}
bool secure DNS__DB_FLARG) {
dns_rbtnode_t *node = NULL, *prevnode = NULL;
dns_slabheader_t *header = NULL, *header_next = NULL;
- dns_rbtnodechain_t nsecchain;
+ dns_qpiter_t nseciter;
bool empty_node;
isc_result_t result;
dns_fixedname_t fname, forigin;
*/
name = dns_fixedname_initname(&fname);
origin = dns_fixedname_initname(&forigin);
-again:
- node = NULL;
- prevnode = NULL;
- result = dns_rbtnodechain_current(&search->chain, name, origin, &node);
+
+ result = dns_qpiter_current(&search->iter, name, (void **)&node, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
+
+again:
do {
dns_slabheader_t *found = NULL, *foundsig = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
empty_node = true;
result = previous_closest_nsec(
type, search, name, origin, &prevnode,
- &nsecchain, &first);
+ &nseciter, &first);
} else {
/*
* We found an active node, but either the
*/
result = previous_closest_nsec(type, search, name,
origin, &prevnode,
- &nsecchain, &first);
+ &nseciter, &first);
}
NODE_UNLOCK(&(search->qpdb->node_locks[node->locknum].lock),
&nlocktype);
prevnode = NULL;
} while (empty_node && result == ISC_R_SUCCESS);
- if (!first) {
- dns_rbtnodechain_invalidate(&nsecchain);
- }
-
if (result == ISC_R_NOMORE && wraps) {
- result = dns_rbtnodechain_last(&search->chain, tree, NULL,
- NULL);
+ result = dns_qpiter_prev(&search->iter, name, (void **)&node,
+ NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
wraps = false;
goto again;
.options = options,
};
dns_fixedname_init(&search.zonecut_name);
- dns_rbtnodechain_init(&search.chain);
TREE_RDLOCK(&search.qpdb->tree_lock, &tlocktype);
* The NSEC3 tree won't have empty nodes,
* so it isn't necessary to check for them.
*/
- dns_rbtnodechain_t chain = search.chain;
- active = activeempty(&search, &chain, name);
+ dns_qpiter_t iter = search.iter;
+ active = activeempty(&search, &iter, name);
}
/*
dns__qpdb_closeversion(db, &version, false DNS__DB_FLARG_PASS);
}
- dns_rbtnodechain_reset(&search.chain);
-
return (result);
}
#define KEEPSTALE(qpdb) ((qpdb)->common.serve_stale_ttl > 0)
-#define QPDBITER_NSEC3_ORIGIN_NODE(qpdb, iterator) \
- ((iterator)->current == &(iterator)->nsec3chain && \
+#define QPDBITER_NSEC3_ORIGIN_NODE(qpdb, iterator) \
+ ((iterator)->current == &(iterator)->nsec3iter && \
(iterator)->node == (qpdb)->nsec3_origin_node)
/*%
/*
* Note that these iterators, unless created with either DNS_DB_NSEC3ONLY or
* DNS_DB_NONSEC3, will transparently move between the last node of the
- * "regular" RBT ("chain" field) and the root node of the NSEC3 RBT
- * ("nsec3chain" field) of the database in question, as if the latter was a
+ * "regular" QP ("iter" field) and the root node of the NSEC3 QP
+ * ("nsec3iter" field) of the database in question, as if the latter was a
* successor to the former in lexical order. The "current" field always holds
- * the address of either "chain" or "nsec3chain", depending on which RBT is
+ * the address of either "iter" or "nsec3iter", depending on which QP is
* being traversed at given time.
*/
static void
isc_result_t result;
dns_fixedname_t name;
dns_fixedname_t origin;
- dns_rbtnodechain_t chain;
- dns_rbtnodechain_t nsec3chain;
- dns_rbtnodechain_t *current;
+ dns_qpiter_t iter;
+ dns_qpiter_t nsec3iter;
+ dns_qpiter_t *current;
dns_rbtnode_t *node;
enum { full, nonsec3, nsec3only } nsec3mode;
} qpdb_dbiterator_t;
dns_fixedname_init(&qpdbiter->name);
dns_fixedname_init(&qpdbiter->origin);
qpdbiter->node = NULL;
+
if ((options & DNS_DB_NSEC3ONLY) != 0) {
qpdbiter->nsec3mode = nsec3only;
} else if ((options & DNS_DB_NONSEC3) != 0) {
} else {
qpdbiter->nsec3mode = full;
}
- dns_rbtnodechain_init(&qpdbiter->chain);
- dns_rbtnodechain_init(&qpdbiter->nsec3chain);
+ dns_qpiter_init(qpdb->tree, &qpdbiter->iter);
+ dns_qpiter_init(qpdb->nsec3, &qpdbiter->nsec3iter);
if (qpdbiter->nsec3mode == nsec3only) {
- qpdbiter->current = &qpdbiter->nsec3chain;
+ qpdbiter->current = &qpdbiter->nsec3iter;
} else {
- qpdbiter->current = &qpdbiter->chain;
+ qpdbiter->current = &qpdbiter->iter;
}
*iteratorp = (dns_dbiterator_t *)qpdbiter;
-
return (ISC_R_SUCCESS);
}
dns_db_attach(qpdbiter->common.db, &db);
dns_db_detach(&qpdbiter->common.db);
- dns_rbtnodechain_reset(&qpdbiter->chain);
- dns_rbtnodechain_reset(&qpdbiter->nsec3chain);
isc_mem_put(db->mctx, qpdbiter, sizeof(*qpdbiter));
dns_db_detach(&db);
isc_result_t result;
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
dns_qpdb_t *qpdb = (dns_qpdb_t *)iterator->db;
- dns_name_t *name = NULL, *origin = NULL;
if (qpdbiter->result != ISC_R_SUCCESS &&
qpdbiter->result != ISC_R_NOTFOUND &&
dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- name = dns_fixedname_name(&qpdbiter->name);
- origin = dns_fixedname_name(&qpdbiter->origin);
- dns_rbtnodechain_reset(&qpdbiter->chain);
- dns_rbtnodechain_reset(&qpdbiter->nsec3chain);
-
switch (qpdbiter->nsec3mode) {
case nsec3only:
- qpdbiter->current = &qpdbiter->nsec3chain;
- result = dns_rbtnodechain_first(qpdbiter->current, qpdb->nsec3,
- name, origin);
+ qpdbiter->current = &qpdbiter->nsec3iter;
+ dns_qpiter_init(qpdb->nsec3, qpdbiter->current);
+ result = dns_qpiter_next(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+ if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
+ /* If we're in the NSEC3 tree, skip the origin */
+ if (QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter)) {
+ result = dns_qpiter_next(
+ qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+ }
+ }
break;
case nonsec3:
- qpdbiter->current = &qpdbiter->chain;
- result = dns_rbtnodechain_first(qpdbiter->current, qpdb->tree,
- name, origin);
+ qpdbiter->current = &qpdbiter->iter;
+ dns_qpiter_init(qpdb->tree, qpdbiter->current);
+ result = dns_qpiter_next(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
break;
case full:
- qpdbiter->current = &qpdbiter->chain;
- result = dns_rbtnodechain_first(qpdbiter->current, qpdb->tree,
- name, origin);
- if (result == ISC_R_NOTFOUND) {
- qpdbiter->current = &qpdbiter->nsec3chain;
- result = dns_rbtnodechain_first(
- qpdbiter->current, qpdb->nsec3, name, origin);
+ qpdbiter->current = &qpdbiter->iter;
+ dns_qpiter_init(qpdb->tree, qpdbiter->current);
+ result = dns_qpiter_next(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+ if (result == ISC_R_NOMORE) {
+ qpdbiter->current = &qpdbiter->nsec3iter;
+ dns_qpiter_init(qpdb->nsec3, qpdbiter->current);
+ result = dns_qpiter_next(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node,
+ NULL);
}
break;
default:
}
if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
- result = dns_rbtnodechain_current(qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
-
- /* If we're in the NSEC3 tree, skip the origin */
- if (QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter)) {
- qpdbiter->node = NULL;
- result = dns_rbtnodechain_next(qpdbiter->current, name,
- origin);
- if (result == ISC_R_SUCCESS ||
- result == DNS_R_NEWORIGIN)
- {
- result = dns_rbtnodechain_current(
- qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
- }
- }
- if (result == ISC_R_SUCCESS) {
- qpdbiter->new_origin = true;
- reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- }
+ qpdbiter->new_origin = true;
+ reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
} else {
- INSIST(result == ISC_R_NOTFOUND);
- result = ISC_R_NOMORE; /* The tree is empty. */
+ INSIST(result == ISC_R_NOMORE); /* The tree is empty. */
}
qpdbiter->result = result;
isc_result_t result;
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
dns_qpdb_t *qpdb = (dns_qpdb_t *)iterator->db;
- dns_name_t *name = NULL, *origin = NULL;
if (qpdbiter->result != ISC_R_SUCCESS &&
qpdbiter->result != ISC_R_NOTFOUND &&
dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- name = dns_fixedname_name(&qpdbiter->name);
- origin = dns_fixedname_name(&qpdbiter->origin);
- dns_rbtnodechain_reset(&qpdbiter->chain);
- dns_rbtnodechain_reset(&qpdbiter->nsec3chain);
-
switch (qpdbiter->nsec3mode) {
case nsec3only:
- qpdbiter->current = &qpdbiter->nsec3chain;
- result = dns_rbtnodechain_last(qpdbiter->current, qpdb->nsec3,
- name, origin);
+ qpdbiter->current = &qpdbiter->nsec3iter;
+ dns_qpiter_init(qpdb->nsec3, qpdbiter->current);
+ result = dns_qpiter_prev(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+ if ((result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) &&
+ QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter))
+ {
+ /*
+ * NSEC3 tree only has an origin node.
+ */
+ qpdbiter->node = NULL;
+ result = ISC_R_NOMORE;
+ }
break;
case nonsec3:
- qpdbiter->current = &qpdbiter->chain;
- result = dns_rbtnodechain_last(qpdbiter->current, qpdb->tree,
- name, origin);
+ qpdbiter->current = &qpdbiter->iter;
+ dns_qpiter_init(qpdb->tree, qpdbiter->current);
+ result = dns_qpiter_prev(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
break;
case full:
- qpdbiter->current = &qpdbiter->nsec3chain;
- result = dns_rbtnodechain_last(qpdbiter->current, qpdb->nsec3,
- name, origin);
- if (result == ISC_R_NOTFOUND) {
- qpdbiter->current = &qpdbiter->chain;
- result = dns_rbtnodechain_last(
- qpdbiter->current, qpdb->tree, name, origin);
+ qpdbiter->current = &qpdbiter->nsec3iter;
+ dns_qpiter_init(qpdb->nsec3, qpdbiter->current);
+ result = dns_qpiter_prev(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+ if ((result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) &&
+ QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter))
+ {
+ /*
+ * NSEC3 tree only has an origin node.
+ */
+ qpdbiter->node = NULL;
+ result = ISC_R_NOMORE;
+ }
+ if (result == ISC_R_NOMORE) {
+ qpdbiter->current = &qpdbiter->iter;
+ dns_qpiter_init(qpdb->tree, qpdbiter->current);
+ result = dns_qpiter_prev(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node,
+ NULL);
}
break;
default:
}
if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
- result = dns_rbtnodechain_current(qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
- if (QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter)) {
- /*
- * NSEC3 tree only has an origin node.
- */
- qpdbiter->node = NULL;
- switch (qpdbiter->nsec3mode) {
- case nsec3only:
- result = ISC_R_NOMORE;
- break;
- case nonsec3:
- case full:
- qpdbiter->current = &qpdbiter->chain;
- result = dns_rbtnodechain_last(
- qpdbiter->current, qpdb->tree, name,
- origin);
- if (result == ISC_R_SUCCESS ||
- result == DNS_R_NEWORIGIN)
- {
- result = dns_rbtnodechain_current(
- qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
- }
- break;
- default:
- UNREACHABLE();
- }
- }
- if (result == ISC_R_SUCCESS) {
- qpdbiter->new_origin = true;
- reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- }
+ qpdbiter->new_origin = true;
+ reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
} else {
- INSIST(result == ISC_R_NOTFOUND);
- result = ISC_R_NOMORE; /* The tree is empty. */
+ INSIST(result == ISC_R_NOMORE); /* The tree is empty. */
}
qpdbiter->result = result;
isc_result_t result, tresult;
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
dns_qpdb_t *qpdb = (dns_qpdb_t *)iterator->db;
- dns_name_t *iname = NULL, *origin = NULL;
if (qpdbiter->result != ISC_R_SUCCESS &&
qpdbiter->result != ISC_R_NOTFOUND &&
dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- iname = dns_fixedname_name(&qpdbiter->name);
- origin = dns_fixedname_name(&qpdbiter->origin);
- dns_rbtnodechain_reset(&qpdbiter->chain);
- dns_rbtnodechain_reset(&qpdbiter->nsec3chain);
-
switch (qpdbiter->nsec3mode) {
case nsec3only:
- qpdbiter->current = &qpdbiter->nsec3chain;
+ qpdbiter->current = &qpdbiter->nsec3iter;
result = dns_qp_lookup(qpdb->nsec3, name, NULL,
qpdbiter->current, NULL,
(void **)&qpdbiter->node, NULL);
break;
case nonsec3:
- qpdbiter->current = &qpdbiter->chain;
+ qpdbiter->current = &qpdbiter->iter;
result = dns_qp_lookup(qpdb->tree, name, NULL,
qpdbiter->current, NULL,
(void **)&qpdbiter->node, NULL);
case full:
/*
* Stay on main chain if not found on
- * either chain.
+ * either iterator.
*/
- qpdbiter->current = &qpdbiter->chain;
+ qpdbiter->current = &qpdbiter->iter;
result = dns_qp_lookup(qpdb->tree, name, NULL,
qpdbiter->current, NULL,
(void **)&qpdbiter->node, NULL);
if (result == DNS_R_PARTIALMATCH) {
dns_rbtnode_t *node = NULL;
tresult = dns_qp_lookup(qpdb->nsec3, name, NULL,
- &qpdbiter->nsec3chain, NULL,
+ &qpdbiter->nsec3iter, NULL,
(void **)&node, NULL);
if (tresult == ISC_R_SUCCESS) {
qpdbiter->node = node;
- qpdbiter->current = &qpdbiter->nsec3chain;
+ qpdbiter->current = &qpdbiter->nsec3iter;
result = tresult;
}
}
}
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
- tresult = dns_rbtnodechain_current(qpdbiter->current, iname,
- origin, NULL);
- if (tresult == ISC_R_SUCCESS) {
- qpdbiter->new_origin = true;
- reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- } else {
- result = tresult;
- qpdbiter->node = NULL;
- }
+ qpdbiter->new_origin = true;
+ reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
} else {
qpdbiter->node = NULL;
}
dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG) {
isc_result_t result;
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
- dns_name_t *name = NULL, *origin = NULL;
dns_qpdb_t *qpdb = (dns_qpdb_t *)iterator->db;
REQUIRE(qpdbiter->node != NULL);
dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
- name = dns_fixedname_name(&qpdbiter->name);
- origin = dns_fixedname_name(&qpdbiter->origin);
- result = dns_rbtnodechain_prev(qpdbiter->current, name, origin);
- if (qpdbiter->current == &qpdbiter->nsec3chain &&
- (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN))
- {
- /*
- * If we're in the NSEC3 tree, it's empty or we've
- * reached the origin, then we're done with it.
- */
- result = dns_rbtnodechain_current(qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
- if (result == ISC_R_NOTFOUND ||
- QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter))
- {
- qpdbiter->node = NULL;
- result = ISC_R_NOMORE;
+ result = dns_qpiter_prev(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+
+ if (qpdbiter->current == &qpdbiter->nsec3iter) {
+ if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
+ /*
+ * If we're in the NSEC3 tree, it's empty or
+ * we've reached the origin, then we're done
+ * with it.
+ */
+ if (QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter)) {
+ qpdbiter->node = NULL;
+ result = ISC_R_NOMORE;
+ }
}
- }
- if (result == ISC_R_NOMORE && qpdbiter->nsec3mode != nsec3only &&
- &qpdbiter->nsec3chain == qpdbiter->current)
- {
- qpdbiter->current = &qpdbiter->chain;
- dns_rbtnodechain_reset(qpdbiter->current);
- result = dns_rbtnodechain_last(qpdbiter->current, qpdb->tree,
- name, origin);
- if (result == ISC_R_NOTFOUND) {
- result = ISC_R_NOMORE;
+ if (result == ISC_R_NOMORE && qpdbiter->nsec3mode == full) {
+ qpdbiter->current = &qpdbiter->iter;
+ dns_qpiter_init(qpdb->tree, qpdbiter->current);
+ result = dns_qpiter_prev(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node,
+ NULL);
}
}
- if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
- qpdbiter->new_origin = (result == DNS_R_NEWORIGIN);
- result = dns_rbtnodechain_current(qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
- }
+ qpdbiter->new_origin = (result == DNS_R_NEWORIGIN);
if (result == ISC_R_SUCCESS) {
reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
dbiterator_next(dns_dbiterator_t *iterator DNS__DB_FLARG) {
isc_result_t result;
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
- dns_name_t *name = NULL, *origin = NULL;
dns_qpdb_t *qpdb = (dns_qpdb_t *)iterator->db;
REQUIRE(qpdbiter->node != NULL);
resume_iteration(qpdbiter);
}
- name = dns_fixedname_name(&qpdbiter->name);
- origin = dns_fixedname_name(&qpdbiter->origin);
- result = dns_rbtnodechain_next(qpdbiter->current, name, origin);
- if (result == ISC_R_NOMORE && qpdbiter->nsec3mode != nonsec3 &&
- &qpdbiter->chain == qpdbiter->current)
+ dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
+
+ result = dns_qpiter_next(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+
+ if (result == ISC_R_NOMORE && qpdbiter->nsec3mode == full &&
+ qpdbiter->current == &qpdbiter->iter)
{
- qpdbiter->current = &qpdbiter->nsec3chain;
- dns_rbtnodechain_reset(qpdbiter->current);
- result = dns_rbtnodechain_first(qpdbiter->current, qpdb->nsec3,
- name, origin);
- if (result == ISC_R_NOTFOUND) {
- result = ISC_R_NOMORE;
- }
+ qpdbiter->current = &qpdbiter->nsec3iter;
+ dns_qpiter_init(qpdb->nsec3, qpdbiter->current);
+ result = dns_qpiter_next(qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
}
- dereference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
-
if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
/*
* If we've just started the NSEC3 tree,
* skip over the origin.
*/
- qpdbiter->new_origin = (result == DNS_R_NEWORIGIN);
- result = dns_rbtnodechain_current(qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
if (QPDBITER_NSEC3_ORIGIN_NODE(qpdb, qpdbiter)) {
- qpdbiter->node = NULL;
- result = dns_rbtnodechain_next(qpdbiter->current, name,
- origin);
- if (result == ISC_R_SUCCESS ||
- result == DNS_R_NEWORIGIN)
- {
- result = dns_rbtnodechain_current(
- qpdbiter->current, NULL, NULL,
- &qpdbiter->node);
+ switch (qpdbiter->nsec3mode) {
+ case nsec3only:
+ case full:
+ result = dns_qpiter_next(
+ qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
+ break;
+ case nonsec3:
+ result = ISC_R_NOMORE;
+ qpdbiter->node = NULL;
+ break;
+ default:
+ UNREACHABLE();
}
}
}
+
+ qpdbiter->new_origin = (result == DNS_R_NEWORIGIN);
+
if (result == ISC_R_SUCCESS) {
reference_iter_node(qpdbiter DNS__DB_FLARG_PASS);
}
dns_qpdb_t *qpdb = (dns_qpdb_t *)iterator->db;
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
dns_rbtnode_t *node = qpdbiter->node;
- isc_result_t result;
- dns_name_t *nodename = dns_fixedname_name(&qpdbiter->name);
- dns_name_t *origin = dns_fixedname_name(&qpdbiter->origin);
+ isc_result_t result = ISC_R_SUCCESS;
REQUIRE(qpdbiter->result == ISC_R_SUCCESS);
REQUIRE(qpdbiter->node != NULL);
}
if (name != NULL) {
- if (qpdbiter->common.relative_names) {
- origin = NULL;
- }
- result = dns_name_concatenate(nodename, origin, name, NULL);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
+ dns_name_copy(qpdbiter->node->name, name);
+
if (qpdbiter->common.relative_names && qpdbiter->new_origin) {
result = DNS_R_NEWORIGIN;
}