Track forwarder timeouts in fetch contexts

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.
This commit is contained in:
Michał Kępień
2019-01-08 08:29:54 +01:00
parent a38b31ccf9
commit 33350626f9
7 changed files with 51 additions and 1 deletions

View File

View 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

View File

@@ -46,6 +46,11 @@ zone "example4." {
file "example.db";
};
zone "example7." {
type master;
file "example.db";
};
zone "grafted." {
type master;
file "example.db";

View File

@@ -44,3 +44,9 @@ zone "example3." {
forward only;
forwarders { };
};
zone "example7." {
type forward;
forward first;
forwarders { 10.53.0.6; };
};

View 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