diff --git a/CHANGES b/CHANGES
index 01ec0b7b26..a0ceea14bb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+5369. [func] Add the ability to specify whether or not to wait
+ for nameserver domain names to be looked up, with
+ a new RPZ modifying directive 'nsdname-wait-recurse'.
+ [GL #1138]
+
5368. [bug] Named failed to restart if 'rndc addzone' names
contained special characters (e.g. '/'). [GL #1655]
diff --git a/bin/named/server.c b/bin/named/server.c
index 781d9e013d..2836429de3 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -2557,6 +2557,13 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps,
zones->p.qname_wait_recurse = false;
}
+ sub_obj = cfg_tuple_get(rpz_obj, "nsdname-wait-recurse");
+ if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) {
+ zones->p.nsdname_wait_recurse = true;
+ } else {
+ zones->p.nsdname_wait_recurse = false;
+ }
+
sub_obj = cfg_tuple_get(rpz_obj, "nsip-wait-recurse");
if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) {
zones->p.nsip_wait_recurse = true;
diff --git a/bin/tests/system/rpzrecurse/clean.sh b/bin/tests/system/rpzrecurse/clean.sh
index ffd9dfd50a..9117a241eb 100644
--- a/bin/tests/system/rpzrecurse/clean.sh
+++ b/bin/tests/system/rpzrecurse/clean.sh
@@ -22,7 +22,7 @@ rm -f ns2/*.queries
rm -f ns2/named.[0-9]*.conf
rm -f ns2/named.conf.header
-rm -f ns3/named2.conf
+rm -f ns3/named.conf
rm -f dnsrps*.conf dnsrpzd*
rm -f ns*/session.key
diff --git a/bin/tests/system/rpzrecurse/ns3/named3.conf.in b/bin/tests/system/rpzrecurse/ns3/named3.conf.in
new file mode 100644
index 0000000000..73470fafbd
--- /dev/null
+++ b/bin/tests/system/rpzrecurse/ns3/named3.conf.in
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+include "../../common/rndc.key";
+
+controls {
+ inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+ query-source address 10.53.0.3;
+ notify-source 10.53.0.3;
+ transfer-source 10.53.0.3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.3; };
+ listen-on-v6 { none; };
+ recursion yes;
+ dnssec-validation yes;
+ response-policy { zone "policy"; } nsdname-wait-recurse no
+ nsdname-enable yes;
+
+ include "../dnsrps.conf";
+};
+
+zone "policy" { type master; file "policy.db"; };
+
+zone "example.tld" { type master; file "example.db"; };
+
+zone "." { type master; file "root.db"; };
diff --git a/bin/tests/system/rpzrecurse/setup.sh b/bin/tests/system/rpzrecurse/setup.sh
index 36786a72de..9ab709fc9d 100644
--- a/bin/tests/system/rpzrecurse/setup.sh
+++ b/bin/tests/system/rpzrecurse/setup.sh
@@ -42,7 +42,6 @@ copy_setports ns2/named.conf.header.in ns2/named.conf.header
copy_setports ns2/named.default.conf ns2/named.conf
copy_setports ns3/named1.conf.in ns3/named.conf
-copy_setports ns3/named2.conf.in ns3/named2.conf
copy_setports ns4/named.conf.in ns4/named.conf
diff --git a/bin/tests/system/rpzrecurse/tests.sh b/bin/tests/system/rpzrecurse/tests.sh
index 3679d35c8f..7b1f206389 100644
--- a/bin/tests/system/rpzrecurse/tests.sh
+++ b/bin/tests/system/rpzrecurse/tests.sh
@@ -474,15 +474,17 @@ for mode in native dnsrps; do
status=1
}
- # Check for invalid prefix length error
- t=`expr $t + 1`
- echo_i "testing for invalid prefix length error (${t})"
- add_test_marker 10.53.0.2
- run_server invalidprefixlength
- grep "invalid rpz IP address \"1000.4.0.53.10.rpz-client-ip.invalidprefixlength\"; invalid prefix length of 1000$" ns2/named.run > /dev/null || {
- echo_ic "failed: expected that invalid prefix length error would be logged"
- status=1
- }
+ if [ "$mode" = "native" ]; then
+ # Check for invalid prefix length error
+ t=`expr $t + 1`
+ echo_i "testing for invalid prefix length error (${t})"
+ add_test_marker 10.53.0.2
+ run_server invalidprefixlength
+ grep "invalid rpz IP address \"1000.4.0.53.10.rpz-client-ip.invalidprefixlength\"; invalid prefix length of 1000$" ns2/named.run > /dev/null || {
+ echo_ic "failed: expected that invalid prefix length error would be logged"
+ status=1
+ }
+ fi
t=`expr $t + 1`
echo_i "checking 'nsip-wait-recurse no' is faster than 'nsip-wait-recurse yes' ($t)"
@@ -493,10 +495,10 @@ for mode in native dnsrps; do
$DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.yes.$t
t2=`$PERL -e 'print time()."\n";'`
p1=`expr $t2 - $t1`
- echo_i "elasped time $p1 seconds"
+ echo_i "elapsed time $p1 seconds"
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush
- cp -f ns3/named2.conf ns3/named.conf
+ copy_setports ns3/named2.conf.in ns3/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload > /dev/null
echo_i "timing 'nsip-wait-recurse no'"
@@ -504,12 +506,44 @@ for mode in native dnsrps; do
$DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.no.$t
t4=`$PERL -e 'print time()."\n";'`
p2=`expr $t4 - $t3`
- echo_i "elasped time $p2 seconds"
+ echo_i "elapsed time $p2 seconds"
if test $p1 -le $p2; then ret=1; fi
if test $ret != 0; then echo_i "failed"; fi
status=`expr $status + $ret`
+ $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush
+ # restore original named.conf
+ copy_setports ns3/named1.conf.in ns3/named.conf
+ $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload > /dev/null
+
+ t=`expr $t + 1`
+ echo_i "checking 'nsdname-wait-recurse no' is faster than 'nsdname-wait-recurse yes' ($t)"
+ add_test_marker 10.53.0.2
+ echo_i "timing 'nsdname-wait-recurse yes' (default)"
+ ret=0
+ t1=`$PERL -e 'print time()."\n";'`
+ $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.yes.$t
+ t2=`$PERL -e 'print time()."\n";'`
+ p1=`expr $t2 - $t1`
+ echo_i "elapsed time $p1 seconds"
+
+ $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush
+ copy_setports ns3/named3.conf.in ns3/named.conf
+ $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload > /dev/null
+
+ echo_i "timing 'nsdname-wait-recurse no'"
+ t3=`$PERL -e 'print time()."\n";'`
+ $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.no.$t
+ t4=`$PERL -e 'print time()."\n";'`
+ p2=`expr $t4 - $t3`
+ echo_i "elapsed time $p2 seconds"
+
+ if test $p1 -le $p2; then ret=1; fi
+ if test $ret != 0; then echo_i "failed"; fi
+ status=`expr $status + $ret`
+
+
[ $status -ne 0 ] && pf=fail || pf=pass
case $mode in
native)
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index 6fc046e950..e291dc88d0 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -9843,18 +9843,36 @@ deny-answer-aliases { "example.net"; };
NSDNAME triggers match names of authoritative servers
- for the query name, a parent of the query name, a CNAME for
- query name, or a parent of a CNAME.
- They are encoded as subdomains of
- rpz-nsdname relativized
- to the RPZ origin name.
- NSIP triggers match IP addresses in A and
- AAAA RRsets for domains that can be checked against NSDNAME
- policy records.
- The nsdname-enable phrase turns NSDNAME
+ for the query name, a parent of the query name, a CNAME
+ for query name, or a parent of a CNAME. They are
+ encoded as subdomains of rpz-nsdname
+ relativized to the RPZ origin name. NSIP triggers match
+ IP addresses in A and AAAA RRsets for domains that can
+ be checked against NSDNAME policy records. The
+ nsdname-enable phrase turns NSDNAME
triggers off or on for a single policy zone or all
zones.
+
+ If authoritative nameservers for the query name are not
+ yet known, named will recursively
+ look up the authoritative servers for the query name
+ before applying an RPZ-NSDNAME rule.
+ This can cause a processing delay. To speed up
+ processing at the cost of precision, the
+ nsdname-wait-recurse option
+ can be used: when set to no,
+ RPZ-NSDNAME rules will only be applied when authoritative
+ servers for the query name have already been looked up and
+ cached. If authoritative servers for the query name
+ are not in the cache, then the RPZ-NSDNAME rule will be
+ ignored, but the authoritative servers for the query name
+ will be looked up in the background, and the rule will be
+ applied to subsequent queries. The default is
+ yes, meaning RPZ-NSDNAME
+ rules should always be applied even if authoritative
+ servers for the query name need to be looked up first.
+
diff --git a/doc/arm/notes-9.17.0.xml b/doc/arm/notes-9.17.0.xml
index 7f0227a95b..5234ccec7e 100644
--- a/doc/arm/notes-9.17.0.xml
+++ b/doc/arm/notes-9.17.0.xml
@@ -49,6 +49,19 @@
100%. [GL #1515]
+
+
+ A new RPZ option nsdname-wait-recurse
+ controls whether RPZ-NSDNAME rules should always be applied
+ even if the names of authoritative name servers for the query
+ name need to be looked up recurively first. The default is
+ yes. Setting it to
+ no speeds up initial responses by skipping
+ RPZ-NSDNAME rules when name server domain names are not yet
+ in the cache. The names will be looked up in the background and
+ the rule will be applied for subsequent queries. [GL #1138]
+
+
diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h
index 4e834d7fe4..966aaee0ed 100644
--- a/lib/dns/include/dns/rpz.h
+++ b/lib/dns/include/dns/rpz.h
@@ -203,6 +203,7 @@ struct dns_rpz_popt {
bool break_dnssec;
bool qname_wait_recurse;
bool nsip_wait_recurse;
+ bool nsdname_wait_recurse;
unsigned int min_ns_labels;
dns_rpz_num_t num_zones;
};
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index d3b0d6a41f..55e16c997b 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -1736,6 +1736,7 @@ static cfg_tuplefielddef_t rpz_fields[] = {
{ "min-update-interval", &cfg_type_duration, 0 },
{ "min-ns-dots", &cfg_type_uint32, 0 },
{ "nsip-wait-recurse", &cfg_type_boolean, 0 },
+ { "nsdname-wait-recurse", &cfg_type_boolean, 0 },
{ "qname-wait-recurse", &cfg_type_boolean, 0 },
{ "recursive-only", &cfg_type_boolean, 0 },
{ "nsip-enable", &cfg_type_boolean, 0 },
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 482b3f3b01..a503109db0 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -2826,7 +2826,10 @@ rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
*/
if (rpz_type == DNS_RPZ_TYPE_IP) {
result = DNS_R_NXRRSET;
- } else if (!client->view->rpzs->p.nsip_wait_recurse) {
+ } else if (!client->view->rpzs->p.nsip_wait_recurse ||
+ (!client->view->rpzs->p.nsdname_wait_recurse &&
+ rpz_type == DNS_RPZ_TYPE_NSDNAME))
+ {
query_rpzfetch(client, name, type);
result = DNS_R_NXRRSET;
} else {