mirror of
https://github.com/isc-projects/bind9.git
synced 2026-03-10 10:11:39 -04:00
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.
(cherry picked from commit 7289090683)
This commit is contained in:
parent
1cdde5656d
commit
a93b6f2040
2 changed files with 40 additions and 2 deletions
|
|
@ -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 <<EOF
|
||||
/SOA/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/IXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
nil. 300 TXT "text 1"
|
||||
nil. 300 TXT "text 2"
|
||||
nil. 300 TXT "text 3"
|
||||
nil. 300 TXT "text 4"
|
||||
nil. 300 TXT "text 5"
|
||||
nil. 300 TXT "text 6: causing too many records"
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
nil. 300 NS ns.nil.
|
||||
nil. 300 TXT "fallback AXFR on too many records"
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
EOF
|
||||
|
||||
sleep 1
|
||||
|
||||
$RNDCCMD 10.53.0.1 refresh nil | sed 's/^/ns1 /' | cat_i
|
||||
|
||||
sleep 2
|
||||
|
||||
$DIG $DIGOPTS @10.53.0.1 nil. TXT | grep 'AXFR on too many records' >/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
|
||||
|
|
|
|||
|
|
@ -859,8 +859,7 @@ xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
|
|||
(void)isc_timer_reset(xfr->max_idle_timer,
|
||||
isc_timertype_inactive, NULL, NULL, 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 (xfr->is_ixfr) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue