]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Replace rbtnodechain with qpchain and qpiter
authorMatthijs Mekking <matthijs@isc.org>
Tue, 16 Jan 2024 10:26:20 +0000 (11:26 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 6 Mar 2024 08:57:24 +0000 (09:57 +0100)
The qp approach pulled apart the chain and iterator into two separate
things. Replace the rbtnodechain with qpchain and qpiter. Most of the
times we are interested in the iterator only, the rbtnodechain was
mainly used as an an iterator to get the previous and next name in the
DNS canonical order.

Since dns_qpiter_prev() and dns_qpiter_next() store the name, origin,
and node in the provided parameters, often there is no need to call
a current() function anymore.

Getting the first or last item from the iterator is done by
re-initializing the iterator and then call dns_qpiter_next() or
dns_qpiter_prev() respectively.

The dbiterator no longer needs to maintain a chain, only an iterator.

lib/dns/qp-cachedb.c
lib/dns/qp-zonedb.c
lib/dns/qpdb.c
lib/dns/qpdb_p.h

index 8e55b7d1f2c68bc3e32380cc055c58b794c5ce72..b063ad7a2afa354e18b602326ee8c8569c6903d4 100644 (file)
@@ -497,26 +497,25 @@ find_deepest_zonecut(qpdb_search_t *search, dns_rbtnode_t *node,
                     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);
 
                /*
@@ -556,31 +555,10 @@ find_deepest_zonecut(qpdb_search_t *search, dns_rbtnode_t *node,
                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) {
@@ -618,16 +596,12 @@ find_deepest_zonecut(qpdb_search_t *search, dns_rbtnode_t *node,
                        }
                }
 
-       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);
 }
@@ -644,11 +618,10 @@ find_coveringnsec(qpdb_search_t *search, const dns_name_t *name,
                  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;
@@ -660,43 +633,31 @@ find_coveringnsec(qpdb_search_t *search, const dns_name_t *name,
        /*
         * 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);
        }
@@ -790,7 +751,6 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
                .now = now,
        };
        dns_fixedname_init(&search.zonecut_name);
-       dns_rbtnodechain_init(&search.chain);
 
        TREE_RDLOCK(&search.qpdb->tree_lock, &tlocktype);
 
@@ -1193,8 +1153,6 @@ tree_exit:
                INSIST(tlocktype == isc_rwlocktype_none);
        }
 
-       dns_rbtnodechain_reset(&search.chain);
-
        update_cachestats(search.qpdb, result);
        return (result);
 }
@@ -1229,7 +1187,6 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
                .now = now,
        };
        dns_fixedname_init(&search.zonecut_name);
-       dns_rbtnodechain_init(&search.chain);
 
        if (dcnull) {
                dcname = foundname;
@@ -1369,8 +1326,6 @@ tree_exit:
 
        INSIST(!search.need_cleanup);
 
-       dns_rbtnodechain_reset(&search.chain);
-
        if (result == DNS_R_DELEGATION) {
                result = ISC_R_SUCCESS;
        }
index e70a05ca280860744e002cf4168dafb96aba7f01..e9f77f9f88994a5f6eac042818336355f4e0b957 100644 (file)
@@ -321,11 +321,10 @@ typedef enum { FORWARD, BACK } direction_t;
  * 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;
@@ -333,17 +332,11 @@ step(qpdb_search_t *search, dns_rbtnodechain_t *chain, direction_t direction,
 
        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)
@@ -359,16 +352,19 @@ step(qpdb_search_t *search, dns_rbtnodechain_t *chain, direction_t direction,
                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);
@@ -381,17 +377,17 @@ step(qpdb_search_t *search, dns_rbtnodechain_t *chain, direction_t direction,
  * 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));
 }
 
@@ -405,7 +401,7 @@ wildcard_blocked(qpdb_search_t *search, const dns_name_t *qname,
        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;
@@ -421,20 +417,20 @@ wildcard_blocked(qpdb_search_t *search, const dns_name_t *qname,
         * 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) {
@@ -470,12 +466,10 @@ wildcard_blocked(qpdb_search_t *search, const dns_name_t *qname,
 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
@@ -493,14 +487,15 @@ find_wildcard(qpdb_search_t *search, dns_rbtnode_t **nodep,
         */
 
        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
@@ -516,52 +511,29 @@ find_wildcard(qpdb_search_t *search, dns_rbtnode_t **nodep,
                                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
@@ -582,7 +554,7 @@ find_wildcard(qpdb_search_t *search, dns_rbtnode_t **nodep,
                                }
                                NODE_UNLOCK(lock, &nlocktype);
                                if (header != NULL ||
-                                   activeempty(search, &wchain, wname))
+                                   activeempty(search, &witer, wname))
                                {
                                        if (wildcard_blocked(search, qname,
                                                             wname))
@@ -617,14 +589,7 @@ find_wildcard(qpdb_search_t *search, dns_rbtnode_t **nodep,
                        result = ISC_R_NOTFOUND;
                        break;
                }
-
-               if (i > 0) {
-                       i--;
-                       node = search->chain.levels[i];
-               } else {
-                       done = true;
-               }
-       } while (!done);
+       }
 
        return (result);
 }
@@ -673,7 +638,7 @@ matchparams(dns_slabheader_t *header, qpdb_search_t *search) {
 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;
@@ -684,13 +649,8 @@ previous_closest_nsec(dns_rdatatype_t type, qpdb_search_t *search,
        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);
@@ -702,7 +662,6 @@ previous_closest_nsec(dns_rdatatype_t type, qpdb_search_t *search,
                         * 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) {
@@ -710,7 +669,7 @@ previous_closest_nsec(dns_rdatatype_t type, qpdb_search_t *search,
                        }
                        nsecnode = NULL;
                        result = dns_qp_lookup(search->qpdb->nsec, name, NULL,
-                                              NULL, nsecchain,
+                                              nseciter, NULL,
                                               (void **)&nsecnode, NULL);
                        if (result == ISC_R_SUCCESS) {
                                /*
@@ -720,8 +679,8 @@ previous_closest_nsec(dns_rdatatype_t type, qpdb_search_t *search,
                                 * 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;
                                }
@@ -729,11 +688,8 @@ previous_closest_nsec(dns_rdatatype_t type, qpdb_search_t *search,
                                   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 {
                        /*
@@ -743,7 +699,7 @@ previous_closest_nsec(dns_rdatatype_t type, qpdb_search_t *search,
                         * 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;
                        }
@@ -787,7 +743,7 @@ find_closest_nsec(qpdb_search_t *search, dns_dbnode_t **nodep,
                  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;
@@ -814,13 +770,13 @@ find_closest_nsec(qpdb_search_t *search, dns_dbnode_t **nodep,
         */
        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;
@@ -926,7 +882,7 @@ again:
                                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
@@ -942,7 +898,7 @@ again:
                         */
                        result = previous_closest_nsec(type, search, name,
                                                       origin, &prevnode,
-                                                      &nsecchain, &first);
+                                                      &nseciter, &first);
                }
                NODE_UNLOCK(&(search->qpdb->node_locks[node->locknum].lock),
                            &nlocktype);
@@ -950,13 +906,9 @@ again:
                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;
@@ -1020,7 +972,6 @@ zone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
                .options = options,
        };
        dns_fixedname_init(&search.zonecut_name);
-       dns_rbtnodechain_init(&search.chain);
 
        TREE_RDLOCK(&search.qpdb->tree_lock, &tlocktype);
 
@@ -1095,8 +1046,8 @@ zone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
                         * 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);
                }
 
                /*
@@ -1511,8 +1462,6 @@ tree_exit:
                dns__qpdb_closeversion(db, &version, false DNS__DB_FLARG_PASS);
        }
 
-       dns_rbtnodechain_reset(&search.chain);
-
        return (result);
 }
 
index f0a43b54d9be05d3979d0ff4e75451bb015e8bed..40991dcaa822c49ef9560eb3aba9106e8138db60 100644 (file)
 
 #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)
 
 /*%
@@ -235,10 +235,10 @@ typedef struct qpdb_rdatasetiter {
 /*
  * 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
@@ -279,9 +279,9 @@ typedef struct qpdb_dbiterator {
        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;
@@ -2247,6 +2247,7 @@ dns__qpdb_createiterator(dns_db_t *db, unsigned int options,
        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) {
@@ -2254,16 +2255,15 @@ dns__qpdb_createiterator(dns_db_t *db, unsigned int options,
        } 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);
 }
 
@@ -4193,8 +4193,6 @@ dbiterator_destroy(dns_dbiterator_t **iteratorp DNS__DB_FLARG) {
        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);
 
@@ -4206,7 +4204,6 @@ dbiterator_first(dns_dbiterator_t *iterator DNS__DB_FLARG) {
        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 &&
@@ -4222,30 +4219,38 @@ dbiterator_first(dns_dbiterator_t *iterator DNS__DB_FLARG) {
 
        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:
@@ -4253,29 +4258,10 @@ dbiterator_first(dns_dbiterator_t *iterator DNS__DB_FLARG) {
        }
 
        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;
@@ -4292,7 +4278,6 @@ dbiterator_last(dns_dbiterator_t *iterator DNS__DB_FLARG) {
        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 &&
@@ -4308,30 +4293,48 @@ dbiterator_last(dns_dbiterator_t *iterator DNS__DB_FLARG) {
 
        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:
@@ -4339,42 +4342,10 @@ dbiterator_last(dns_dbiterator_t *iterator DNS__DB_FLARG) {
        }
 
        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;
@@ -4388,7 +4359,6 @@ dbiterator_seek(dns_dbiterator_t *iterator,
        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 &&
@@ -4404,20 +4374,15 @@ dbiterator_seek(dns_dbiterator_t *iterator,
 
        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);
@@ -4425,20 +4390,20 @@ dbiterator_seek(dns_dbiterator_t *iterator,
        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;
                        }
                }
@@ -4448,15 +4413,8 @@ dbiterator_seek(dns_dbiterator_t *iterator,
        }
 
        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;
        }
@@ -4471,7 +4429,6 @@ static isc_result_t
 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);
@@ -4486,42 +4443,31 @@ dbiterator_prev(dns_dbiterator_t *iterator DNS__DB_FLARG) {
 
        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);
@@ -4536,7 +4482,6 @@ static isc_result_t
 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);
@@ -4549,44 +4494,45 @@ dbiterator_next(dns_dbiterator_t *iterator DNS__DB_FLARG) {
                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);
        }
@@ -4602,9 +4548,7 @@ dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
        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);
@@ -4614,13 +4558,8 @@ dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
        }
 
        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;
                }
index ca481d887016f6ac802edffd3b5902ce56e1f5e6..4d87dd440a1541d19c686f061451ef10bda35679 100644 (file)
@@ -269,7 +269,8 @@ typedef struct {
        dns_qpdb_version_t *rbtversion;
        uint32_t serial;
        unsigned int options;
-       dns_rbtnodechain_t chain;
+       dns_qpchain_t chain;
+       dns_qpiter_t iter;
        bool copy_name;
        bool need_cleanup;
        bool wild;