From: JINMEI Tatuya Date: Fri, 16 Aug 2024 07:53:38 +0000 (+0900) Subject: allow IXFR-to-AXFR fallback on DNS_R_TOOMANYRECORDS X-Git-Tag: v9.21.2~50^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7289090683b07d5c9e9843fb68fe626f8552c664;p=thirdparty%2Fbind9.git allow IXFR-to-AXFR fallback on DNS_R_TOOMANYRECORDS This change allows fallback from an IXFR failure to AXFR when the reason is DNS_R_TOOMANYRECORDS. This is because this error condition could be temporary only in an intermediate version of IXFR transactions and it's possible that the latest version of the zone doesn't have that condition. In such a case, the secondary would never be able to update the zone (even if it could) without this fallback. This fallback behavior is particularly useful with the recently introduced max-records-per-type and max-types-per-name options: the primary may not have these limitations and may temporarily introduce "too many" records, breaking IXFR. If the primary side subsequently deletes these records, this fallback will help recover the zone transfer failure automatically; without it, the secondary side would first need to increase the limit, which requires more operational overhead and has its own adverse effect. This change also fixes a minor glitch that DNS_R_TOOMANYRECORDS wasn't logged in xfrin_fail. --- diff --git a/bin/tests/system/ixfr/tests.sh b/bin/tests/system/ixfr/tests.sh index 2b9e085cd5f..97014200f23 100644 --- a/bin/tests/system/ixfr/tests.sh +++ b/bin/tests/system/ixfr/tests.sh @@ -65,6 +65,7 @@ zone "nil" { type secondary; file "myftp.db"; primaries { 10.53.0.2; }; + max-records-per-type 5; # use a small value for fallback test }; EOF @@ -144,6 +145,44 @@ $DIG $DIGOPTS @10.53.0.1 nil. TXT | grep 'fallback AXFR' >/dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) +n=$((n + 1)) +echo_i "testing AXFR fallback after IXFR failure (too many records) ($n)" +ret=0 + +# Provide an IXFR response that would cause a "too many records" condition + +sendcmd </dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + n=$((n + 1)) echo_i "testing AXFR fallback after IXFR failure (bad SOA owner) ($n)" ret=0 diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 99da559b895..3d5a1752027 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -1125,8 +1125,7 @@ xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) { if (atomic_compare_exchange_strong(&xfr->shuttingdown, &(bool){ false }, true)) { - if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) - { + if (result != DNS_R_UPTODATE) { xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg, isc_result_totext(result)); if (atomic_load(&xfr->is_ixfr) &&