]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[v9_9] improve RRL handling of deferrals and slipped NXDOMAIN
authorEvan Hunt <each@isc.org>
Sat, 8 Jun 2013 20:20:02 +0000 (13:20 -0700)
committerEvan Hunt <each@isc.org>
Sat, 8 Jun 2013 20:20:02 +0000 (13:20 -0700)
3590. [bug] When using RRL on recursive servers, defer
rate-limiting until after recursion is complete;
also, use correct rcode for slipped NXDOMAIN
responses.  [RT #33604]
(cherry picked from commit 89be55dc9040b119fd85bb33e7dc97d2ad454c6f)

CHANGES
bin/named/query.c
bin/tests/system/rrl/ns2/named.conf
bin/tests/system/rrl/tests.sh

diff --git a/CHANGES b/CHANGES
index 027447fde8446cf3fffbced90618257838b8c059..97f67d9cb03fe5446034b9e2d2a2206abe62f84a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+3590.  [bug]           When using RRL on recursive servers, defer
+                       rate-limiting until after recursion is complete;
+                       also, use correct rcode for slipped NXDOMAIN
+                       responses.  [RT #33604]
+
 3588.  [bug]           dig: addressed a memory leak in the sigchase code
                        that could cause a shutdown crash.  [RT #33733]
 
index 6917f076fe1ab8342f71b90ff120d98b5eab5153..c3d63a2003b51449131ed9d32357117fb2451db7 100644 (file)
@@ -5868,15 +5868,25 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
 #ifdef USE_RRL
        /*
         * Rate limit these responses to this client.
+        * Do not delay counting and handling obvious referrals,
+        *      since those won't come here again.
+        * Delay handling delegations for which we are certain to recurse and
+        *      return here (DNS_R_DELEGATION, not a child of one of our
+        *      own zones, and recursion enabled)
+        * Don't mess with responses rewritten by RPZ
+        * Count each response at most once.
         */
        if (client->view->rrl != NULL &&
            ((fname != NULL && dns_name_isabsolute(fname)) ||
             (result == ISC_R_NOTFOUND && !RECURSIONOK(client))) &&
+           !(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) &&
+           (client->query.rpz_st == NULL ||
+            (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0)&&
            (client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0) {
                dns_rdataset_t nc_rdataset;
                isc_boolean_t wouldlog;
                char log_buf[DNS_RRL_LOG_BUF_LEN];
-               isc_result_t nc_result;
+               isc_result_t nc_result, resp_result;
                dns_rrl_result_t rrl_result;
 
                client->query.attributes |= NS_QUERYATTR_RRL_CHECKED;
@@ -5889,7 +5899,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                         */
                        if (db != NULL)
                                tname = dns_db_origin(db);
-                       rrl_result = result;
+                       resp_result = result;
                } else if (result == DNS_R_NCACHENXDOMAIN &&
                           rdataset != NULL &&
                           dns_rdataset_isassociated(rdataset) &&
@@ -5913,12 +5923,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                                }
                                dns_rdataset_disassociate(&nc_rdataset);
                        }
-                       rrl_result = DNS_R_NXDOMAIN;
+                       resp_result = DNS_R_NXDOMAIN;
                } else if (result == DNS_R_NXRRSET ||
                           result == DNS_R_EMPTYNAME) {
-                       rrl_result = DNS_R_NXRRSET;
+                       resp_result = DNS_R_NXRRSET;
                } else if (result == DNS_R_DELEGATION) {
-                       rrl_result = result;
+                       resp_result = result;
                } else if (result == ISC_R_NOTFOUND) {
                        /*
                         * Handle referral to ".", including when recursion
@@ -5926,15 +5936,15 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                         * been loaded or we have "additional-from-cache no".
                         */
                        tname = dns_rootname;
-                       rrl_result = DNS_R_DELEGATION;
+                       resp_result = DNS_R_DELEGATION;
                } else {
-                       rrl_result = ISC_R_SUCCESS;
+                       resp_result = ISC_R_SUCCESS;
                }
                rrl_result = dns_rrl(client->view, &client->peeraddr,
                                     ISC_TF((client->attributes
                                             & NS_CLIENTATTR_TCP) != 0),
                                     client->message->rdclass, qtype, tname,
-                                    rrl_result, client->now,
+                                    resp_result, client->now,
                                     wouldlog, log_buf, sizeof(log_buf));
                if (rrl_result != DNS_RRL_RESULT_OK) {
                        /*
@@ -5972,6 +5982,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                                                dns_nsstatscounter_rateslipped);
                                        client->message->flags |=
                                                DNS_MESSAGEFLAG_TC;
+                                       if (resp_result == DNS_R_NXDOMAIN)
+                                               client->message->rcode =
+                                                       dns_rcode_nxdomain;
                                }
                                goto cleanup;
                        }
index 969532556a64892e20e36beb11e3bdf72bc394d6..de00d7691415c6589ea372953cfcf7d57b6b09b1 100644 (file)
@@ -31,7 +31,7 @@ options {
 
        rate-limit {
            responses-per-second 2;
-           all-per-second 70;
+           all-per-second 50;
            slip 3;
            exempt-clients { 10.53.0.7; };
 
index 6d77480739be58b2c2d82cb9e424e3c4ed269898..8c60c7232e25c7467b0a786bd0a34c4caba92e87 100644 (file)
@@ -19,7 +19,6 @@ SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
 
 #set -x
-#set -o noclobber
 
 ns1=10.53.0.1                      # root, defining the others
 ns2=10.53.0.2                      # test server
@@ -90,22 +89,16 @@ digcmd () {
 
 
 #   $1=number of tests  $2=target domain  $3=dig options
-CNT=1
+QNUM=1
 burst () {
     BURST_LIMIT=$1; shift
     BURST_DOM_BASE="$1"; shift
     while test "$BURST_LIMIT" -ge 1; do
-       if test $CNT -lt 10; then
-           CNT="00$CNT"
-       else
-           if test $CNT -lt 100; then
-               CNT="0$CNT"
-           fi
-       fi
+       CNT=`expr "00$QNUM" : '.*\(...\)'`
        eval BURST_DOM="$BURST_DOM_BASE"
        FILE="dig.out-$BURST_DOM-$CNT"
        digcmd $FILE $BURST_DOM $* &
-       CNT=`expr $CNT + 1`
+       QNUM=`expr $QNUM + 1`
        BURST_LIMIT=`expr "$BURST_LIMIT" - 1`
     done
 }
@@ -116,29 +109,32 @@ burst () {
 ck_result() {
     BAD=
     wait
-    ADDRS=`ls dig.out-$1-*=$2          2>/dev/null     | wc -l | tr -d ' '`
-    TC=`ls dig.out-$1-*=TC             2>/dev/null     | wc -l | tr -d ' '`
-    DROP=`ls dig.out-$1-*=drop         2>/dev/null     | wc -l | tr -d ' '`
-    NXDOMAIN=`ls dig.out-$1-*=NXDOMAIN 2>/dev/null     | wc -l | tr -d ' '`
-    SERVFAIL=`ls dig.out-$1-*=SERVFAIL 2>/dev/null     | wc -l | tr -d ' '`
+    ADDRS=`ls dig.out-$1-*=$2                          2>/dev/null | wc -l`
+    # count simple truncated and truncated NXDOMAIN as TC
+    TC=`ls dig.out-$1-*=TC dig.out-$1-*=NXDOMAINTC     2>/dev/null | wc -l`
+    DROP=`ls dig.out-$1-*=drop                         2>/dev/null | wc -l`
+    # count NXDOMAIN and truncated NXDOMAIN as NXDOMAIN
+    NXDOMAIN=`ls dig.out-$1-*=NXDOMAIN  dig.out-$1-*=NXDOMAINTC        2>/dev/null \
+                                                       | wc -l`
+    SERVFAIL=`ls dig.out-$1-*=SERVFAIL                 2>/dev/null | wc -l`
     if test $ADDRS -ne "$3"; then
-       setret "I:$ADDRS instead of $3 '$2' responses for $1"
+       setret "I:"$ADDRS" instead of $3 '$2' responses for $1"
        BAD=yes
     fi
     if test $TC -ne "$4"; then
-       setret "I:$TC instead of $4 truncation responses for $1"
+       setret "I:"$TC" instead of $4 truncation responses for $1"
        BAD=yes
     fi
     if test $DROP -ne "$5"; then
-       setret "I:$DROP instead of $5 dropped responses for $1"
+       setret "I:"$DROP" instead of $5 dropped responses for $1"
        BAD=yes
     fi
     if test $NXDOMAIN -ne "$6"; then
-       setret "I:$NXDOMAIN instead of $6 NXDOMAIN responses for $1"
+       setret "I:"$NXDOMAIN" instead of $6 NXDOMAIN responses for $1"
        BAD=yes
     fi
     if test $SERVFAIL -ne "$7"; then
-       setret "I:$SERVFAIL instead of $7 error responses for $1"
+       setret "I:"$SERVFAIL" instead of $7 error responses for $1"
        BAD=yes
     fi
     if test -z "$BAD"; then
@@ -151,11 +147,11 @@ ckstats () {
     LABEL="$1"; shift
     TYPE="$1"; shift
     EXPECTED="$1"; shift
-    CNT=`sed -n -e "s/[         ]*\([0-9]*\).responses $TYPE for rate limits.*/\1/p"  \
+    C=`sed -n -e "s/[   ]*\([0-9]*\).responses $TYPE for rate limits.*/\1/p"  \
            ns2/named.stats | tail -1`
-    CNT=`expr 0$CNT + 0`
-    if test "$CNT" -ne $EXPECTED; then
-       setret "I:wrong $LABEL $TYPE statistics of $CNT instead of $EXPECTED"
+    C=`expr 0$C + 0`
+    if test "$C" -ne $EXPECTED; then
+       setret "I:wrong $LABEL $TYPE statistics of $C instead of $EXPECTED"
     fi
 }
 
@@ -170,7 +166,7 @@ burst 5 a1.tld3 +norec
 burst 3 a1.tld2
 # 1 second delay allows an additional response.
 sleep 1
-burst 21 a1.tld2
+burst 10 a1.tld2
 # Request 30 different qnames to try a wildcard.
 burst 30 'x$CNT.a2.tld2'
 # These should be counted and limited but are not.  See RT33138.
@@ -179,8 +175,8 @@ burst 10 'y.x$CNT.a2.tld2'
 #                                      IP      TC      drop  NXDOMAIN SERVFAIL
 # referrals to "."
 ck_result   a1.tld3    ''              2       1       2       0       0
-# check 24 results including 1 second delay that allows an additional response
-ck_result   a1.tld2    192.0.2.1       3       7       14      0       0
+# check 13 results including 1 second delay that allows an additional response
+ck_result   a1.tld2    192.0.2.1       3       4       6       0       0
 
 # Check the wild card answers.
 # The parent name of the 30 requests is counted.
@@ -192,64 +188,68 @@ ck_result 'y.x*.a2.tld2' 192.0.2.2        10      0       0       0       0
 #########
 sec_start
 
-burst 1 'y$CNT.a3.tld3'; wait; burst 20 'y$CNT.a3.tld3'
-burst 20 'z$CNT.a4.tld2'
+burst 10 'x.a3.tld3'
+burst 10 'y$CNT.a3.tld3'
+burst 10 'z$CNT.a4.tld2'
+
+# 10 identical recursive responses are limited
+ck_result 'x.a3.tld3'  192.0.3.3       2       3       5       0       0
 
-# Recursion.
-#   The first answer is counted separately because it is counted against
-#   the rate limit on recursing to the server for a3.tld3.  The remaining 20
-#   are counted as local responses from the cache.
-ck_result 'y*.a3.tld3' 192.0.3.3       3       6       12      0       0
+# 10 different recursive responses are not limited
+ck_result 'y*.a3.tld3' 192.0.3.3       10      0       0       0       0
 
-# NXDOMAIN responses are also limited based on the parent name.
-ck_result 'z*.a4.tld2' x               0       6       12      2       0
+# 10 different NXDOMAIN responses are limited based on the parent name.
+#   We count 13 responses because we count truncated NXDOMAIN responses
+#   as both truncated and NXDOMAIN.
+ck_result 'z*.a4.tld2' x               0       3       5       5       0
 
 $RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats
-ckstats first dropped 58
-ckstats first truncated 30
+ckstats first dropped 36
+ckstats first truncated 21
 
 
 #########
 sec_start
 
-burst 20 a5.tld2 +tcp
-burst 20 a6.tld2 -b $ns7
-burst 20 a7.tld4
+burst 10 a5.tld2 +tcp
+burst 10 a6.tld2 -b $ns7
+burst 10 a7.tld4
 burst 2 a8.tld2 AAAA
 burst 2 a8.tld2 TXT
 burst 2 a8.tld2 SPF
 
+#                                      IP      TC      drop  NXDOMAIN SERVFAIL
 # TCP responses are not rate limited
-ck_result a5.tld2      192.0.2.5       20      0       0       0       0
+ck_result a5.tld2      192.0.2.5       10      0       0       0       0
 
 # whitelisted client is not rate limited
-ck_result a6.tld2      192.0.2.6       20      0       0       0       0
+ck_result a6.tld2      192.0.2.6       10      0       0       0       0
 
-# Errors such as SERVFAIL are rate limited.  The numbers are confusing, because
-#   other rate limiting can be triggered before the SERVFAIL limit is reached.
-ck_result a7.tld4      192.0.2.1       0       6       12      0       2
+# Errors such as SERVFAIL are rate limited.
+ck_result a7.tld4      x               0       0       8       0       2
 
 # NODATA responses are counted as the same regardless of qtype.
 ck_result a8.tld2      ''              2       2       2       0       0
 
 $RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats
-ckstats second dropped 72
-ckstats second truncated 38
+ckstats second dropped 46
+ckstats second truncated 23
 
 
 #########
 sec_start
 
+#                                      IP      TC      drop  NXDOMAIN SERVFAIL
 # all-per-second
 #   The qnames are all unique but the client IP address is constant.
-CNT=101
-burst 80 'all$CNT.a9.tld2'
+QNUM=101
+burst 60 'all$CNT.a9.tld2'
 
-ck_result 'a*.a9.tld2' 192.0.2.8       70      0       10      0       0
+ck_result 'a*.a9.tld2' 192.0.2.8       50      0       10      0       0
 
 $RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats
-ckstats final dropped 82
-ckstats final truncated 38
+ckstats final dropped 56
+ckstats final truncated 23
 
 
 echo "I:exit status: $ret"