]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Track forwarder timeouts in fetch contexts
authorMichał Kępień <michal@isc.org>
Tue, 8 Jan 2019 07:29:54 +0000 (08:29 +0100)
committerMichał Kępień <michal@isc.org>
Tue, 8 Jan 2019 07:29:54 +0000 (08:29 +0100)
Since following a delegation resets most fetch context state, address
marks (FCTX_ADDRINFO_MARK) set inside lib/dns/resolver.c are not
preserved when a delegation is followed.  This is fine for full
recursive resolution but when named is configured with "forward first;"
and one of the specified forwarders times out, triggering a fallback to
full recursive resolution, that forwarder should no longer be consulted
at each delegation point subsequently reached within a given fetch
context.

Add a new badnstype_t enum value, badns_forwarder, and use it to mark a
forwarder as bad when it times out in a "forward first;" configuration.
Since the bad server list is not cleaned when a fetch context follows a
delegation, this prevents a forwarder from being queried again after
falling back to full recursive resolution.  Yet, as each fetch context
maintains its own list of bad servers, this change does not cause a
forwarder timeout to prevent that forwarder from being used by other
fetch contexts.

bin/tests/system/forward/ans6/startme [new file with mode: 0644]
bin/tests/system/forward/ns1/root.db
bin/tests/system/forward/ns2/named.conf.in
bin/tests/system/forward/ns3/named.conf.in
bin/tests/system/forward/tests.sh
lib/dns/resolver.c
util/copyrights

diff --git a/bin/tests/system/forward/ans6/startme b/bin/tests/system/forward/ans6/startme
new file mode 100644 (file)
index 0000000..e69de29
index 7346810ba6aa8b552ff02ded71f21c22c9cb7018..23e40bd583c8a3c03cfc1e703d752b202cba1fbc 100644 (file)
@@ -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
index 522e965393079bb4a9880562ead2058d6e8c54cc..190bd69953d65a464537b664e800f009b250de92 100644 (file)
@@ -46,6 +46,11 @@ zone "example4." {
        file "example.db";
 };
 
+zone "example7." {
+       type master;
+       file "example.db";
+};
+
 zone "grafted." {
        type master;
        file "example.db";
index 0fdcf65e5243d549ffd3a64c3f97bb06b5a910a6..f6022135eb26541d5fbd25c3d2bb10f80bf6fd3b 100644 (file)
@@ -44,3 +44,9 @@ zone "example3." {
        forward only;
        forwarders { };
 };
+
+zone "example7." {
+       type forward;
+       forward first;
+       forwarders { 10.53.0.6; };
+};
index aa80f189e6a82c572532e3333c28e2ff20f6edfa..3e6064a043600189c9f9cddc05aa37a872789f77 100644 (file)
@@ -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
index 8beecbcb07ca995497d09d9dbd404c78fddb0ae7..7b09edf20719107ab51af69b438233b831f367eb 100644 (file)
@@ -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;
                }
        }
 
index 20b4c811f2b301b4bf7711a0fb3c8d3f60201002..3da3d4113eaffe0cf548cb6e38b02080bb23aab7 100644 (file)
 ./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