]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[v9_9_6_patch] add max-recursion-queries
authorEvan Hunt <each@isc.org>
Wed, 19 Nov 2014 06:17:37 +0000 (22:17 -0800)
committerEvan Hunt <each@isc.org>
Wed, 19 Nov 2014 06:17:37 +0000 (22:17 -0800)
also fixes and documentation for max-recursion-depth

(cherry picked from commit c4f54e5bd1cd09f601252627b5b26768ab797742)
(cherry picked from commit b3aa528d7e4df70a2b1e473faa9721347567f920)
(cherry picked from commit 711e833921d3dd67df7515438e152bbfdb2c1249)

26 files changed:
CHANGES
bin/named/config.c
bin/named/server.c
bin/tests/system/conf.sh.in
bin/tests/system/many/clean.sh [deleted file]
bin/tests/system/many/ns4/named.conf [deleted file]
bin/tests/system/many/ns5/hints.db [deleted file]
bin/tests/system/many/setup.sh [deleted file]
bin/tests/system/many/tests.sh [deleted file]
bin/tests/system/reclimit/README [new file with mode: 0644]
bin/tests/system/reclimit/ans2/ans.pl [new file with mode: 0644]
bin/tests/system/reclimit/clean.sh [new file with mode: 0644]
bin/tests/system/reclimit/ns1/named.conf [moved from bin/tests/system/many/ns1/named.conf with 89% similarity]
bin/tests/system/reclimit/ns1/root.db [new file with mode: 0644]
bin/tests/system/reclimit/ns3/.gitignore [new file with mode: 0644]
bin/tests/system/reclimit/ns3/hints.db [new file with mode: 0644]
bin/tests/system/reclimit/ns3/named1.conf [moved from bin/tests/system/many/ns5/named.conf with 73% similarity]
bin/tests/system/reclimit/ns3/named2.conf [moved from bin/tests/system/many/ns3/named.conf with 79% similarity]
bin/tests/system/reclimit/ns3/named3.conf [moved from bin/tests/system/many/ns2/named.conf with 70% similarity]
bin/tests/system/reclimit/ns3/named4.conf [new file with mode: 0644]
bin/tests/system/reclimit/setup.sh [new file with mode: 0644]
bin/tests/system/reclimit/tests.sh [new file with mode: 0644]
doc/arm/Bv9ARM-book.xml
lib/dns/include/dns/resolver.h
lib/dns/resolver.c
lib/isccfg/namedconf.c

diff --git a/CHANGES b/CHANGES
index 69aea991925e3f59a0d15e50979edac9722e1781..bb083446576eb474d58258d0f25812e72b06d3bf 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,7 +7,8 @@
                        query (CVE-2014-8500).
 
                        The recursion depth limit is configured via the
-                       "max-recursion-depth" option.  [RT #37580]
+                       "max-recursion-depth" option, and the query limit
+                        via the "max-recursion-queries" option.  [RT #37580]
 
        --- 9.9.6 released ---
 
index 5ee8c4ee661957f0fd7d42b2e0bdb52cf23213ab..ebc48cfc464eca84a0fbb86cda7bd8a9cf85a5fc 100644 (file)
@@ -159,6 +159,7 @@ options {\n\
        clients-per-query 10;\n\
        max-clients-per-query 100;\n\
        max-recursion-depth 7;\n\
+       max-recursion-queries 50;\n\
        zero-no-soa-ttl-cache no;\n\
        nsec3-test-zone no;\n\
        allow-new-zones no;\n\
index 62ea032223855e599325035707daf1ea068da139..84e3ecf32108601a116294eeeae86f20d0e8d22b 100644 (file)
@@ -3163,6 +3163,11 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
        INSIST(result == ISC_R_SUCCESS);
        dns_resolver_setmaxdepth(view->resolver, cfg_obj_asuint32(obj));
 
+       obj = NULL;
+       result = ns_config_get(maps, "max-recursion-queries", &obj);
+       INSIST(result == ISC_R_SUCCESS);
+       dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj));
+
 #ifdef ALLOW_FILTER_AAAA_ON_V4
        obj = NULL;
        result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
index 06c212b291b3751411642a0ff4a2360281f6d76c..2745c1f46edf2c8b2f18459cb6ffa3a7de9ea0fa 100644 (file)
@@ -67,8 +67,8 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
         @COVERAGE@ database dlv dlvauto dlz dlzexternal dname dns64
         dnssec ecdsa emptyzones filter-aaaa formerr forward glue
         gost ixfr inline limits logfileconfig lwresd masterfile
-        masterformat metadata notify nslookup nsupdate pending
-        pkcs11 redirect resolver rndc rpz rrl rrsetorder rsabigexponent
+        masterformat metadata notify nslookup nsupdate pending pkcs11
+        reclimit redirect resolver rndc rpz rrl rrsetorder rsabigexponent
         smartsign sortlist spf staticstub stub tkey tsig tsiggss
         unknown upforwd verify views wildcard xfer xferquota zero
         zonechecks"
diff --git a/bin/tests/system/many/clean.sh b/bin/tests/system/many/clean.sh
deleted file mode 100644 (file)
index 119b1f5..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-rm -f ns1/[1-9]*example.tld?.db
-rm -f ns2/[1-9]*example.tld?.db
-rm -f ns1/zones.conf
-rm -f ns2/zones.conf
-rm -f */root.db
-rm -f ns3/tld1.db
-rm -f ns4/tld2.db
diff --git a/bin/tests/system/many/ns4/named.conf b/bin/tests/system/many/ns4/named.conf
deleted file mode 100644 (file)
index ca9aa6a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014  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.
- */
-
-controls { /* empty */ };
-
-options {
-       query-source address 10.53.0.4;
-       notify-source 10.53.0.4;
-       transfer-source 10.53.0.4;
-       port 5300;
-       pid-file "named.pid";
-       listen-on { 10.53.0.4; };
-       listen-on-v6 { none; };
-       recursion no;
-};
-
-zone "tld2" { type master; file "tld2.db"; };
diff --git a/bin/tests/system/many/ns5/hints.db b/bin/tests/system/many/ns5/hints.db
deleted file mode 100644 (file)
index c05809b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-. 60 in ns ns.nil.
-ns.nil. 60 in A 10.53.0.3
diff --git a/bin/tests/system/many/setup.sh b/bin/tests/system/many/setup.sh
deleted file mode 100644 (file)
index 80695b5..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-i=1
-
-cat > ns3/root.db << EOF
-. 60 in soa ns.nil. hostmaster.ns.nil. 1 0 0 0 0
-. 60 in ns ns.nil.
-ns.nil. 60 in a 10.53.0.3
-tld1. 60 in ns ns.tld1.
-ns.tld1. 60 in a 10.53.0.3
-tld2. 60 in ns ns.tld2.
-ns.tld2. 60 in a 10.53.0.4
-EOF
-
-cat > ns3/tld1.db << EOF
-tld1. 60 in soa ns.tld1. hostmaster.ns.tld1. 1 0 0 0 0
-tld1. 60 in ns ns.tld1.
-ns.tld1. 60 in a 10.53.0.1
-EOF
-
-cat > ns4/tld2.db << EOF
-tld2. 60 in soa ns.tld2. hostmaster.ns.tld4. 1 0 0 0 0
-tld2. 60 in ns ns.tld2.
-ns.tld2. 60 in a 10.53.0.1
-EOF
-
-: > ns1/zones.conf
-: > ns2/zones.conf
-
-while [ $i -lt 1000 ]
-do
-j=`expr $i + 1`
-s=`expr $j % 2 + 1`
-n=`expr $i % 2 + 1`
-t=`expr $s + 2`
-
-# i=1 j=2 s=1 n=2
-# i=2 j=3 s=1 n=2
-# i=3 j=4 s=1 n=2
-
-cat > ns1/${i}example.tld${s}.db << EOF
-${i}example.tld${s}. 60 in soa ns.${j}example.tld${n}. hostmaster 1 0 0 0 0
-${i}example.tld${s}. 60 in ns ns.${j}example.tld${n}.
-ns.${i}example.tld${s}. 60 in a 10.53.0.1
-EOF
-
-cat >> ns1/zones.conf << EOF
-zone "${i}example.tld${s}" { type master; file "${i}example.tld${s}.db"; };
-EOF
-
-cat >> ns${t}/tld${s}.db << EOF
-${i}example.tld${s}. 60 in ns ns.${j}example.tld${n}.
-EOF
-
-i=$j
-
-done
-
-j=`expr $i + 1`
-s=`expr $j % 2 + 1`
-n=`expr $s % 2 + 1`
-t=`expr $s + 2`
-
-cat > ns1/${i}example.tld${s}.db << EOF
-${i}example.tld${s}. 60 in soa ns.${i}example.tld${s}. hostmaster 1 0 0 0 0
-${i}example.tld${s}. 60 in ns ns.${i}example.tld${s}.
-ns.${i}example.tld${s}. 60 in a 10.53.0.1
-EOF
-
-cat >> ns1/zones.conf << EOF
-zone "${i}example.tld${s}" { type master; file "${i}example.tld${s}.db"; };
-EOF
-
-cat >> ns${t}/tld${s}.db << EOF
-${i}example.tld${s}. 60 in ns ns.${i}example.tld${s}.
-ns.${i}example.tld${s}. 60 in a 10.53.0.1
-EOF
diff --git a/bin/tests/system/many/tests.sh b/bin/tests/system/many/tests.sh
deleted file mode 100644 (file)
index 37964e2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh
-#
-# Copyright (C) 2014  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.
-
-SYSTEMTESTTOP=..
-. $SYSTEMTESTTOP/conf.sh
-
-status=0
-n=0
-
-n=`expr $n + 1`
-echo "I: attempt lookup 1example.tld2 soa ($n)"
-ret=0
-$DIG +tcp 1example.tld1 soa @10.53.0.5 -p 5300  > dig.out.test$n
-grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
-if [ $ret != 0 ]; then echo "I:failed"; fi
-status=`expr $status + $ret`
-
-n=`expr $n + 1`
-echo "I: attempt lookup 992example.tld2 soa ($n)"
-ret=0
-$DIG +tcp 992example.tld2 soa @10.53.0.5 -p 5300 >  dig.out.test$n
-grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
-if [ $ret != 0 ]; then echo "I:failed"; fi
-status=`expr $status + $ret`
-
-n=`expr $n + 1`
-echo "I: attempt lookup 993example.tld1 soa ($n)"
-ret=0
-$DIG +tcp 993example.tld1 soa @10.53.0.5 -p 5300 >  dig.out.test$n
-grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
-if [ $ret != 0 ]; then echo "I:failed"; fi
-status=`expr $status + $ret`
-
-echo "I:exit status: $status"
-exit $status
diff --git a/bin/tests/system/reclimit/README b/bin/tests/system/reclimit/README
new file mode 100644 (file)
index 0000000..b802a05
--- /dev/null
@@ -0,0 +1,6 @@
+system test for recursion limits
+
+ns1  -- root server
+ans2 -- delegate to ns1.(n+1).example.com for all n, up to
+        the value specified in ans.limit
+ns3  -- resolver under test
diff --git a/bin/tests/system/reclimit/ans2/ans.pl b/bin/tests/system/reclimit/ans2/ans.pl
new file mode 100644 (file)
index 0000000..a6e39a6
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use IO::File;
+use Getopt::Long;
+use Net::DNS::Nameserver;
+
+my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
+print $pidf "$$\n" or die "cannot write pid file: $!";
+$pidf->close or die "cannot close pid file: $!";
+sub rmpid { unlink "ans.pid"; exit 1; };
+
+$SIG{INT} = \&rmpid;
+$SIG{TERM} = \&rmpid;
+
+my $count = 0;
+my $send_response = 0;
+
+sub getlimit {
+    if ( -e "ans.limit") {
+        open(FH, "<", "ans.limit");
+        my $line = <FH>;
+        chomp $line;
+        close FH;
+        if ($line =~ /^\d+$/) {
+            return $line;
+        }
+    }
+
+    return 0;
+}
+
+my $localaddr = "10.53.0.2";
+my $localport = 5300;
+my $verbose = 0;
+my $limit = getlimit();
+
+sub reply_handler {
+    my ($qname, $qclass, $qtype, $peerhost, $query, $conn) = @_;
+    my ($rcode, @ans, @auth, @add);
+
+    print ("request: $qname/$qtype\n");
+    STDOUT->flush();
+
+    $count += 1;
+
+    if ($qname eq "count" ) {
+        if ($qtype eq "TXT") {
+            my ($ttl, $rdata) = (0, "$count");
+            my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
+            push @ans, $rr;
+            print ("\tcount: $count\n");
+        }
+        $rcode = "NOERROR";
+    } elsif ($qname eq "reset" ) {
+        $count = 0;
+        $send_response = 0;
+        $limit = getlimit();
+        $rcode = "NOERROR";
+        print ("\tlimit: $limit\n");
+    } elsif ($qname eq "direct.example.org" ) {
+        if ($qtype eq "A") {
+            my ($ttl, $rdata) = (3600, $localaddr);
+            my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
+            push @ans, $rr;
+        }
+        $rcode = "NOERROR";
+    } elsif ($qname eq "indirect.example.org") {
+        if (! $send_response) {
+            my $rr = new Net::DNS::RR("indirect.example.org 86400 $qclass NS ns1.1.example.org");
+            push @auth, $rr;
+        } elsif ($qtype eq "A") {
+            my ($ttl, $rdata) = (3600, $localaddr);
+            my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
+            push @ans, $rr;
+        } 
+        $rcode = "NOERROR";
+    } elsif ($qname =~ /^ns1\.(\d+)\.example\.org$/) {
+        my $next = $1 + 1;
+        if ($limit == 0 || (! $send_response && $next <= $limit)) {
+            my $rr = new Net::DNS::RR("$1.example.org 86400 $qclass NS ns1.$next.example.org");
+            push @auth, $rr;
+        } else {
+            $send_response = 1;
+            if ($qtype eq "A") {
+                my ($ttl, $rdata) = (3600, $localaddr);
+                my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
+print("\tresponse: $qname $ttl $qclass $qtype $rdata\n");
+                push @ans, $rr;
+            }
+        }
+        $rcode = "NOERROR";
+    } else {
+        $rcode = "NXDOMAIN";
+    }
+
+    # mark the answer as authoritive (by setting the 'aa' flag
+    return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
+}
+
+GetOptions(
+    'port=i' => \$localport,
+    'verbose!' => \$verbose,
+);
+
+my $ns = Net::DNS::Nameserver->new(
+    LocalAddr => $localaddr,
+    LocalPort => $localport,
+    ReplyHandler => \&reply_handler,
+    Verbose => $verbose,
+);
+
+$ns->main_loop;
diff --git a/bin/tests/system/reclimit/clean.sh b/bin/tests/system/reclimit/clean.sh
new file mode 100644 (file)
index 0000000..b48874a
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Copyright (C) 2014  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.
+
+rm -f dig.out*
+rm -f ans2/ans.limit
+rm -f ns3/named.conf
similarity index 89%
rename from bin/tests/system/many/ns1/named.conf
rename to bin/tests/system/reclimit/ns1/named.conf
index abc9dca4bc1f30f16f057155b6dcdddb5cbd8f25..5e1c947d10278739328a0673a9c085fb1a9a9af0 100644 (file)
@@ -17,6 +17,7 @@
 controls { /* empty */ };
 
 options {
+       directory ".";
        query-source address 10.53.0.1;
        notify-source 10.53.0.1;
        transfer-source 10.53.0.1;
@@ -27,7 +28,4 @@ options {
        recursion no;
 };
 
-include "zones.conf";
-
-// zone "tld1" { type master; file "tld1.db"; };
-// zone "tld2" { type master; file "tld2.db"; };
+zone "." { type master; file "root.db"; };
diff --git a/bin/tests/system/reclimit/ns1/root.db b/bin/tests/system/reclimit/ns1/root.db
new file mode 100644 (file)
index 0000000..8e706b2
--- /dev/null
@@ -0,0 +1,20 @@
+; Copyright (C) 2014  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.
+
+. 60 IN SOA ns.nil. hostmaster.ns.nil. 1 0 0 0 0
+. 60 IN NS ns.nil.
+ns.nil. 60 IN A 10.53.0.1
+ns.tld1. 60 IN A 10.53.0.1
+example.org. 60 IN NS direct.example.org.
+direct.example.org. 60 IN A 10.53.0.2
diff --git a/bin/tests/system/reclimit/ns3/.gitignore b/bin/tests/system/reclimit/ns3/.gitignore
new file mode 100644 (file)
index 0000000..58e5c92
--- /dev/null
@@ -0,0 +1 @@
+named.conf
diff --git a/bin/tests/system/reclimit/ns3/hints.db b/bin/tests/system/reclimit/ns3/hints.db
new file mode 100644 (file)
index 0000000..2ea27ca
--- /dev/null
@@ -0,0 +1,16 @@
+; Copyright (C) 2014  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.
+
+. 60 IN NS ns.nil.
+ns.nil. 60 IN A 10.53.0.1
similarity index 73%
rename from bin/tests/system/many/ns5/named.conf
rename to bin/tests/system/reclimit/ns3/named1.conf
index fce7d5925f526107d04432922cb07417e5b947e7..558c230a5cea11e04f766b3b8fc32e75b0d17280 100644 (file)
 controls { /* empty */ };
 
 options {
-       query-source address 10.53.0.5;
-       notify-source 10.53.0.5;
-       transfer-source 10.53.0.5;
+       directory ".";
+       query-source address 10.53.0.3;
+       notify-source 10.53.0.3;
+       transfer-source 10.53.0.3;
        port 5300;
        pid-file "named.pid";
-       listen-on { 10.53.0.5; };
+       listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
+        servfail-ttl 0;
+        max-recursion-depth 12;
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
 };
 
 zone "." { type hint; file "hints.db"; };
similarity index 79%
rename from bin/tests/system/many/ns3/named.conf
rename to bin/tests/system/reclimit/ns3/named2.conf
index b950afe9c7af529412c35b05edb58cd6d98e06bd..eb1fa09f632e552ca75684b2fd7d294ba7e3e39c 100644 (file)
@@ -17,6 +17,7 @@
 controls { /* empty */ };
 
 options {
+       directory ".";
        query-source address 10.53.0.3;
        notify-source 10.53.0.3;
        transfer-source 10.53.0.3;
@@ -24,9 +25,17 @@ options {
        pid-file "named.pid";
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
-       recursion no;
+        servfail-ttl 0;
+        max-recursion-depth 5;
 };
 
-zone "." { type master; file "root.db"; };
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
+};
 
-zone "tld1" { type master; file "tld1.db"; };
+zone "." { type hint; file "hints.db"; };
similarity index 70%
rename from bin/tests/system/many/ns2/named.conf
rename to bin/tests/system/reclimit/ns3/named3.conf
index 16266e225aadd18baf856b3c41da9e8c0ef5df5c..1c3679a89e8a513f216812690fa3cf4f2c36c357 100644 (file)
 controls { /* empty */ };
 
 options {
-       query-source address 10.53.0.2;
-       notify-source 10.53.0.2;
-       transfer-source 10.53.0.2;
+       directory ".";
+       query-source address 10.53.0.3;
+       notify-source 10.53.0.3;
+       transfer-source 10.53.0.3;
        port 5300;
        pid-file "named.pid";
-       listen-on { 10.53.0.2; };
+       listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
-       recursion no;
+        servfail-ttl 0;
+        max-recursion-depth 100;
 };
 
-include "zones.conf";
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
+};
+
+zone "." { type hint; file "hints.db"; };
diff --git a/bin/tests/system/reclimit/ns3/named4.conf b/bin/tests/system/reclimit/ns3/named4.conf
new file mode 100644 (file)
index 0000000..46da448
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014  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.
+ */
+
+controls { /* empty */ };
+
+options {
+       directory ".";
+       query-source address 10.53.0.3;
+       notify-source 10.53.0.3;
+       transfer-source 10.53.0.3;
+       port 5300;
+       pid-file "named.pid";
+       listen-on { 10.53.0.3; };
+       listen-on-v6 { none; };
+        servfail-ttl 0;
+        max-recursion-depth 100;
+        max-recursion-queries 40;
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
+};
+
+zone "." { type hint; file "hints.db"; };
diff --git a/bin/tests/system/reclimit/setup.sh b/bin/tests/system/reclimit/setup.sh
new file mode 100644 (file)
index 0000000..f4adda2
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# Copyright (C) 2014  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.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+cp -f ns3/named1.conf ns3/named.conf
diff --git a/bin/tests/system/reclimit/tests.sh b/bin/tests/system/reclimit/tests.sh
new file mode 100644 (file)
index 0000000..f67da3e
--- /dev/null
@@ -0,0 +1,154 @@
+#!/bin/sh
+#
+# Copyright (C) 2014  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.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+DIGOPTS="-p 5300"
+
+status=0
+n=0
+
+n=`expr $n + 1`
+echo "I: attempt excessive-depth lookup ($n)"
+ret=0
+echo "1000" > ans2/ans.limit
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 26 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: attempt permissible lookup ($n)"
+ret=0
+echo "12" > ans2/ans.limit
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 49 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:reset max-recursion-depth"
+cp ns3/named2.conf ns3/named.conf
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 reconfig 2>&1 | sed 's/^/I:ns1 /'
+sleep 2
+
+n=`expr $n + 1`
+echo "I: attempt excessive-depth lookup ($n)"
+ret=0
+echo "12" > ans2/ans.limit
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 12 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: attempt permissible lookup ($n)"
+ret=0
+echo "5" > ans2/ans.limit
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 21 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:reset max-recursion-depth"
+cp ns3/named3.conf ns3/named.conf
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 reconfig 2>&1 | sed 's/^/I:ns1 /'
+sleep 2
+
+n=`expr $n + 1`
+echo "I: attempt excessive-queries lookup ($n)"
+ret=0
+echo "25" > ans2/ans.limit
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
+grep "exceeded max queries resolving 'indirect.example.org/A'" ns3/named.run > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 100 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: attempt permissible lookup ($n)"
+ret=0
+echo "24" > ans2/ans.limit
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 97 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:reset max-recursion-queries"
+cp ns3/named4.conf ns3/named.conf
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 reconfig 2>&1 | sed 's/^/I:ns1 /'
+sleep 2
+
+n=`expr $n + 1`
+echo "I: attempt excessive-queries lookup ($n)"
+ret=0
+echo "21" > ans2/ans.limit
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
+grep "exceeded max queries resolving 'indirect.example.org/A'" ns3/named.run > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 84 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: attempt permissible lookup ($n)"
+ret=0
+echo "19" > ans2/ans.limit
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
+$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
+$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
+grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
+$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
+eval count=`cat dig.out.2.test$n`
+[ $count -eq 77 ] || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:exit status: $status"
+exit $status
index 68a12408aa1a217e9f7bc9285a511f995a816700..044c1d578ded4d7d86bf85ad4646594d90f3bf1d 100644 (file)
@@ -8684,8 +8684,26 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
              <listitem>
                <para>
                  Sets the maximum number of levels of recursion
-                 permitted at any one time while resolving a name.
-                 The default is 7.
+                 that are permitted at any one time while servicing
+                 a recursive query. Resolving a name may require
+                 looking up a name server address, which in turn
+                 requires resolving another name, etc; if the number
+                 of indirections exceeds this value, the recursive
+                 query is terminated and returns SERVFAIL.  The
+                 default is 7.
+               </para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry id="max-recursion-queries">
+             <term><command>max-recursion-queries</command></term>
+             <listitem>
+               <para>
+                 Sets the maximum number of iterative queries that
+                 may be sent while servicing a recursive query.
+                 If more queries are sent, the recursive query
+                 is terminated and returns SERVFAIL. The default
+                 is 50.
                </para>
              </listitem>
            </varlistentry>
index c2560493ecf2a2a4ec1571f5b648b705230a80b2..8a8200a7ecf9a89996272b1cb88161edb14a7e98 100644 (file)
@@ -601,6 +601,18 @@ dns_resolver_getmaxdepth(dns_resolver_t *resolver);
  * \li resolver to be valid.
  */
 
+void
+dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries);
+unsigned int
+dns_resolver_getmaxqueries(dns_resolver_t *resolver);
+/*%
+ * Get and set how many iterative queries will be allowed before
+ * terminating a recursive query.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ */
+
 ISC_LANG_ENDDECLS
 
 #endif /* DNS_RESOLVER_H */
index ccf19eecbe868f8d7c5e0db9ad148b5e405e227d..fd7396ace55f950616003e7484dd2d982345b9fc 100644 (file)
@@ -432,6 +432,7 @@ struct dns_resolver {
        isc_boolean_t                   zero_no_soa_ttl;
        unsigned int                    query_timeout;
        unsigned int                    maxdepth;
+       unsigned int                    maxqueries;
 
        /* Locked by lock. */
        unsigned int                    references;
@@ -2210,9 +2211,9 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
                 */
                INSIST(!SHUTTINGDOWN(fctx));
                fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
+               fctx->totalqueries += find->qtotal;
                if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) {
                        want_try = ISC_TRUE;
-                       fctx->totalqueries += find->qtotal;
                } else {
                        fctx->findfail++;
                        if (fctx->pending == 0) {
@@ -2242,7 +2243,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
        else if (want_done)
                fctx_done(fctx, ISC_R_FAILURE, __LINE__);
        else if (destroy) {
-                       fctx_destroy(fctx);
+               fctx_destroy(fctx);
                if (bucket_empty)
                        empty_bucket(res);
        }
@@ -2611,7 +2612,10 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
        res = fctx->res;
 
        if (fctx->depth > res->maxdepth) {
-               FCTXTRACE("too much NS indirection");
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+                             DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+                             "too much NS indirection resolving '%s'",
+                             fctx->info);
                return (DNS_R_SERVFAIL);
        }
 
@@ -3053,8 +3057,14 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
 
        REQUIRE(!ADDRWAIT(fctx));
 
-       if (fctx->totalqueries > DEFAULT_MAX_QUERIES)
+       if (fctx->totalqueries > fctx->res->maxqueries) {
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+                             DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+                             "exceeded max queries resolving '%s'",
+                             fctx->info);
                fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
+               return;
+       }
 
        addrinfo = fctx_nextaddress(fctx);
        if (addrinfo == NULL) {
@@ -5704,7 +5714,7 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
                                        char qbuf[DNS_NAME_FORMATSIZE];
                                        char nbuf[DNS_NAME_FORMATSIZE];
                                        char tbuf[DNS_RDATATYPE_FORMATSIZE];
-                                       dns_rdatatype_format(fctx->type, tbuf,
+                                       dns_rdatatype_format(type, tbuf,
                                                             sizeof(tbuf));
                                        dns_name_format(name, nbuf,
                                                             sizeof(nbuf));
@@ -5713,7 +5723,7 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
                                        log_formerr(fctx,
                                                    "unrelated %s %s in "
                                                    "%s authority section",
-                                                   tbuf, qbuf, nbuf);
+                                                   tbuf, nbuf, qbuf);
                                        goto nextname;
                                }
                                if (type == dns_rdatatype_ns) {
@@ -7804,6 +7814,7 @@ dns_resolver_create(dns_view_t *view,
        res->zero_no_soa_ttl = ISC_FALSE;
        res->query_timeout = DEFAULT_QUERY_TIMEOUT;
        res->maxdepth = DEFAULT_RECURSION_DEPTH;
+       res->maxqueries = DEFAULT_MAX_QUERIES;
        res->nbuckets = ntasks;
        res->activebuckets = ntasks;
        res->buckets = isc_mem_get(view->mctx,
@@ -9156,3 +9167,15 @@ dns_resolver_getmaxdepth(dns_resolver_t *resolver) {
        REQUIRE(VALID_RESOLVER(resolver));
        return (resolver->maxdepth);
 }
+
+void
+dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) {
+       REQUIRE(VALID_RESOLVER(resolver));
+       resolver->maxqueries = queries;
+}
+
+unsigned int
+dns_resolver_getmaxqueries(dns_resolver_t *resolver) {
+       REQUIRE(VALID_RESOLVER(resolver));
+       return (resolver->maxqueries);
+}
index 5f8b037064ee3511879e928c31280e03844c8873..1c82f9bfd0680852d607d29307ec15995398c445 100644 (file)
@@ -15,8 +15,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 /*! \file */
 
 #include <config.h>
@@ -1394,6 +1392,7 @@ view_clauses[] = {
        { "max-clients-per-query", &cfg_type_uint32, 0 },
        { "max-ncache-ttl", &cfg_type_uint32, 0 },
        { "max-recursion-depth", &cfg_type_uint32, 0 },
+       { "max-recursion-queries", &cfg_type_uint32, 0 },
        { "max-udp-size", &cfg_type_uint32, 0 },
        { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP },
        { "minimal-responses", &cfg_type_boolean, 0 },