]> 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:38:17 +0000 (11:38 +1100)
                        wasn't a node at the specified name. [RT #41846]

(cherry picked from commit 6214c3c93a43dc86f080dc0219e4560b69721f53)

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 add70f0d039b51610b39921d969877c33a961c5f..c817989808377da561eab8fd7677067da19bb29e 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]
+
 4338.  [bug]           Reimplement change 4324 as it wasn't properly doing
                        all the required book keeping. [RT #41941]
 
index 42e6c59b832908ed582e03ee6a3254202b27b40e..6ffd83ea2e9eaa23e239af5c4b371e24a742758d 100644 (file)
@@ -190,5 +190,32 @@ nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l`
 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
+dump_cache
+awk '/plain success\/timeout/ {getline; getline; if ($2 == "ns.flushtest.example") exit(0); exit(1); }' ns2/named_dump.db || ret=1
+$RNDC $RNDCOPTS flushtree flushtest.example || ret=1
+dump_cache
+awk '/plain success\/timeout/ {getline; getline; if ($2 == "ns.flushtest.example") exit(1); exit(0); }' ns2/named_dump.db || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 exit $status
index 09882331498039387aa7fc295b83c79be8d42a41..a37acf935bdc111b5e44ff0166ffd32b7d210e28 100644 (file)
@@ -1211,6 +1211,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;
 
@@ -1262,7 +1264,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 df7f68c1b78a1973293012696b6babb077bf6f45..80713da20dd9b068e6fb3560c68699cc74b7a020 100644 (file)
@@ -8804,23 +8804,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) {
@@ -8835,7 +8819,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);