]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4387. [bug] Change 4336 was not complete leading to SERVFAIL
authorMark Andrews <marka@isc.org>
Wed, 22 Jun 2016 05:26:38 +0000 (15:26 +1000)
committerMark Andrews <marka@isc.org>
Thu, 7 Jul 2016 01:27:45 +0000 (11:27 +1000)
                        being return as NS records expired. [RT #42683]

(cherry picked from commit b56bd9b59f590ade778ac6621fb5bede4001d8ae)
(cherry picked from commit aa630523173f5d0267d97e8e9e5016f65ce006db)

CHANGES
bin/tests/system/zero/ns1/root.db
bin/tests/system/zero/ns2/named.conf
bin/tests/system/zero/ns2/tld.db [new file with mode: 0644]
bin/tests/system/zero/ns4/named.conf
bin/tests/system/zero/ns4/one.tld.db [new file with mode: 0644]
bin/tests/system/zero/tests.sh
lib/dns/rbtdb.c

diff --git a/CHANGES b/CHANGES
index bcc57205377e86180e3967e772014831a2779a94..359b496dd08eec212e8edcab774befd7b1929499 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4387.  [bug]           Change 4336 was not complete leading to SERVFAIL
+                       being return as NS records expired. [RT #42683]
+
        --- 9.9.9-P1 released ---
 
 4366.  [bug]           Address race condition when updating rbtnode bit
index 69aca86fb8522f590abb9f95d75c134f8d2672ab..c07a41751c0b6ea55e37a44387d9813109d8f58a 100644 (file)
@@ -22,3 +22,5 @@ example. NS ns2.example.
 ns2.example. A 10.53.0.2
 example. NS ns4.example.
 ns4.example. A 10.53.0.4
+tld. NS ns2.tld.
+ns2.tld. A 10.53.0.2
index 86673b218874d29d8877c6caff2be47602d68d2d..c1d2e6a6471bda24bfc61e1e8c547a39fae0e275 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2013, 2016  Internet Systems Consortium, Inc. ("ISC")
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -35,3 +35,7 @@ zone "example" {
        file "example.db";
 };
 
+zone "tld" {
+       type master;
+       file "tld.db";
+};
diff --git a/bin/tests/system/zero/ns2/tld.db b/bin/tests/system/zero/ns2/tld.db
new file mode 100644 (file)
index 0000000..f5e987e
--- /dev/null
@@ -0,0 +1,23 @@
+; Copyright (C) 2016  Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+$TTL 1
+@      300     SOA     ns2.tld. hostmaster.ns2.tld. 0 1 1 1 1
+@      300     NS      ns2.tld.
+ns2    300     A       10.53.0.2
+;
+;      The TTL of these delegation records needs to 1.
+;
+one    1       NS      ns4.one.tld.
+ns4.one        1       A       10.53.0.4
index bceeb231175e104cd71b63262ceb875e7af07441..3cf95a59b253a7b8d1c09fbc65d0af76a0d8859e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2013, 2016  Internet Systems Consortium, Inc. ("ISC")
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -36,3 +36,7 @@ zone "example" {
        file "example.bk";
 };
 
+zone "one.tld" {
+       type master;
+       file "one.tld.db";
+};
diff --git a/bin/tests/system/zero/ns4/one.tld.db b/bin/tests/system/zero/ns4/one.tld.db
new file mode 100644 (file)
index 0000000..9442309
--- /dev/null
@@ -0,0 +1,20 @@
+; Copyright (C) 2016  Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+$TTL 1
+;      The TTL of all these records needs to be 1.
+@      1       SOA     ns4.one.tld. hostmaster.ns4.tld. 0 1 1 1 1
+@      1       NS      ns4.one.tld.
+ns4    1       A       10.53.0.4
+www    1       A       10.53.0.4
index 15c2906a9286292395f05b3cdc23b8a80b12c376..703bd43fb28dbf3f8b6ccbbb61e9f5787c5416d1 100644 (file)
@@ -16,7 +16,10 @@ SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
 
 status=0
-echo "I:check lookups against zero TTL records"
+n=0
+
+n=`expr $n + 1`
+echo "I:check lookups against TTL=0 records ($n)"
 i=0
 passes=10
 $DIG -p 5300 @10.53.0.2 axfr example | 
@@ -24,22 +27,49 @@ awk '$2 == "0" { print "-q", $1, $4; print "-q", "zzz"$1, $4;}' > query.list
 while [ $i -lt $passes ]
 do
        ret=0
-       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.1 &
-       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.2 &
-       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.3 &
-       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.4 &
-       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.5 &
-       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.6 &
+       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.1.test$n &
+       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.2.test$n &
+       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.3.test$n &
+       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.4.test$n &
+       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.5.test$n &
+       $DIG -p 5300 @10.53.0.3 -f query.list > dig.out$i.6.test$n &
        wait
-       grep "status: SERVFAIL" dig.out$i.1 && ret=1
-       grep "status: SERVFAIL" dig.out$i.2 && ret=1
-       grep "status: SERVFAIL" dig.out$i.3 && ret=1
-       grep "status: SERVFAIL" dig.out$i.5 && ret=1
-       grep "status: SERVFAIL" dig.out$i.6 && ret=1
-       grep "status: SERVFAIL" dig.out$i.6 && ret=1
+       grep "status: SERVFAIL" dig.out$i.1.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.2.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.3.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.4.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.5.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.6.test$n && ret=1
+       [ $ret = 1 ] && break
+       i=`expr $i + 1`
+       echo "I: successfully completed pass $i of $passes"
+done
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:check lookups against TTL=1 records ($n)"
+i=0
+passes=10
+while [ $i -lt $passes ]
+do
+       ret=0
+       $DIG -p 5300 @10.53.0.3 www.one.tld > dig.out$i.1.test$n
+       $DIG -p 5300 @10.53.0.3 www.one.tld > dig.out$i.2.test$n
+       $DIG -p 5300 @10.53.0.3 www.one.tld > dig.out$i.3.test$n
+       $DIG -p 5300 @10.53.0.3 www.one.tld > dig.out$i.4.test$n
+       $DIG -p 5300 @10.53.0.3 www.one.tld > dig.out$i.5.test$n
+       $DIG -p 5300 @10.53.0.3 www.one.tld > dig.out$i.6.test$n
+       grep "status: SERVFAIL" dig.out$i.1.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.2.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.3.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.4.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.5.test$n && ret=1
+       grep "status: SERVFAIL" dig.out$i.6.test$n && ret=1
        [ $ret = 1 ] && break
        i=`expr $i + 1`
        echo "I: successfully completed pass $i of $passes"
+       $PERL -e 'select(undef, undef, undef, 0.3);'
 done
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
index 80713da20dd9b068e6fb3560c68699cc74b7a020..1912c8478d2e40c6600abd484e943954e7d6bb6e 100644 (file)
@@ -451,6 +451,10 @@ struct acachectl {
 #define ZEROTTL(header) \
        (((header)->attributes & RDATASET_ATTR_ZEROTTL) != 0)
 
+#define ACTIVE(header, now) \
+       (((header)->rdh_ttl > (now)) || \
+        ((header)->rdh_ttl == (now) && ZEROTTL(header)))
+
 #define DEFAULT_NODE_LOCK_COUNT         7       /*%< Should be prime. */
 
 /*%
@@ -4334,8 +4338,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
        header_prev = NULL;
        for (header = node->data; header != NULL; header = header_next) {
                header_next = header->next;
-               if (header->rdh_ttl < search->now ||
-                   (header->rdh_ttl == search->now && !ZEROTTL(header))) {
+               if (!ACTIVE(header, search->now)) {
                        /*
                         * This rdataset is stale.  If no one else is
                         * using the node, we can clean it up right
@@ -4459,8 +4462,7 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
                     header != NULL;
                     header = header_next) {
                        header_next = header->next;
-                       if (header->rdh_ttl < search->now ||
-                           (header->rdh_ttl == search->now && !ZEROTTL(header))) {
+                       if (!ACTIVE(header, search->now)) {
                                /*
                                 * This rdataset is stale.  If no one else is
                                 * using the node, we can clean it up right
@@ -4637,8 +4639,7 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
                     header != NULL;
                     header = header_next) {
                        header_next = header->next;
-                       if (header->rdh_ttl < now ||
-                           (header->rdh_ttl == now && !ZEROTTL(header))) {
+                       if (!ACTIVE(header, now)) {
                                /*
                                 * This rdataset is stale.  If no one else is
                                 * using the node, we can clean it up right
@@ -5045,8 +5046,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
        header_prev = NULL;
        for (header = node->data; header != NULL; header = header_next) {
                header_next = header->next;
-               if (header->rdh_ttl < now ||
-                   (header->rdh_ttl == now && !ZEROTTL(header))) {
+               if (!ACTIVE(header, now)) {
                        /*
                         * This rdataset is stale.  If no one else is using the
                         * node, we can clean it up right now, otherwise we
@@ -5353,8 +5353,7 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
        header_prev = NULL;
        for (header = node->data; header != NULL; header = header_next) {
                header_next = header->next;
-               if (header->rdh_ttl < now ||
-                   (header->rdh_ttl == now && !ZEROTTL(header))) {
+               if (!ACTIVE(header, now)) {
                        /*
                         * This rdataset is stale.  If no one else is using the
                         * node, we can clean it up right now, otherwise we
@@ -5843,8 +5842,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
 
        for (header = rbtnode->data; header != NULL; header = header_next) {
                header_next = header->next;
-               if (header->rdh_ttl < now ||
-                   (header->rdh_ttl == now && !ZEROTTL(header))) {
+               if (!ACTIVE(header, now)) {
                        if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
                            (locktype == isc_rwlocktype_write ||
                             NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
@@ -6169,7 +6167,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                        }
                        }
                        if (topheader != NULL && EXISTS(topheader) &&
-                           topheader->rdh_ttl >= now) {
+                           ACTIVE(topheader, now)) {
                                /*
                                 * Found one.
                                 */
@@ -6235,7 +6233,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                 * has no effect, provided that the cache data isn't stale.
                 */
                if (rbtversion == NULL && trust < header->trust &&
-                   (header->rdh_ttl >= now || header_nx)) {
+                   (ACTIVE(header, now) || header_nx)) {
                        free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
                        if (addedrdataset != NULL)
                                bind_rdataset(rbtdb, rbtnode, header, now,
@@ -6305,7 +6303,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                 * Don't lower trust of existing record if the
                 * update is forced.
                 */
-               if (IS_CACHE(rbtdb) && header->rdh_ttl >= now &&
+               if (IS_CACHE(rbtdb) && ACTIVE(header, now) &&
                    header->type == dns_rdatatype_ns &&
                    !header_nx && !newheader_nx &&
                    header->trust >= newheader->trust &&
@@ -6341,7 +6339,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                 * to be no more than the current NS RRset's TTL.  This
                 * ensures the delegations that are withdrawn are honoured.
                 */
-               if (IS_CACHE(rbtdb) && header->rdh_ttl >= now &&
+               if (IS_CACHE(rbtdb) && ACTIVE(header, now) &&
                    header->type == dns_rdatatype_ns &&
                    !header_nx && !newheader_nx &&
                    header->trust <= newheader->trust) {
@@ -6349,7 +6347,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                newheader->rdh_ttl = header->rdh_ttl;
                        }
                }
-               if (IS_CACHE(rbtdb) && header->rdh_ttl >= now &&
+               if (IS_CACHE(rbtdb) && ACTIVE(header, now) &&
                    (header->type == dns_rdatatype_a ||
                     header->type == dns_rdatatype_aaaa ||
                     header->type == dns_rdatatype_ds ||