}
static isc_result_t
-cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
- void *arg DNS__DB_FLARG) {
+check_zonecut(dns_rbtnode_t *node, void *arg DNS__DB_FLARG) {
qpdb_search_t *search = arg;
dns_slabheader_t *header = NULL;
dns_slabheader_t *header_prev = NULL, *header_next = NULL;
REQUIRE(search->zonecut == NULL);
- /*
- * Keep compiler silent.
- */
- UNUSED(name);
-
lock = &(search->qpdb->node_locks[node->locknum].lock);
NODE_RDLOCK(lock, &nlocktype);
*/
dns_rbtnodechain_init(&chain);
target = dns_fixedname_initname(&ftarget);
- result = dns_rbt_findnode(search->qpdb->nsec, name, target, &node,
- &chain, DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ result = dns_qp_lookup(search->qpdb->nsec, name, target, NULL, &chain,
+ (void **)&node, NULL);
if (result != DNS_R_PARTIALMATCH) {
dns_rbtnodechain_reset(&chain);
return (ISC_R_NOTFOUND);
* Lookup the predecessor in the main tree.
*/
node = NULL;
- result = dns_rbt_findnode(search->qpdb->tree, target, fname, &node,
- NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ result = dns_qp_lookup(search->qpdb->tree, target, fname, NULL, NULL,
+ (void **)&node, NULL);
if (result != ISC_R_SUCCESS) {
return (ISC_R_NOTFOUND);
}
TREE_RDLOCK(&search.qpdb->tree_lock, &tlocktype);
/*
- * Search down from the root of the tree. If, while going down, we
- * encounter a callback node, cache_zonecut_callback() will search the
- * rdatasets at the zone cut for a DNAME rdataset.
+ * Search down from the root of the tree.
*/
- result = dns_rbt_findnode(search.qpdb->tree, name, foundname, &node,
- &search.chain, DNS_RBTFIND_EMPTYDATA,
- cache_zonecut_callback, &search);
+ result = dns_qp_lookup(search.qpdb->tree, name, foundname, NULL,
+ &search.chain, (void **)&node, NULL);
+
+ /*
+ * Check the QP chain to see if there's a node above us with a
+ * active DNAME or NS rdatasets.
+ *
+ * We're only interested in nodes above QNAME, so if the result
+ * was success, then we skip the last item in the chain.
+ */
+ unsigned int len = dns_qpchain_length(&search.chain);
+ if (result == ISC_R_SUCCESS) {
+ len--;
+ }
+
+ for (unsigned int i = 0; i < len; i++) {
+ isc_result_t zcresult;
+ dns_rbtnode_t *encloser = NULL;
+
+ dns_qpchain_node(&search.chain, i, NULL, (void **)&encloser,
+ NULL);
+
+ if (encloser->find_callback) {
+ zcresult = check_zonecut(
+ encloser, (void *)&search DNS__DB_FLARG_PASS);
+ if (zcresult != DNS_R_CONTINUE) {
+ result = DNS_R_PARTIALMATCH;
+ search.chain.len = i - 1;
+ node = encloser;
+ break;
+ }
+ }
+ }
if (result == DNS_R_PARTIALMATCH) {
/*
- * If dns_rbt_findnode discovered a covering DNAME skip
- * looking for a covering NSEC.
+ * If we discovered a covering DNAME skip looking for a covering
+ * NSEC.
*/
if ((search.options & DNS_DBFIND_COVERINGNSEC) != 0 &&
(search.zonecut_header == NULL ||
dns_slabheader_t *header = NULL;
dns_slabheader_t *header_prev = NULL, *header_next = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
- unsigned int rbtoptions = DNS_RBTFIND_EMPTYDATA;
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
bool dcnull = (dcname == NULL);
dcname = foundname;
}
- if ((options & DNS_DBFIND_NOEXACT) != 0) {
- rbtoptions |= DNS_RBTFIND_NOEXACT;
- }
-
TREE_RDLOCK(&search.qpdb->tree_lock, &tlocktype);
/*
* Search down from the root of the tree.
*/
- result = dns_rbt_findnode(search.qpdb->tree, name, dcname, &node,
- &search.chain, rbtoptions, NULL, &search);
+ result = dns_qp_lookup(search.qpdb->tree, name, dcname, NULL,
+ &search.chain, (void **)&node, NULL);
+ if ((options & DNS_DBFIND_NOEXACT) != 0 && result == ISC_R_SUCCESS) {
+ int len = dns_qpchain_length(&search.chain);
+ if (len >= 2) {
+ node = NULL;
+ dns_qpchain_node(&search.chain, len - 2, NULL,
+ (void **)&node, NULL);
+ search.chain.len = len - 1;
+ result = DNS_R_PARTIALMATCH;
+ } else {
+ result = ISC_R_NOTFOUND;
+ }
+ }
if (result == DNS_R_PARTIALMATCH) {
result = find_deepest_zonecut(&search, node, nodep, foundname,
&header_prev))
{
/*
- * The function dns_rbt_findnode found us the a matching
+ * The function dns_qp_lookup found us a matching
* node for 'name' and stored the result in 'dcname'.
* This is the deepest known zonecut in our database.
* However, this node may be stale and if serve-stale
}
static isc_result_t
-zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
- void *arg DNS__DB_FLARG) {
+check_zonecut(dns_rbtnode_t *node, void *arg DNS__DB_FLARG) {
qpdb_search_t *search = arg;
dns_slabheader_t *header = NULL, *header_next = NULL;
dns_slabheader_t *dname_header = NULL, *sigdname_header = NULL;
* is, we need to remember the node name.
*/
zcname = dns_fixedname_name(&search->zonecut_name);
- dns_name_copy(name, zcname);
+ dns_name_copy(node->name, zcname);
search->copy_name = true;
}
} else {
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, *wnode = NULL;
+ dns_rbtnode_t *node = NULL, *level_node = NULL;
dns_slabheader_t *header = NULL;
isc_result_t result = ISC_R_NOTFOUND;
- dns_name_t name;
- dns_name_t *wname = NULL;
- dns_fixedname_t fwname;
dns_qpdb_t *qpdb = NULL;
bool done, wild, active;
- dns_rbtnodechain_t wchain;
/*
* Caller must be holding the tree lock and MUST NOT be holding
NODE_UNLOCK(lock, &nlocktype);
if (wild) {
+ dns_name_t *wname = NULL;
+ dns_fixedname_t fwname;
+ dns_rbtnode_t *wnode = NULL;
+ dns_qpiter_t wchain;
+
/*
* Construct the wildcard name for this level.
*/
wnode = NULL;
dns_rbtnodechain_init(&wchain);
- result = dns_rbt_findnode(
- qpdb->tree, wname, NULL, &wnode, &wchain,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+
+ result = dns_qp_lookup(qpdb->tree, wname, NULL, NULL,
+ &wchain, (void **)&wnode, NULL);
if (result == ISC_R_SUCCESS) {
/*
* We have found the wildcard node. If it
return (result);
}
nsecnode = NULL;
- result = dns_rbt_findnode(
- search->qpdb->nsec, target, NULL, &nsecnode,
- nsecchain, DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ result = dns_qp_lookup(search->qpdb->nsec, name, NULL,
+ NULL, nsecchain,
+ (void **)&nsecnode, NULL);
if (result == ISC_R_SUCCESS) {
/*
* Since this was the first loop, finding the
} else if (result == ISC_R_NOTFOUND ||
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) {
return (result);
}
- /*
- * Construct the name to seek in the main tree.
- */
- result = dns_name_concatenate(name, origin, target, NULL);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
-
*nodep = NULL;
- result = dns_rbt_findnode(search->qpdb->tree, target, NULL,
- nodep, &search->chain,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ result = dns_qp_lookup(search->qpdb->tree, name, NULL,
+ &search->iter, &search->chain,
+ (void **)nodep, NULL);
if (result == ISC_R_SUCCESS) {
return (result);
}
TREE_RDLOCK(&search.qpdb->tree_lock, &tlocktype);
/*
- * Search down from the root of the tree. If, while going down, we
- * encounter a callback node, zone_zonecut_callback() will search the
- * rdatasets at the zone cut for active DNAME or NS rdatasets.
+ * Search down from the root of the tree.
*/
tree = (options & DNS_DBFIND_FORCENSEC3) != 0 ? search.qpdb->nsec3
: search.qpdb->tree;
- result = dns_rbt_findnode(tree, name, foundname, &node, &search.chain,
- DNS_RBTFIND_EMPTYDATA, zone_zonecut_callback,
- &search);
+ result = dns_qp_lookup(tree, name, foundname, &search.iter,
+ &search.chain, (void **)&node, NULL);
+
+ /*
+ * Check the QP chain to see if there's a node above us with a
+ * active DNAME or NS rdatasets.
+ *
+ * We're only interested in nodes above QNAME, so if the result
+ * was success, then we skip the last item in the chain.
+ */
+ unsigned int len = dns_qpchain_length(&search.chain);
+ if (result == ISC_R_SUCCESS) {
+ len--;
+ }
+
+ for (unsigned int i = 0; i < len; i++) {
+ isc_result_t zcresult;
+ dns_rbtnode_t *encloser = NULL;
+
+ dns_qpchain_node(&search.chain, i, NULL, (void **)&encloser,
+ NULL);
+
+ if (encloser->find_callback) {
+ zcresult = check_zonecut(
+ encloser, (void *)&search DNS__DB_FLARG_PASS);
+ if (zcresult != DNS_R_CONTINUE) {
+ result = DNS_R_PARTIALMATCH;
+ search.chain.len = i - 1;
+ node = encloser;
+ break;
+ }
+ }
+ }
if (result == DNS_R_PARTIALMATCH) {
partial_match:
* have matched a wildcard.
*/
+ lock = &search.qpdb->node_locks[node->locknum].lock;
+ NODE_RDLOCK(lock, &nlocktype);
+
if (search.zonecut != NULL) {
/*
* If we're beneath a zone cut, we don't want to look for
* We now go looking for rdata...
*/
- lock = &search.qpdb->node_locks[node->locknum].lock;
- NODE_RDLOCK(lock, &nlocktype);
-
found = NULL;
foundsig = NULL;
sigtype = DNS_SIGTYPE(type);
dns_name_init(&nodename, NULL);
TREE_RDLOCK(&qpdb->tree_lock, &tlocktype);
- result = dns_rbt_findnode(tree, name, NULL, &node, NULL,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ result = dns_qp_lookup(tree, name, NULL, NULL, NULL, (void **)&node,
+ NULL);
if (result != ISC_R_SUCCESS) {
if (!create) {
if (result == DNS_R_PARTIALMATCH) {
switch (qpdbiter->nsec3mode) {
case nsec3only:
qpdbiter->current = &qpdbiter->nsec3chain;
- result = dns_rbt_findnode(qpdb->nsec3, name, NULL,
- &qpdbiter->node, qpdbiter->current,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ result = dns_qp_lookup(qpdb->nsec3, name, NULL,
+ qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
break;
case nonsec3:
qpdbiter->current = &qpdbiter->chain;
- result = dns_rbt_findnode(qpdb->tree, name, NULL,
- &qpdbiter->node, qpdbiter->current,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ result = dns_qp_lookup(qpdb->tree, name, NULL,
+ qpdbiter->current, NULL,
+ (void **)&qpdbiter->node, NULL);
break;
case full:
/*
- * Stay on main chain if not found on either chain.
+ * Stay on main chain if not found on
+ * either chain.
*/
qpdbiter->current = &qpdbiter->chain;
- result = dns_rbt_findnode(qpdb->tree, name, NULL,
- &qpdbiter->node, qpdbiter->current,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
+ 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_rbt_findnode(qpdb->nsec3, name, NULL,
- &node, &qpdbiter->nsec3chain,
- DNS_RBTFIND_EMPTYDATA, NULL,
- NULL);
+ tresult = dns_qp_lookup(qpdb->nsec3, name, NULL,
+ &qpdbiter->nsec3chain, NULL,
+ (void **)&node, NULL);
if (tresult == ISC_R_SUCCESS) {
qpdbiter->node = node;
qpdbiter->current = &qpdbiter->nsec3chain;