diff --git a/CHANGES b/CHANGES index be81b3f462..d273ace638 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +5122. [bug] In a "forward first;" configuration, a forwarder + timeout did not prevent that forwarder from being + queried again after falling back to full recursive + resolution. [GL #315] + 5121. [contrib] dlz_stub_driver.c fails to return ISC_R_NOTFOUND on none matching zone names. [GL !1299] diff --git a/bin/tests/system/forward/ans6/startme b/bin/tests/system/forward/ans6/startme new file mode 100644 index 0000000000..e69de29bb2 diff --git a/bin/tests/system/forward/ns1/root.db b/bin/tests/system/forward/ns1/root.db index 7346810ba6..23e40bd583 100644 --- a/bin/tests/system/forward/ns1/root.db +++ b/bin/tests/system/forward/ns1/root.db @@ -26,3 +26,6 @@ ns.example2 A 10.53.0.1 example3 NS ns.example3 ns.example3 A 10.53.0.1 + +example7 NS ns.example7 +ns.example7 A 10.53.0.2 diff --git a/bin/tests/system/forward/ns2/named.conf.in b/bin/tests/system/forward/ns2/named.conf.in index 522e965393..190bd69953 100644 --- a/bin/tests/system/forward/ns2/named.conf.in +++ b/bin/tests/system/forward/ns2/named.conf.in @@ -46,6 +46,11 @@ zone "example4." { file "example.db"; }; +zone "example7." { + type master; + file "example.db"; +}; + zone "grafted." { type master; file "example.db"; diff --git a/bin/tests/system/forward/ns3/named.conf.in b/bin/tests/system/forward/ns3/named.conf.in index 0fdcf65e52..f6022135eb 100644 --- a/bin/tests/system/forward/ns3/named.conf.in +++ b/bin/tests/system/forward/ns3/named.conf.in @@ -44,3 +44,9 @@ zone "example3." { forward only; forwarders { }; }; + +zone "example7." { + type forward; + forward first; + forwarders { 10.53.0.6; }; +}; diff --git a/bin/tests/system/forward/tests.sh b/bin/tests/system/forward/tests.sh index aa80f189e6..3e6064a043 100644 --- a/bin/tests/system/forward/tests.sh +++ b/bin/tests/system/forward/tests.sh @@ -11,6 +11,7 @@ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh DIGOPTS="-p ${PORT}" +SENDCMD="$PERL ../send.pl 10.53.0.6 $EXTRAPORT1" root=10.53.0.1 hidden=10.53.0.2 @@ -131,5 +132,20 @@ $CHECKCONF ula-notinherited.conf | grep "forward first;" >/dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +echo_i "checking that a forwarder timeout prevents it from being reused in the same fetch context" +ret=0 +# Make ans6 receive queries without responding to them. +echo "//" | $SENDCMD +# Query for a record in a zone which is forwarded to a non-responding forwarder +# and is delegated from the root to check whether the forwarder will be retried +# when a delegation is encountered after falling back to full recursive +# resolution. +$DIG $DIGOPTS txt.example7. txt @$f1 > dig.out.f1 || ret=1 +# The forwarder for the "example7" zone should only be queried once. +sent=`sed -n '/sending packet to 10.53.0.6/,/^$/p' ns3/named.run | grep ";txt.example7.*IN.*TXT" | wc -l` +if [ $sent -ne 1 ]; then ret=1; fi +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 8beecbcb07..7b09edf207 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -253,7 +253,8 @@ typedef enum { typedef enum { badns_unreachable = 0, badns_response, - badns_validation + badns_validation, + badns_forwarder, } badnstype_t; struct fetchctx { @@ -1206,6 +1207,18 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, else dns_adb_timeout(fctx->adb, query->addrinfo); + /* + * If "forward first;" is used and a forwarder timed + * out, do not attempt to query it again in this fetch + * context. + */ + if (fctx->fwdpolicy == dns_fwdpolicy_first && + ISFORWARDER(query->addrinfo)) + { + add_bad(fctx, query->addrinfo, ISC_R_TIMEDOUT, + badns_forwarder); + } + /* * We don't have an RTT for this query. Maybe the * packet was lost, or maybe this server is very @@ -3176,6 +3189,12 @@ add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, break; case badns_validation: break; /* counted as 'valfail' */ + case badns_forwarder: + /* + * We were called to prevent the given forwarder from + * being used again for this fetch context. + */ + break; } } diff --git a/util/copyrights b/util/copyrights index 20b4c811f2..3da3d4113e 100644 --- a/util/copyrights +++ b/util/copyrights @@ -638,6 +638,7 @@ ./bin/tests/system/formerr/setup.sh SH 2018,2019 ./bin/tests/system/formerr/tests.sh SH 2013,2015,2016,2018,2019 ./bin/tests/system/formerr/twoquestions X 2013,2018,2019 +./bin/tests/system/forward/ans6/startme X 2019 ./bin/tests/system/forward/clean.sh SH 2000,2001,2004,2007,2012,2014,2015,2016,2018,2019 ./bin/tests/system/forward/ns1/example.db X 2000,2001,2018 ./bin/tests/system/forward/ns2/example.db X 2000,2001,2018