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

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

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 8b2299d1a0b41faee59d68c672353d48a20bdf93..19f4e365a95f57b3211e568f25d9c2cd85df7c2d 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]
 
 4003.  [security]      When geoip-directory was reconfigured during
                        named run-time, the previously loaded GeoIP
index 163441dcfaedc505414ea0a91c507c9cf85c1efb..53ac6275520216221b0cd4e64a0ab7b1f0d1f5a2 100644 (file)
@@ -169,6 +169,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 e0b872d83cab1c727e880af3a5b087432bf37686..e240503edb457e249b8d6e11a6deb90c94c842ed 100644 (file)
@@ -3443,6 +3443,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
        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
        obj = NULL;
        result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
index ad5d6da1004405e436e618253c9ec5e49a8f6cfc..43a4f60efa8e41529e459b2d5b0bf8463db07f4b 100644 (file)
@@ -70,8 +70,10 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
         dname dns64 dnssec dsdigest dscp ecdsa emptyzones filter-aaaa
         formerr forward geoip glue gost ixfr inline limits logfileconfig
         lwresd masterfile masterformat metadata notify nslookup nsupdate
-        pending @PKCS11_TEST@ redirect resolver rndc rpz rrl rrchecker
-        rrsetorder rsabigexponent sit smartsign sortlist spf staticstub
+        pending @PKCS11_TEST@
+         reclimit redirect resolver rndc rpz rrl
+         rrchecker rrsetorder rsabigexponent
+         sit smartsign sortlist spf staticstub
         statistics 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 16a7a9e7ffe0006580b6a9e041e6f6bcee6b7842..6cc13444d02fb6d6bd31ddab0e2e84204255ada7 100644 (file)
@@ -8945,8 +8945,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 cded6d7145fced3cb4886040e46082afb1ea35e2..f7ec526c7534dcc31f6aab3aefc0a3f7a7738c7b 100644 (file)
@@ -653,6 +653,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 fdb20ba3e8cff3785e5a8942d4b3e7acae95db2b..4541dcbbf5ddff16538bf9eacd4fd9e4b6bedbae 100644 (file)
@@ -448,6 +448,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;
@@ -2457,9 +2458,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) {
@@ -2489,7 +2490,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);
        }
@@ -2858,7 +2859,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);
        }
 
@@ -3299,8 +3303,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) {
@@ -5981,7 +5991,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));
@@ -5990,7 +6000,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) {
@@ -8195,6 +8205,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;
        if (view->resstats != NULL)
                isc_stats_set(view->resstats, ntasks,
@@ -9724,3 +9735,15 @@ dns_resolver_getmaxdepth(dns_resolver_t *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 1c4fe042f14fb87246d399a06dd70dc556a4b818..282d23e606f63d259cbb5063b246eecc2e979aa2 100644 (file)
@@ -15,8 +15,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 /*! \file */
 
 #include <config.h>
@@ -1509,6 +1507,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 },