]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4341. [bug] 'rndc flushtree' could fail to clean the tree if there
authorMark Andrews <marka@isc.org>
Thu, 24 Mar 2016 00:31:25 +0000 (11:31 +1100)
committerMark Andrews <marka@isc.org>
Thu, 24 Mar 2016 00:31:25 +0000 (11:31 +1100)
                        wasn't a node at the specified name. [RT #41846]

CHANGES
bin/tests/system/cacheclean/tests.sh
lib/dns/cache.c
lib/dns/include/dns/dbiterator.h
lib/dns/rbtdb.c
lib/dns/tests/dbiterator_test.c

diff --git a/CHANGES b/CHANGES
index a5d88d80ebcc78f4645ed37f87903d3e4951d31a..aa682999130fa760f3f65a9a2bd1974a4ab4fff1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4341.  [bug]           'rndc flushtree' could fail to clean the tree if there
+                       wasn't a node at the specified name. [RT #41846]
+
        --- 9.11.0a1 released ---
 
 4341.  [bug]           Correct the handling of ECS options with
index 86b90a8d7d43e2b7577535798a3f1db199f6e5da..0ab44dab032b70ff8b3eca6fcaf70bd790cfad40 100644 (file)
@@ -190,6 +190,22 @@ nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | egrep '(TXT|
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:check the check that flushname of a partial match works."
+ret=0
+in_cache txt second2.top1.flushtest.example || ret=1
+$RNDC $RNDCOPTS flushtree example
+in_cache txt second2.top1.flushtest.example && ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:check the number of cached records remaining"
+ret=0
+dump_cache
+nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | egrep '(TXT|ANY)' |  wc -l`
+[ $nrecords -eq 1 ] || { ret=1; echo "I: found $nrecords records expected 1"; }
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:check flushtree clears adb correctly"
 ret=0
 load_cache
index 83da390b47647f64e0b30b7e9770b58c29628f56..514959cf5768002b10ad8d7641ddbe4c4c54a71a 100644 (file)
@@ -1228,6 +1228,8 @@ cleartree(dns_db_t *db, dns_name_t *name) {
                goto cleanup;
 
        result = dns_dbiterator_seek(iter, name);
+       if (result == DNS_R_PARTIALMATCH)
+               result = dns_dbiterator_next(iter);
        if (result != ISC_R_SUCCESS)
                goto cleanup;
 
@@ -1279,7 +1281,7 @@ dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name,
        dns_dbnode_t *node = NULL;
        dns_db_t *db = NULL;
 
-       if (dns_name_equal(name, dns_rootname))
+       if (tree && dns_name_equal(name, dns_rootname))
                return (dns_cache_flush(cache));
 
        LOCK(&cache->lock);
index 366d6767a79fe90f0f09cdeed845a13d11c4a8fb..8f51d1c96f80e367a297d7950f071dde65a45460 100644 (file)
@@ -166,6 +166,8 @@ dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name);
  * Returns:
  *\li  #ISC_R_SUCCESS
  *\li  #ISC_R_NOTFOUND
+ *\li  #DNS_R_PARTIALMATCH
+ *     (node is at name above requested named when name has children)
  *
  *\li  Other results are possible, depending on the DB implementation.
  */
index d831162001f43913f4e4d0576eaecd1884235762..cb98eeac900dd7e948eb21813c047cd13fb97098 100644 (file)
@@ -9204,23 +9204,7 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
                }
        }
 
-#if 1
-       if (result == ISC_R_SUCCESS) {
-               result = dns_rbtnodechain_current(rbtdbiter->current, iname,
-                                                 origin, NULL);
-               if (result == ISC_R_SUCCESS) {
-                       rbtdbiter->new_origin = ISC_TRUE;
-                       reference_iter_node(rbtdbiter);
-               }
-       } else if (result == DNS_R_PARTIALMATCH) {
-               result = ISC_R_NOTFOUND;
-               rbtdbiter->node = NULL;
-       }
-
-       rbtdbiter->result = result;
-#else
        if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
-               isc_result_t tresult;
                tresult = dns_rbtnodechain_current(rbtdbiter->current, iname,
                                                   origin, NULL);
                if (tresult == ISC_R_SUCCESS) {
@@ -9235,7 +9219,6 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
 
        rbtdbiter->result = (result == DNS_R_PARTIALMATCH) ?
                            ISC_R_SUCCESS : result;
-#endif
 
        return (result);
 }
index dc7b37058a147e177729c050aeefbbbba9a5f975..888d3be89dc6effebeb1ca5fad11632abefd65bd 100644 (file)
@@ -318,7 +318,7 @@ static void test_seek_empty(const atf_tc_t *tc) {
        ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
 
        result = dns_dbiterator_seek(iter, seekname);
-       ATF_CHECK_EQ(result, ISC_R_NOTFOUND);
+       ATF_CHECK_EQ(result, DNS_R_PARTIALMATCH);
 
        dns_dbiterator_destroy(&iter);
        dns_db_detach(&db);
@@ -374,6 +374,12 @@ static void test_seek_nx(const atf_tc_t *tc) {
        result = make_name("nonexistent." TEST_ORIGIN, seekname);
        ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
 
+       result = dns_dbiterator_seek(iter, seekname);
+       ATF_CHECK_EQ(result, DNS_R_PARTIALMATCH);
+
+       result = make_name("nonexistent.", seekname);
+       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
        result = dns_dbiterator_seek(iter, seekname);
        ATF_CHECK_EQ(result, ISC_R_NOTFOUND);