Merge branch '2349-backport-max-ixfr-ration-v9_16' into 'v9_16'
Backport max-ixfr-ratio to BIND 9.16 See merge request isc-projects/bind9!4598
This commit is contained in:
@@ -2,6 +2,13 @@
|
||||
BIND 9 version number, in an effort to tightly couple
|
||||
internal libraries with a specific release. [GL #2387]
|
||||
|
||||
5562. [func] Limit the size of IXFR responses so that AXFR will
|
||||
be used instead if it would be smaller. This is
|
||||
controlled by the "max-ixfr-ratio" option, which
|
||||
is a percentage representing the ratio of IXFR size
|
||||
to the size of the entire zone. This value cannot
|
||||
exceed 100%, which is the default. [GL #1515]
|
||||
|
||||
5561. [bug] KASP incorrectly set signature validity to the value
|
||||
of the DNSKEY signature validity. This is now fixed.
|
||||
[GL #2383]
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ options {\n\
|
||||
listen-on-v6 {any;};\n\
|
||||
# lock-file \"" NAMED_LOCALSTATEDIR "/run/named/named.lock\";\n\
|
||||
match-mapped-addresses no;\n\
|
||||
max-ixfr-ratio 100%;\n\
|
||||
max-rsa-exponent-size 0; /* no limit */\n\
|
||||
max-udp-size 1232;\n\
|
||||
memstatistics-file \"named.memstats\";\n\
|
||||
|
||||
@@ -1398,6 +1398,15 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
ixfrdiff);
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-ixfr-ratio", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
if (cfg_obj_isstring(obj)) {
|
||||
dns_zone_setixfrratio(zone, 0);
|
||||
} else {
|
||||
dns_zone_setixfrratio(zone, cfg_obj_aspercentage(obj));
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "request-expire", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone example {
|
||||
type master;
|
||||
masterfile-format map;
|
||||
file "example.db";
|
||||
max-ixfr-ratio 0.9;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone example {
|
||||
type master;
|
||||
masterfile-format map;
|
||||
file "example.db";
|
||||
max-ixfr-ratio 0%;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone example {
|
||||
type master;
|
||||
masterfile-format map;
|
||||
file "example.db";
|
||||
max-ixfr-ratio 50%;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone example {
|
||||
type master;
|
||||
masterfile-format map;
|
||||
file "example.db";
|
||||
max-ixfr-ratio unlimited;
|
||||
};
|
||||
@@ -81,6 +81,7 @@ options {
|
||||
"corp";
|
||||
};
|
||||
dnssec-policy "test";
|
||||
max-ixfr-ratio 90%;
|
||||
transfer-source 0.0.0.0 dscp 63;
|
||||
zone-statistics none;
|
||||
};
|
||||
@@ -92,11 +93,13 @@ view "first" {
|
||||
type master;
|
||||
file "xxx";
|
||||
update-policy local;
|
||||
max-ixfr-ratio 20%;
|
||||
notify-source 10.10.10.10 port 53 dscp 55;
|
||||
};
|
||||
zone "clone" {
|
||||
type master;
|
||||
file "yyy";
|
||||
max-ixfr-ratio unlimited;
|
||||
};
|
||||
dnssec-validation auto;
|
||||
zone-statistics terse;
|
||||
|
||||
@@ -559,9 +559,16 @@ awk 'BEGIN { ok = 0; } /cut here/ { ok = 1; getline } ok == 1 { print }' good-ka
|
||||
[ -s good-kasp.conf.in ] || ret=1
|
||||
$CHECKCONF -p good-kasp.conf.in | grep -v '^good-kasp.conf.in:' > good-kasp.conf.out 2>&1 || ret=1
|
||||
cmp good-kasp.conf.in good-kasp.conf.out || ret=1
|
||||
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "check that max-ixfr-ratio 100% generates a warning ($n)"
|
||||
ret=0
|
||||
$CHECKCONF warn-maxratio1.conf > checkconf.out$n 2>/dev/null || ret=1
|
||||
grep "exceeds 100%" < checkconf.out$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone example {
|
||||
type master;
|
||||
masterfile-format map;
|
||||
file "example.db";
|
||||
max-ixfr-ratio 101%;
|
||||
};
|
||||
@@ -11,12 +11,12 @@
|
||||
|
||||
rm -f stats.*
|
||||
rm -f ns1/*.db ns1/*.jnl
|
||||
rm -f ns3/*.jnl ns3/mytest.db ns3/subtest.db
|
||||
rm -f ns3/*.jnl ns3/mytest*.db ns3/subtest*.db
|
||||
rm -f ns4/*.jnl ns4/*.db
|
||||
rm -f ns5/*.jnl ns5/*.db
|
||||
rm -f */named.memstats
|
||||
rm -f */named.conf
|
||||
rm -f */named.run
|
||||
rm -f */named.run */named.run.prev
|
||||
rm -f */ans.run
|
||||
rm -f dig.out.test* dig.out1.test* dig.out2.test* dig.out3.test*
|
||||
rm -f ns3/large.db
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
messages=1
|
||||
records=6
|
||||
bytes=219
|
||||
records=5
|
||||
bytes=204
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
named.conf
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.1;
|
||||
notify-source 10.53.0.1;
|
||||
transfer-source 10.53.0.1;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.1; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify yes;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$ORIGIN test.
|
||||
$TTL 15
|
||||
test. 15 IN SOA ns1.test. hostmaster.test. (
|
||||
1 ; serial
|
||||
3H ; refresh
|
||||
15 ; retry
|
||||
1w ; expire
|
||||
3h ; minimum
|
||||
)
|
||||
IN NS ns1.test.
|
||||
IN NS ns2.test.
|
||||
IN NS ns5.test.
|
||||
ns1 IN A 10.53.0.3
|
||||
ns2 IN A 10.53.0.4
|
||||
ns5 IN A 10.53.0.5
|
||||
host1 IN A 192.168.10.3
|
||||
host2 IN A 192.168.10.4
|
||||
@@ -1,26 +0,0 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$ORIGIN test.
|
||||
$TTL 15
|
||||
test. 15 IN SOA ns1.test. hostmaster.test. (
|
||||
2 ; serial
|
||||
3H ; refresh
|
||||
15 ; retry
|
||||
1w ; expire
|
||||
3h ; minimum
|
||||
)
|
||||
IN NS ns1.test.
|
||||
IN NS ns2.test.
|
||||
IN NS ns5.test.
|
||||
ns1 IN A 10.53.0.3
|
||||
ns2 IN A 10.53.0.4
|
||||
ns5 IN A 10.53.0.5
|
||||
host1 IN A 192.168.10.13
|
||||
host2 IN A 192.168.10.4
|
||||
@@ -1,26 +0,0 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$ORIGIN test.
|
||||
$TTL 15
|
||||
test. 15 IN SOA ns1.test. hostmaster.test. (
|
||||
3 ; serial
|
||||
3H ; refresh
|
||||
15 ; retry
|
||||
1w ; expire
|
||||
3h ; minimum
|
||||
)
|
||||
IN NS ns1.test.
|
||||
IN NS ns2.test.
|
||||
IN NS ns5.test.
|
||||
ns1 IN A 10.53.0.3
|
||||
ns2 IN A 10.53.0.4
|
||||
ns5 IN A 10.53.0.5
|
||||
host1 IN A 192.168.10.13
|
||||
host2 IN A 192.168.10.14
|
||||
@@ -37,6 +37,7 @@ view "primary" {
|
||||
zone "test" IN {
|
||||
type primary;
|
||||
file "mytest.db";
|
||||
max-ixfr-ratio 75%;
|
||||
};
|
||||
zone "sub.test" IN {
|
||||
type primary;
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$ORIGIN sub.test.
|
||||
$TTL 15
|
||||
sub.test. 15 IN SOA ns1.test. hostmaster.test. (
|
||||
1 ; serial
|
||||
3H ; refresh
|
||||
15 ; retry
|
||||
1w ; expire
|
||||
3h ; minimum
|
||||
)
|
||||
IN NS ns1.test.
|
||||
IN NS ns2.test.
|
||||
host3 IN A 192.168.10.23
|
||||
host4 IN A 192.168.10.24
|
||||
@@ -1,22 +0,0 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$ORIGIN sub.test.
|
||||
$TTL 15
|
||||
sub.test. 15 IN SOA ns1.test. hostmaster.test. (
|
||||
3 ; serial
|
||||
3H ; refresh
|
||||
15 ; retry
|
||||
1w ; expire
|
||||
3h ; minimum
|
||||
)
|
||||
IN NS ns1.test.
|
||||
IN NS ns2.test.
|
||||
host3 IN A 192.168.10.123
|
||||
host4 IN A 192.168.10.24
|
||||
@@ -37,6 +37,7 @@ view "primary" {
|
||||
type secondary;
|
||||
file "mytest.db";
|
||||
primaries { 10.53.0.3; };
|
||||
max-ixfr-ratio unlimited;
|
||||
};
|
||||
zone "sub.test" IN {
|
||||
type secondary;
|
||||
|
||||
@@ -12,35 +12,56 @@
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
cat <<EOF >ns1/named.conf
|
||||
options {
|
||||
query-source address 10.53.0.1;
|
||||
notify-source 10.53.0.1;
|
||||
transfer-source 10.53.0.1;
|
||||
port ${PORT};
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.1; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify yes;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.1 port ${CONTROLPORT} allow { any; } keys { rndc_key; };
|
||||
};
|
||||
EOF
|
||||
$SHELL clean.sh
|
||||
|
||||
copy_setports ns1/named.conf.in ns1/named.conf
|
||||
copy_setports ns3/named.conf.in ns3/named.conf
|
||||
copy_setports ns4/named.conf.in ns4/named.conf
|
||||
copy_setports ns5/named.conf.in ns5/named.conf
|
||||
|
||||
# Setup initial db files for ns3
|
||||
cp ns3/mytest0.db ns3/mytest.db
|
||||
cp ns3/subtest0.db ns3/subtest.db
|
||||
# Set up db files for zone "test" - this is a series of four
|
||||
# versions of the zone, the second and third having small changes
|
||||
# and the fourth having a large one.
|
||||
|
||||
testdb () {
|
||||
cat << EOF
|
||||
\$ORIGIN $1
|
||||
\$TTL 15
|
||||
@ 15 IN SOA ns1.test. hostmaster.test. (
|
||||
$2 ; serial
|
||||
3H ; refresh
|
||||
15 ; retry
|
||||
1w ; expire
|
||||
3h ; minimum
|
||||
)
|
||||
IN NS ns1.test.
|
||||
IN NS ns2.test.
|
||||
IN NS ns5.test.
|
||||
ns1 IN A 10.53.0.3
|
||||
ns2 IN A 10.53.0.4
|
||||
ns5 IN A 10.53.0.5
|
||||
EOF
|
||||
|
||||
i=0
|
||||
while [ $i -lt $3 ]; do
|
||||
echo "host$i IN A 192.0.2.$i"
|
||||
i=$((i+1))
|
||||
done
|
||||
}
|
||||
|
||||
testdb test. 1 60 > ns3/mytest.db
|
||||
testdb test. 2 61 > ns3/mytest1.db
|
||||
testdb test. 3 62 > ns3/mytest2.db
|
||||
testdb test. 4 0 > ns3/mytest3.db
|
||||
|
||||
# Set up similar db files for sub.test, which will have IXFR disabled
|
||||
testdb sub.test. 1 60 > ns3/subtest.db
|
||||
testdb sub.test. 3 61 > ns3/subtest1.db
|
||||
|
||||
# Set up a large zone
|
||||
i=0
|
||||
$SHELL ../genzone.sh 3 > ns3/large.db
|
||||
awk 'END { for (i = 0; i < 10000; i++) printf("record%d 10 IN TXT this is record %d\n", i, i) }' < /dev/null >> ns3/large.db
|
||||
while [ $i -lt 10000 ]; do
|
||||
echo "record$i 10 IN TXT this is record %i" >> ns3/large.db
|
||||
i=$((i+1))
|
||||
done
|
||||
|
||||
+122
-197
@@ -18,6 +18,12 @@
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
wait_for_serial() (
|
||||
$DIG $DIGOPTS "@$1" "$2" SOA > "$4"
|
||||
serial=$(awk '$4 == "SOA" { print $7 }' "$4")
|
||||
[ "$3" -eq "${serial:--1}" ]
|
||||
)
|
||||
|
||||
status=0
|
||||
n=0
|
||||
|
||||
@@ -27,6 +33,7 @@ RNDCCMD="$RNDC -p ${CONTROLPORT} -c ../common/rndc.conf -s"
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "testing initial AXFR ($n)"
|
||||
ret=0
|
||||
|
||||
$SENDCMD <<EOF
|
||||
/SOA/
|
||||
@@ -58,20 +65,15 @@ EOF
|
||||
|
||||
rndc_reload ns1 10.53.0.1
|
||||
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
$DIG $DIGOPTS @10.53.0.1 nil. SOA > dig.out.test$n
|
||||
grep "SOA" dig.out.test$n > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
retry_quiet 10 wait_for_serial 10.53.0.1 nil. 1 dig.out.test$n || ret=1
|
||||
|
||||
$DIG $DIGOPTS @10.53.0.1 nil. TXT | grep 'initial AXFR' >/dev/null || {
|
||||
echo_i "failed"
|
||||
status=1
|
||||
}
|
||||
$DIG $DIGOPTS @10.53.0.1 nil. TXT | grep 'initial AXFR' >/dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "testing successful IXFR ($n)"
|
||||
ret=0
|
||||
|
||||
# We change the IP address of a.nil., and the TXT record at the apex.
|
||||
# Then we do a SOA-only update.
|
||||
@@ -94,17 +96,17 @@ EOF
|
||||
|
||||
sleep 1
|
||||
|
||||
$RNDCCMD 10.53.0.1 refresh nil
|
||||
$RNDCCMD 10.53.0.1 refresh nil | sed 's/^/ns1 /' | cat_i
|
||||
|
||||
sleep 2
|
||||
|
||||
$DIG $DIGOPTS @10.53.0.1 nil. TXT | grep 'successful IXFR' >/dev/null || {
|
||||
echo_i "failed"
|
||||
status=1
|
||||
}
|
||||
$DIG $DIGOPTS @10.53.0.1 nil. TXT | grep 'successful IXFR' >/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 ($n)"
|
||||
ret=0
|
||||
|
||||
# Provide a broken IXFR response and a working fallback AXFR response
|
||||
|
||||
@@ -129,14 +131,13 @@ EOF
|
||||
|
||||
sleep 1
|
||||
|
||||
$RNDCCMD 10.53.0.1 refresh nil
|
||||
$RNDCCMD 10.53.0.1 refresh nil | sed 's/^/ns1 /' | cat_i
|
||||
|
||||
sleep 2
|
||||
|
||||
$DIG $DIGOPTS @10.53.0.1 nil. TXT | grep 'fallback AXFR' >/dev/null || {
|
||||
echo_i "failed"
|
||||
status=1
|
||||
}
|
||||
$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 ixfr-from-differences option ($n)"
|
||||
@@ -146,150 +147,84 @@ if [ $? -ne 0 ]
|
||||
then
|
||||
echo_i "named-checkzone returned failure on ns3/mytest.db"
|
||||
fi
|
||||
# modify the primary
|
||||
#echo_i "digging against primary: "
|
||||
#$DIG $DIGOPTS @10.53.0.3 a host1.test.
|
||||
#echo_i "digging against secondary: "
|
||||
#$DIG $DIGOPTS @10.53.0.4 a host1.test.
|
||||
|
||||
# wait for secondary to be stable
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
$DIG $DIGOPTS +tcp @10.53.0.4 SOA test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..1" dig.out.test$n > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
retry_quiet 10 wait_for_serial 10.53.0.4 test. 1 dig.out.test$n || ret=1
|
||||
|
||||
nextpart ns4/named.run > /dev/null
|
||||
|
||||
# modify the primary
|
||||
cp ns3/mytest1.db ns3/mytest.db
|
||||
$RNDCCMD 10.53.0.3 reload | sed 's/^/ns3 /' | cat_i
|
||||
|
||||
#wait for primary to reload load
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
$DIG $DIGOPTS +tcp @10.53.0.3 SOA test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..2" dig.out.test$n > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
# wait for primary to reload
|
||||
retry_quiet 10 wait_for_serial 10.53.0.3 test. 2 dig.out.test$n || ret=1
|
||||
|
||||
#wait for secondary to transfer zone
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
do
|
||||
$DIG $DIGOPTS +tcp @10.53.0.4 SOA test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..2" dig.out.test$n > /dev/null && break
|
||||
|
||||
# re-notify if we've been waiting a long time
|
||||
if [ $i -ge 5 ]; then
|
||||
$RNDCCMD 10.53.0.3 notify test | set 's/^/ns3 /' | cat_i
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# secondary should have gotten notify and updated
|
||||
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
INCR=`grep "test/IN/primary" ns4/named.run|grep "got incremental"|wc -l`
|
||||
[ $INCR -eq 1 ] && break
|
||||
sleep 1
|
||||
done
|
||||
if [ $INCR -ne 1 ]
|
||||
then
|
||||
echo_i "failed to get incremental response"
|
||||
status=1
|
||||
# wait for secondary to reload
|
||||
tret=0
|
||||
retry_quiet 5 wait_for_serial 10.53.0.4 test. 2 dig.out.test$n || tret=1
|
||||
if [ $tret -eq 1 ]; then
|
||||
# re-noitfy after 5 seconds, then wait another 10
|
||||
$RNDCCMD 10.53.0.3 notify test | set 's/^/ns3 /' | cat_i
|
||||
retry_quiet 10 wait_for_serial 10.53.0.4 test. 2 dig.out.test$n || ret=1
|
||||
fi
|
||||
|
||||
wait_for_log 10 'got incremental' ns4/named.run || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "testing request-ixfr option in view vs zone ($n)"
|
||||
echo_i "testing 'request-ixfr no' option inheritance from view ($n)"
|
||||
ret=0
|
||||
# There's a view with 2 zones. In the view, "request-ixfr yes"
|
||||
# but in the zone "sub.test", request-ixfr no"
|
||||
# we want to make sure that a change to sub.test results in AXFR, while
|
||||
# changes to test. result in IXFR
|
||||
|
||||
echo_ic "this result should be AXFR"
|
||||
cp ns3/subtest1.db ns3/subtest.db # change to sub.test zone, should be AXFR
|
||||
nextpart ns4/named.run > /dev/null
|
||||
$RNDCCMD 10.53.0.3 reload | sed 's/^/ns3 /' | cat_i
|
||||
|
||||
#wait for primary to reload zone
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
$DIG $DIGOPTS +tcp @10.53.0.3 SOA sub.test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..3" dig.out.test$n > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
# wait for primary to reload
|
||||
retry_quiet 10 wait_for_serial 10.53.0.3 sub.test. 3 dig.out.test$n || ret=1
|
||||
|
||||
#wait for secondary to transfer zone
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
do
|
||||
$DIG $DIGOPTS +tcp @10.53.0.4 SOA sub.test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..3" dig.out.test$n > /dev/null && break
|
||||
|
||||
# re-notify if we've been waiting a long time
|
||||
if [ $i -ge 5 ]; then
|
||||
$RNDCCMD 10.53.0.3 notify sub.test | set 's/^/ns3 /' | cat_i
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo_ic "this result should be AXFR"
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
NONINCR=`grep 'sub\.test/IN/primary' ns4/named.run|grep "got nonincremental" | wc -l`
|
||||
[ $NONINCR -eq 2 ] && break
|
||||
sleep 1
|
||||
done
|
||||
if [ $NONINCR -ne 2 ]
|
||||
then
|
||||
echo_ic "failed to get nonincremental response in 2nd AXFR test"
|
||||
|
||||
echo_i "failed"
|
||||
status=1
|
||||
else
|
||||
echo_ic "success: AXFR it was"
|
||||
# wait for secondary to reload
|
||||
tret=0
|
||||
retry_quiet 5 wait_for_serial 10.53.0.4 sub.test. 3 dig.out.test$n || tret=1
|
||||
if [ $tret -eq 1 ]; then
|
||||
# re-noitfy after 5 seconds, then wait another 10
|
||||
$RNDCCMD 10.53.0.3 notify sub.test | set 's/^/ns3 /' | cat_i
|
||||
retry_quiet 10 wait_for_serial 10.53.0.4 sub.test. 3 dig.out.test$n || ret=1
|
||||
fi
|
||||
|
||||
echo_ic "this result should be IXFR"
|
||||
cp ns3/mytest2.db ns3/mytest.db # change to test zone, should be IXFR
|
||||
$RNDCCMD 10.53.0.3 reload | sed 's/^/ns3 /' | cat_i
|
||||
|
||||
# wait for primary to reload zone
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
$DIG +tcp -p 5300 @10.53.0.3 SOA test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..4" dig.out.test$n > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# wait for secondary to transfer zone
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
do
|
||||
$DIG $DIGOPTS +tcp @10.53.0.4 SOA test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..4" dig.out.test$n > /dev/null && break
|
||||
|
||||
# re-notify if we've been waiting a long time
|
||||
if [ $i -ge 5 ]; then
|
||||
$RNDCCMD 10.53.0.3 notify test | set 's/^/ns3 /' | cat_i
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
for i in 0 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
INCR=`grep "test/IN/primary" ns4/named.run|grep "got incremental"|wc -l`
|
||||
[ $INCR -eq 2 ] && break
|
||||
sleep 1
|
||||
done
|
||||
if [ $INCR -ne 2 ]
|
||||
then
|
||||
echo_ic "failed to get incremental response in 2nd IXFR test"
|
||||
|
||||
echo_i "failed"
|
||||
status=1
|
||||
else
|
||||
echo_ic "success: IXFR it was"
|
||||
fi
|
||||
wait_for_log 10 'got nonincremental response' ns4/named.run || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "testing 'request-ixfr yes' option inheritance from view ($n)"
|
||||
ret=0
|
||||
cp ns3/mytest2.db ns3/mytest.db # change to test zone, should be IXFR
|
||||
nextpart ns4/named.run > /dev/null
|
||||
$RNDCCMD 10.53.0.3 reload | sed 's/^/ns3 /' | cat_i
|
||||
|
||||
# wait for primary to reload
|
||||
retry_quiet 10 wait_for_serial 10.53.0.3 test. 3 dig.out.test$n || ret=1
|
||||
|
||||
# wait for secondary to reload
|
||||
tret=0
|
||||
retry_quiet 5 wait_for_serial 10.53.0.4 test. 3 dig.out.test$n || tret=1
|
||||
if [ $tret -eq 1 ]; then
|
||||
# re-noitfy after 5 seconds, then wait another 10
|
||||
$RNDCCMD 10.53.0.3 notify test | set 's/^/ns3 /' | cat_i
|
||||
retry_quiet 10 wait_for_serial 10.53.0.4 test. 3 dig.out.test$n || ret=1
|
||||
fi
|
||||
|
||||
wait_for_log 10 'got incremental response' ns4/named.run || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
ret=0
|
||||
echo_i "testing DiG's handling of a multi message AXFR style IXFR response ($n)"
|
||||
(
|
||||
(sleep 10 && kill $$) 2>/dev/null &
|
||||
@@ -298,9 +233,11 @@ $DIG -p ${PORT} ixfr=0 large @10.53.0.3 > dig.out.test$n
|
||||
kill $sub
|
||||
)
|
||||
lines=`grep hostmaster.large dig.out.test$n | wc -l`
|
||||
test ${lines:-0} -eq 2 || { echo_i "failed"; status=1; }
|
||||
test ${lines:-0} -eq 2 || ret=1
|
||||
messages=`sed -n 's/^;;.*messages \([0-9]*\),.*/\1/p' dig.out.test$n`
|
||||
test ${messages:-0} -gt 1 || { echo_i "failed"; status=1; }
|
||||
test ${messages:-0} -gt 1 || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "test 'dig +notcp ixfr=<value>' vs 'dig ixfr=<value> +notcp' vs 'dig ixfr=<value>' ($n)"
|
||||
@@ -314,24 +251,19 @@ awk '$4 == "SOA" { if ($7 == 3) exit(0); else exit(1);}' dig.out1.test$n || ret=
|
||||
# Should be incremental transfer.
|
||||
$DIG $DIGOPTS ixfr=1 test @10.53.0.4 > dig.out3.test$n || ret=1
|
||||
awk '$4 == "SOA" { soacnt++} END { if (soacnt == 6) exit(0); else exit(1);}' dig.out3.test$n || ret=1
|
||||
if [ ${ret} != 0 ]; then
|
||||
echo_i "failed"
|
||||
status=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
# make sure ns5 has transfered the zone
|
||||
# wait for secondary to reload
|
||||
tret=0
|
||||
retry_quiet 5 wait_for_serial 10.53.0.5 test. 4 dig.out.test$n || tret=1
|
||||
if [ $tret -eq 1 ]; then
|
||||
# re-noitfy after 5 seconds, then wait another 10
|
||||
$RNDCCMD 10.53.0.3 notify test | set 's/^/ns3 /' | cat_i
|
||||
retry_quiet 10 wait_for_serial 10.53.0.5 test. 3 dig.out.test$n || ret=1
|
||||
fi
|
||||
|
||||
# wait for secondary to transfer zone
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
do
|
||||
$DIG $DIGOPTS +tcp @10.53.0.5 SOA test > dig.out.test$n
|
||||
grep -i "hostmaster\.test\..4" dig.out.test$n > /dev/null && break
|
||||
|
||||
# re-notify if we've been waiting a long time
|
||||
if [ $i -ge 5 ]; then
|
||||
$RNDCCMD 10.53.0.3 notify test | set 's/^/ns3 /' | cat_i
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "test 'provide-ixfr no;' (serial < current) ($n)"
|
||||
ret=0
|
||||
@@ -342,32 +274,6 @@ $DIG $DIGOPTS ixfr=1 test @10.53.0.5 > dig.out1.test$n || ret=1
|
||||
$DIG $DIGOPTS ixfr=1 +notcp test @10.53.0.5 > dig.out2.test$n || ret=1
|
||||
awk '$4 == "SOA" { soacnt++} END {if (soacnt == 2) exit(0); else exit(1);}' dig.out1.test$n || ret=1
|
||||
awk '$4 == "SOA" { soacnt++} END {if (soacnt == 1) exit(0); else exit(1);}' dig.out2.test$n || ret=1
|
||||
msg="IXFR delta response disabled due to 'provide-ixfr no;' being set"
|
||||
nextpart ns5/named.run | grep "$msg" > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "test 'provide-ixfr no;' (serial = current) ($n)"
|
||||
ret=0
|
||||
# Should be "AXFR style" response
|
||||
$DIG $DIGOPTS ixfr=3 test @10.53.0.5 > dig.out1.test$n || ret=1
|
||||
# Should be "switch to TCP" response
|
||||
$DIG $DIGOPTS ixfr=3 +notcp test @10.53.0.5 > dig.out2.test$n || ret=1
|
||||
awk '$4 == "SOA" { soacnt++} END {if (soacnt == 1) exit(0); else exit(1);}' dig.out1.test$n || ret=1
|
||||
awk '$4 == "SOA" { soacnt++} END {if (soacnt == 1) exit(0); else exit(1);}' dig.out2.test$n || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "test 'provide-ixfr no;' (serial > current) ($n)"
|
||||
ret=0
|
||||
# Should be "AXFR style" response
|
||||
$DIG $DIGOPTS ixfr=4 test @10.53.0.5 > dig.out1.test$n || ret=1
|
||||
# Should be "switch to TCP" response
|
||||
$DIG $DIGOPTS ixfr=4 +notcp test @10.53.0.5 > dig.out2.test$n || ret=1
|
||||
awk '$4 == "SOA" { soacnt++} END {if (soacnt == 1) exit(0); else exit(1);}' dig.out1.test$n || ret=1
|
||||
awk '$4 == "SOA" { soacnt++} END {if (soacnt == 1) exit(0); else exit(1);}' dig.out2.test$n || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
@@ -376,32 +282,51 @@ echo_i "checking whether dig calculates IXFR statistics correctly ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS +noedns +stat -b 10.53.0.4 @10.53.0.4 test. ixfr=2 > dig.out1.test$n
|
||||
get_dig_xfer_stats dig.out1.test$n > stats.dig
|
||||
diff ixfr-stats.good stats.dig || ret=1
|
||||
diff ixfr-stats.good stats.dig > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
# Note: in the next two tests, we use ns4 logs for checking both incoming and
|
||||
# outgoing transfer statistics as ns4 is both a secondary server (for ns3) and a
|
||||
# primary server (for dig queries from the previous test) for "test".
|
||||
|
||||
_wait_for_stats () {
|
||||
get_named_xfer_stats ns4/named.run "$1" test "$2" > "$3"
|
||||
diff ixfr-stats.good "$3" > /dev/null || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "checking whether named calculates incoming IXFR statistics correctly ($n)"
|
||||
ret=0
|
||||
get_named_xfer_stats ns4/named.run 10.53.0.3 test "Transfer completed" > stats.incoming
|
||||
diff ixfr-stats.good stats.incoming || ret=1
|
||||
retry_quiet 10 _wait_for_stats 10.53.0.3 "Transfer completed" stats.incoming
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "checking whether named calculates outgoing IXFR statistics correctly ($n)"
|
||||
ret=1
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
get_named_xfer_stats ns4/named.run 10.53.0.4 test "IXFR ended" > stats.outgoing
|
||||
if diff ixfr-stats.good stats.outgoing > /dev/null; then
|
||||
ret=0
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
retry_quiet 10 _wait_for_stats 10.53.0.4 "IXFR ended" stats.outgoing
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
ret=0
|
||||
echo_i "testing fallback to AXFR when max-ixfr-ratio is exceeded ($n)"
|
||||
nextpart ns4/named.run > /dev/null
|
||||
|
||||
cp ns3/mytest3.db ns3/mytest.db # change to test zone, too big for IXFR
|
||||
$RNDCCMD 10.53.0.3 reload | sed 's/^/ns3 /' | cat_i
|
||||
|
||||
# wait for secondary to reload
|
||||
tret=0
|
||||
retry_quiet 5 wait_for_serial 10.53.0.4 test. 4 dig.out.test$n || tret=1
|
||||
if [ $tret -eq 1 ]; then
|
||||
# re-noitfy after 5 seconds, then wait another 10
|
||||
$RNDCCMD 10.53.0.3 notify test | set 's/^/ns3 /' | cat_i
|
||||
retry_quiet 10 wait_for_serial 10.53.0.4 test. 4 dig.out.test$n || ret=1
|
||||
fi
|
||||
|
||||
wait_for_log 10 'got nonincremental response' ns4/named.run || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
|
||||
Regular → Executable
@@ -35,6 +35,7 @@ zone <string> [ <class> ] {
|
||||
key-directory <quoted_string>;
|
||||
masterfile-format ( map | raw | text );
|
||||
masterfile-style ( full | relative );
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-transfer-idle-out <integer>;
|
||||
|
||||
@@ -16,6 +16,7 @@ zone <string> [ <class> ] {
|
||||
masterfile-format ( map | raw | text );
|
||||
masterfile-style ( full | relative );
|
||||
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-refresh-time <integer>;
|
||||
|
||||
@@ -241,6 +241,7 @@ options {
|
||||
max-cache-ttl <duration>;
|
||||
max-clients-per-query <integer>;
|
||||
max-ixfr-log-size ( default | unlimited | <sizeval> ); // ancient
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-ncache-ttl <duration>;
|
||||
max-records <integer>;
|
||||
@@ -608,6 +609,7 @@ view <string> [ <class> ] {
|
||||
max-cache-ttl <duration>;
|
||||
max-clients-per-query <integer>;
|
||||
max-ixfr-log-size ( default | unlimited | <sizeval> ); // ancient
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-ncache-ttl <duration>;
|
||||
max-records <integer>;
|
||||
@@ -835,6 +837,7 @@ view <string> [ <class> ] {
|
||||
... };
|
||||
max-ixfr-log-size ( default | unlimited |
|
||||
<sizeval> ); // ancient
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-refresh-time <integer>;
|
||||
@@ -943,6 +946,7 @@ zone <string> [ <class> ] {
|
||||
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
|
||||
<integer> ] ) [ key <string> ]; ... };
|
||||
max-ixfr-log-size ( default | unlimited | <sizeval> ); // ancient
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-refresh-time <integer>;
|
||||
|
||||
@@ -215,6 +215,7 @@ options {
|
||||
max-cache-size ( default | unlimited | <sizeval> | <percentage> );
|
||||
max-cache-ttl <duration>;
|
||||
max-clients-per-query <integer>;
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-ncache-ttl <duration>;
|
||||
max-records <integer>;
|
||||
@@ -545,6 +546,7 @@ view <string> [ <class> ] {
|
||||
max-cache-size ( default | unlimited | <sizeval> | <percentage> );
|
||||
max-cache-ttl <duration>;
|
||||
max-clients-per-query <integer>;
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-ncache-ttl <duration>;
|
||||
max-records <integer>;
|
||||
@@ -755,6 +757,7 @@ view <string> [ <class> ] {
|
||||
<primaries> | <ipv4_address> [ port <integer> ] |
|
||||
<ipv6_address> [ port <integer> ] ) [ key <string> ];
|
||||
... };
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-refresh-time <integer>;
|
||||
@@ -856,6 +859,7 @@ zone <string> [ <class> ] {
|
||||
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
|
||||
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
|
||||
<integer> ] ) [ key <string> ]; ... };
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-refresh-time <integer>;
|
||||
|
||||
@@ -28,6 +28,7 @@ zone <string> [ <class> ] {
|
||||
masterfile-format ( map | raw | text );
|
||||
masterfile-style ( full | relative );
|
||||
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-refresh-time <integer>;
|
||||
|
||||
@@ -24,7 +24,18 @@ Known Issues
|
||||
New Features
|
||||
~~~~~~~~~~~~
|
||||
|
||||
- None.
|
||||
- When a secondary server receives a large incremental zone
|
||||
transfer (IXFR), it can have a negative impact on query
|
||||
performance while the incremental changes are applied to
|
||||
the zone. To address this, ``named`` can now
|
||||
limit the size of IXFR responses it sends in response to zone
|
||||
transfer requests. If an IXFR response would be larger than an
|
||||
AXFR of the entire zone, it will send an AXFR resonse instead.
|
||||
|
||||
This behavior is controlled by the ``max-ixfr-ratio``
|
||||
option - a percentage value representing the ratio of IXFR size
|
||||
to the size of a full zone transfer. This value cannot exceed
|
||||
100%, which is also the default. [GL #1515]
|
||||
|
||||
Removed Features
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1567,6 +1567,24 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(options, "max-ixfr-ratio", &obj);
|
||||
if (obj != NULL && cfg_obj_ispercentage(obj)) {
|
||||
uint32_t percent = cfg_obj_aspercentage(obj);
|
||||
if (percent == 0) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'ixfr-max-ratio' must be a nonzero "
|
||||
"percentage or 'unlimited')");
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_RANGE;
|
||||
}
|
||||
} else if (percent > 100) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
|
||||
"'ixfr-max-ratio %d%%' exceeds 100%%",
|
||||
percent);
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(options, "check-names", &obj);
|
||||
if (obj != NULL && !cfg_obj_islist(obj)) {
|
||||
|
||||
@@ -1489,10 +1489,10 @@ dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
|
||||
|
||||
isc_result_t
|
||||
dns_db_getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records,
|
||||
uint64_t *bytes);
|
||||
uint64_t *xfrsize);
|
||||
/*%<
|
||||
* On success if 'records' is not NULL, it is set to the number of records
|
||||
* in the given version of the database. If 'bytes' is not NULL, it is
|
||||
* in the given version of the database. If 'xfrisize' is not NULL, it is
|
||||
* set to the approximate number of bytes needed to transfer the records,
|
||||
* counting name, TTL, type, class, and rdata for each RR. (This is meant
|
||||
* to be a rough approximation of the size of a full zone transfer, though
|
||||
@@ -1502,7 +1502,7 @@ dns_db_getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records,
|
||||
* \li 'db' is a valid zone database.
|
||||
* \li 'version' is NULL or a valid version.
|
||||
* \li 'records' is NULL or a pointer to return the record count in.
|
||||
* \li 'bytes' is NULL or a pointer to return the byte count in.
|
||||
* \li 'xfrsize' is NULL or a pointer to return the byte count in.
|
||||
*
|
||||
* Returns:
|
||||
* \li #ISC_R_SUCCESS
|
||||
|
||||
@@ -190,11 +190,17 @@ dns_journal_last_serial(dns_journal_t *j);
|
||||
|
||||
isc_result_t
|
||||
dns_journal_iter_init(dns_journal_t *j, uint32_t begin_serial,
|
||||
uint32_t end_serial);
|
||||
uint32_t end_serial, size_t *xfrsizep);
|
||||
/*%<
|
||||
* Prepare to iterate over the transactions that will bring the database
|
||||
* from SOA serial number 'begin_serial' to 'end_serial'.
|
||||
*
|
||||
* If 'xfrsizep' is not NULL, then on success it will be set to the
|
||||
* total size of all records in the iteration (excluding headers). This
|
||||
* is meant to be a rough approximation of the size of an incremental
|
||||
* zone transfer, though it does not account for DNS message overhead
|
||||
* or name compression.)
|
||||
*
|
||||
* Returns:
|
||||
*\li ISC_R_SUCCESS
|
||||
*\li ISC_R_RANGE begin_serial is outside the addressable range.
|
||||
|
||||
@@ -2338,6 +2338,25 @@ dns_zone_setrequestixfr(dns_zone_t *zone, bool flag);
|
||||
* \li 'zone' to be valid.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_zone_getixfrratio(dns_zone_t *zone);
|
||||
/*%
|
||||
* Returns the zone's current IXFR ratio.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'zone' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio);
|
||||
/*%
|
||||
* Sets the ratio of IXFR size to zone size above which we use an AXFR
|
||||
* response, expressed as a percentage. Cannot exceed 100.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'zone' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method);
|
||||
/*%
|
||||
|
||||
+54
-13
@@ -221,6 +221,7 @@ typedef union {
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char size[4]; /*%< In bytes, excluding header. */
|
||||
unsigned char count[4]; /*%< Number of records in transaction */
|
||||
unsigned char serial0[4]; /*%< SOA serial before update. */
|
||||
unsigned char serial1[4]; /*%< SOA serial after update. */
|
||||
} journal_rawxhdr_t;
|
||||
@@ -256,9 +257,9 @@ typedef struct {
|
||||
/*%
|
||||
* The in-core representation of the transaction header.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t size;
|
||||
uint32_t count;
|
||||
uint32_t serial0;
|
||||
uint32_t serial1;
|
||||
} journal_xhdr_t;
|
||||
@@ -304,13 +305,13 @@ struct dns_journal {
|
||||
isc_offset_t offset; /*%< Current file offset */
|
||||
journal_header_t header; /*%< In-core journal header */
|
||||
unsigned char *rawindex; /*%< In-core buffer for journal index
|
||||
* in
|
||||
* on-disk format */
|
||||
* in on-disk format */
|
||||
journal_pos_t *index; /*%< In-core journal index */
|
||||
|
||||
/*% Current transaction state (when writing). */
|
||||
struct {
|
||||
unsigned int n_soa; /*%< Number of SOAs seen */
|
||||
unsigned int n_rr; /*%< Number of RRs to write */
|
||||
journal_pos_t pos[2]; /*%< Begin/end position */
|
||||
} x;
|
||||
|
||||
@@ -323,8 +324,7 @@ struct dns_journal {
|
||||
uint32_t current_serial; /*%< Current SOA serial
|
||||
* */
|
||||
isc_buffer_t source; /*%< Data from disk */
|
||||
isc_buffer_t target; /*%< Data from _fromwire check
|
||||
* */
|
||||
isc_buffer_t target; /*%< Data from _fromwire check */
|
||||
dns_decompress_t dctx; /*%< Dummy decompression ctx */
|
||||
dns_name_t name; /*%< Current domain name */
|
||||
dns_rdata_t rdata; /*%< Current rdata */
|
||||
@@ -462,16 +462,18 @@ journal_read_xhdr(dns_journal_t *j, journal_xhdr_t *xhdr) {
|
||||
return (result);
|
||||
}
|
||||
xhdr->size = decode_uint32(raw.size);
|
||||
xhdr->count = decode_uint32(raw.count);
|
||||
xhdr->serial0 = decode_uint32(raw.serial0);
|
||||
xhdr->serial1 = decode_uint32(raw.serial1);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
journal_write_xhdr(dns_journal_t *j, uint32_t size, uint32_t serial0,
|
||||
uint32_t serial1) {
|
||||
journal_write_xhdr(dns_journal_t *j, uint32_t size, uint32_t count,
|
||||
uint32_t serial0, uint32_t serial1) {
|
||||
journal_rawxhdr_t raw;
|
||||
encode_uint32(size, raw.size);
|
||||
encode_uint32(count, raw.count);
|
||||
encode_uint32(serial0, raw.serial0);
|
||||
encode_uint32(serial1, raw.serial1);
|
||||
return (journal_write(j, &raw, sizeof(raw)));
|
||||
@@ -1026,7 +1028,8 @@ dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) {
|
||||
dns_difftuple_t *t;
|
||||
isc_buffer_t buffer;
|
||||
void *mem = NULL;
|
||||
uint64_t size;
|
||||
uint64_t size = 0;
|
||||
uint32_t rrcount = 0;
|
||||
isc_result_t result;
|
||||
isc_region_t used;
|
||||
|
||||
@@ -1040,7 +1043,6 @@ dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) {
|
||||
* Pass 1: determine the buffer size needed, and
|
||||
* keep track of SOA serial numbers.
|
||||
*/
|
||||
size = 0;
|
||||
for (t = ISC_LIST_HEAD(diff->tuples); t != NULL;
|
||||
t = ISC_LIST_NEXT(t, link)) {
|
||||
if (t->rdata.type == dns_rdatatype_soa) {
|
||||
@@ -1089,12 +1091,15 @@ dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) {
|
||||
isc_buffer_putuint16(&buffer, (uint16_t)t->rdata.length);
|
||||
INSIST(isc_buffer_availablelength(&buffer) >= t->rdata.length);
|
||||
isc_buffer_putmem(&buffer, t->rdata.data, t->rdata.length);
|
||||
|
||||
rrcount++;
|
||||
}
|
||||
|
||||
isc_buffer_usedregion(&buffer, &used);
|
||||
INSIST(used.length == size);
|
||||
|
||||
j->x.pos[1].offset += used.length;
|
||||
j->x.n_rr = rrcount;
|
||||
|
||||
/*
|
||||
* Write the buffer contents to the journal file.
|
||||
@@ -1205,7 +1210,8 @@ dns_journal_commit(dns_journal_t *j) {
|
||||
* Update the transaction header.
|
||||
*/
|
||||
CHECK(journal_seek(j, j->x.pos[0].offset));
|
||||
CHECK(journal_write_xhdr(j, offset, j->x.pos[0].serial,
|
||||
CHECK(journal_write_xhdr(j, offset, j->x.n_rr,
|
||||
j->x.pos[0].serial,
|
||||
j->x.pos[1].serial));
|
||||
}
|
||||
|
||||
@@ -1355,7 +1361,7 @@ roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) {
|
||||
CHECK(DNS_R_UPTODATE);
|
||||
}
|
||||
|
||||
CHECK(dns_journal_iter_init(j, db_serial, end_serial));
|
||||
CHECK(dns_journal_iter_init(j, db_serial, end_serial, NULL));
|
||||
|
||||
for (result = dns_journal_first_rr(j); result == ISC_R_SUCCESS;
|
||||
result = dns_journal_next_rr(j))
|
||||
@@ -1515,7 +1521,7 @@ dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file) {
|
||||
start_serial = dns_journal_first_serial(j);
|
||||
end_serial = dns_journal_last_serial(j);
|
||||
|
||||
CHECK(dns_journal_iter_init(j, start_serial, end_serial));
|
||||
CHECK(dns_journal_iter_init(j, start_serial, end_serial, NULL));
|
||||
|
||||
for (result = dns_journal_first_rr(j); result == ISC_R_SUCCESS;
|
||||
result = dns_journal_next_rr(j))
|
||||
@@ -1672,7 +1678,7 @@ size_buffer(isc_mem_t *mctx, isc_buffer_t *b, unsigned size) {
|
||||
|
||||
isc_result_t
|
||||
dns_journal_iter_init(dns_journal_t *j, uint32_t begin_serial,
|
||||
uint32_t end_serial) {
|
||||
uint32_t end_serial, size_t *xfrsizep) {
|
||||
isc_result_t result;
|
||||
|
||||
CHECK(journal_find(j, begin_serial, &j->it.bpos));
|
||||
@@ -1681,6 +1687,41 @@ dns_journal_iter_init(dns_journal_t *j, uint32_t begin_serial,
|
||||
CHECK(journal_find(j, end_serial, &j->it.epos));
|
||||
INSIST(j->it.epos.serial == end_serial);
|
||||
|
||||
if (xfrsizep != NULL) {
|
||||
journal_pos_t pos = j->it.bpos;
|
||||
journal_xhdr_t xhdr;
|
||||
uint64_t size = 0;
|
||||
uint32_t count = 0;
|
||||
|
||||
/*
|
||||
* We already know the beginning and ending serial
|
||||
* numbers are in the journal. Scan through them,
|
||||
* adding up sizes and RR counts so we can calculate
|
||||
* the IXFR size.
|
||||
*/
|
||||
CHECK(journal_seek(j, pos.offset));
|
||||
do {
|
||||
CHECK(journal_read_xhdr(j, &xhdr));
|
||||
|
||||
size += xhdr.size;
|
||||
count += xhdr.count;
|
||||
|
||||
result = journal_next(j, &pos);
|
||||
if (result == ISC_R_NOMORE) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
CHECK(result);
|
||||
} while (pos.serial != end_serial);
|
||||
|
||||
/*
|
||||
* For each RR, subtract the length of the RR header,
|
||||
* as this would not be present in IXFR messages.
|
||||
* (We don't need to worry about the transaction header
|
||||
* because that was already excluded from xdr.size.)
|
||||
*/
|
||||
*xfrsizep = size - (count * sizeof(journal_rawrrhdr_t));
|
||||
}
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
failure:
|
||||
j->it.result = result;
|
||||
|
||||
+25
-25
@@ -441,11 +441,11 @@ typedef struct rbtdb_version {
|
||||
unsigned char salt[DNS_NSEC3_SALTSIZE];
|
||||
|
||||
/*
|
||||
* records and bytes are covered by rwlock.
|
||||
* records and xfrsize are covered by rwlock.
|
||||
*/
|
||||
isc_rwlock_t rwlock;
|
||||
uint64_t records;
|
||||
uint64_t bytes;
|
||||
uint64_t xfrsize;
|
||||
|
||||
isc_rwlock_t glue_rwlock;
|
||||
size_t glue_table_bits;
|
||||
@@ -1396,7 +1396,7 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) {
|
||||
RWLOCK(&rbtdb->current_version->rwlock,
|
||||
isc_rwlocktype_read);
|
||||
version->records = rbtdb->current_version->records;
|
||||
version->bytes = rbtdb->current_version->bytes;
|
||||
version->xfrsize = rbtdb->current_version->xfrsize;
|
||||
RWUNLOCK(&rbtdb->current_version->rwlock,
|
||||
isc_rwlocktype_read);
|
||||
rbtdb->next_serial++;
|
||||
@@ -6067,18 +6067,18 @@ recordsize(rdatasetheader_t *header, unsigned int namelen) {
|
||||
}
|
||||
|
||||
static void
|
||||
update_recordsandbytes(bool add, rbtdb_version_t *rbtversion,
|
||||
rdatasetheader_t *header, unsigned int namelen) {
|
||||
update_recordsandxfrsize(bool add, rbtdb_version_t *rbtversion,
|
||||
rdatasetheader_t *header, unsigned int namelen) {
|
||||
unsigned char *hdr = (unsigned char *)header;
|
||||
size_t hdrsize = sizeof(*header);
|
||||
|
||||
RWLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
|
||||
if (add) {
|
||||
rbtversion->records += dns_rdataslab_count(hdr, hdrsize);
|
||||
rbtversion->bytes += recordsize(header, namelen);
|
||||
rbtversion->xfrsize += recordsize(header, namelen);
|
||||
} else {
|
||||
rbtversion->records -= dns_rdataslab_count(hdr, hdrsize);
|
||||
rbtversion->bytes -= recordsize(header, namelen);
|
||||
rbtversion->xfrsize -= recordsize(header, namelen);
|
||||
}
|
||||
RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
|
||||
}
|
||||
@@ -6491,9 +6491,9 @@ find_header:
|
||||
}
|
||||
newheader->next = topheader->next;
|
||||
if (rbtversion != NULL && !header_nx) {
|
||||
update_recordsandbytes(false, rbtversion,
|
||||
header,
|
||||
nodename->length);
|
||||
update_recordsandxfrsize(false, rbtversion,
|
||||
header,
|
||||
nodename->length);
|
||||
}
|
||||
free_rdataset(rbtdb, rbtdb->common.mctx, header);
|
||||
} else {
|
||||
@@ -6544,9 +6544,9 @@ find_header:
|
||||
}
|
||||
}
|
||||
if (rbtversion != NULL && !header_nx) {
|
||||
update_recordsandbytes(false, rbtversion,
|
||||
header,
|
||||
nodename->length);
|
||||
update_recordsandxfrsize(false, rbtversion,
|
||||
header,
|
||||
nodename->length);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -6623,8 +6623,8 @@ find_header:
|
||||
}
|
||||
|
||||
if (rbtversion != NULL && !newheader_nx) {
|
||||
update_recordsandbytes(true, rbtversion, newheader,
|
||||
nodename->length);
|
||||
update_recordsandxfrsize(true, rbtversion, newheader,
|
||||
nodename->length);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -7118,8 +7118,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
* to additional info. We need to clear these fields
|
||||
* to avoid having duplicated references.
|
||||
*/
|
||||
update_recordsandbytes(true, rbtversion, newheader,
|
||||
nodename->length);
|
||||
update_recordsandxfrsize(true, rbtversion, newheader,
|
||||
nodename->length);
|
||||
} else if (result == DNS_R_NXRRSET) {
|
||||
/*
|
||||
* This subtraction would remove all of the rdata;
|
||||
@@ -7155,8 +7155,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
* topheader.
|
||||
*/
|
||||
INSIST(rbtversion->serial >= topheader->serial);
|
||||
update_recordsandbytes(false, rbtversion, header,
|
||||
nodename->length);
|
||||
update_recordsandxfrsize(false, rbtversion, header,
|
||||
nodename->length);
|
||||
if (topheader_prev != NULL) {
|
||||
topheader_prev->next = newheader;
|
||||
} else {
|
||||
@@ -7520,8 +7520,8 @@ rbt_datafixer(dns_rbtnode_t *rbtnode, void *base, size_t filesize, void *arg,
|
||||
}
|
||||
}
|
||||
|
||||
update_recordsandbytes(true, rbtdb->current_version, header,
|
||||
rbtnode->fullnamelen);
|
||||
update_recordsandxfrsize(true, rbtdb->current_version, header,
|
||||
rbtnode->fullnamelen);
|
||||
}
|
||||
|
||||
/* We're done deserializing; clear fullnamelen */
|
||||
@@ -8142,7 +8142,7 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
|
||||
|
||||
static isc_result_t
|
||||
getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records,
|
||||
uint64_t *bytes) {
|
||||
uint64_t *xfrsize) {
|
||||
dns_rbtdb_t *rbtdb;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
rbtdb_version_t *rbtversion = version;
|
||||
@@ -8162,8 +8162,8 @@ getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records,
|
||||
*records = rbtversion->records;
|
||||
}
|
||||
|
||||
if (bytes != NULL) {
|
||||
*bytes = rbtversion->bytes;
|
||||
if (xfrsize != NULL) {
|
||||
*xfrsize = rbtversion->xfrsize;
|
||||
}
|
||||
RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_read);
|
||||
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||
@@ -8805,7 +8805,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
||||
}
|
||||
|
||||
rbtdb->current_version->records = 0;
|
||||
rbtdb->current_version->bytes = 0;
|
||||
rbtdb->current_version->xfrsize = 0;
|
||||
rbtdb->future_version = NULL;
|
||||
ISC_LIST_INIT(rbtdb->open_versions);
|
||||
/*
|
||||
|
||||
@@ -1221,6 +1221,7 @@ dns_zone_getgluecachestats
|
||||
dns_zone_getidlein
|
||||
dns_zone_getidleout
|
||||
dns_zone_getincludes
|
||||
dns_zone_getixfrratio
|
||||
dns_zone_getjournal
|
||||
dns_zone_getjournalsize
|
||||
dns_zone_getkasp
|
||||
@@ -1323,6 +1324,7 @@ dns_zone_setforwardacl
|
||||
dns_zone_setidlein
|
||||
dns_zone_setidleout
|
||||
dns_zone_setisself
|
||||
dns_zone_setixfrratio
|
||||
dns_zone_setjournal
|
||||
dns_zone_setjournalsize
|
||||
dns_zone_setkasp
|
||||
|
||||
+2
-2
@@ -1529,10 +1529,10 @@ maybe_free(dns_xfrin_ctx_t *xfr) {
|
||||
xfrin_log(xfr, ISC_LOG_INFO,
|
||||
"Transfer completed: %d messages, %d records, "
|
||||
"%" PRIu64 " bytes, "
|
||||
"%u.%03u secs (%u bytes/sec)",
|
||||
"%u.%03u secs (%u bytes/sec) (serial %u)",
|
||||
xfr->nmsg, xfr->nrecs, xfr->nbytes,
|
||||
(unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
|
||||
(unsigned int)persec);
|
||||
(unsigned int)persec, xfr->end_serial);
|
||||
|
||||
if (xfr->socket != NULL) {
|
||||
isc_socket_detach(&xfr->socket);
|
||||
|
||||
+15
-1
@@ -407,6 +407,7 @@ struct dns_zone {
|
||||
* whether ixfr is requested
|
||||
*/
|
||||
bool requestixfr;
|
||||
uint32_t ixfr_ratio;
|
||||
|
||||
/*%
|
||||
* whether EDNS EXPIRE is requested
|
||||
@@ -1128,6 +1129,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
||||
zone->sourceserial = 0;
|
||||
zone->sourceserialset = false;
|
||||
zone->requestixfr = true;
|
||||
zone->ixfr_ratio = 100;
|
||||
zone->requestexpire = true;
|
||||
ISC_LIST_INIT(zone->rss_events);
|
||||
ISC_LIST_INIT(zone->rss_post);
|
||||
@@ -15741,7 +15743,7 @@ sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
|
||||
return (DNS_R_UNCHANGED);
|
||||
}
|
||||
|
||||
CHECK(dns_journal_iter_init(journal, start, end));
|
||||
CHECK(dns_journal_iter_init(journal, start, end, NULL));
|
||||
for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS;
|
||||
result = dns_journal_next_rr(journal))
|
||||
{
|
||||
@@ -20561,6 +20563,18 @@ dns_zone_getrequestixfr(dns_zone_t *zone) {
|
||||
return (zone->requestixfr);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
zone->ixfr_ratio = ratio;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_zone_getixfrratio(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
return (zone->ixfr_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
@@ -92,6 +92,7 @@ static cfg_type_t cfg_type_dnstapoutput;
|
||||
static cfg_type_t cfg_type_dyndb;
|
||||
static cfg_type_t cfg_type_plugin;
|
||||
static cfg_type_t cfg_type_ixfrdifftype;
|
||||
static cfg_type_t cfg_type_ixfrratio;
|
||||
static cfg_type_t cfg_type_key;
|
||||
static cfg_type_t cfg_type_logfile;
|
||||
static cfg_type_t cfg_type_logging;
|
||||
@@ -2203,6 +2204,8 @@ static cfg_clausedef_t zone_clauses[] = {
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB |
|
||||
CFG_ZONE_REDIRECT },
|
||||
{ "max-ixfr-log-size", &cfg_type_size, CFG_CLAUSEFLAG_ANCIENT },
|
||||
{ "max-ixfr-ratio", &cfg_type_ixfrratio,
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR },
|
||||
{ "max-journal-size", &cfg_type_size,
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR },
|
||||
{ "max-records", &cfg_type_uint32,
|
||||
@@ -2740,6 +2743,28 @@ static cfg_type_t cfg_type_sizeorpercent = {
|
||||
doc_parse_size_or_percent, &cfg_rep_string, sizeorpercent_enums
|
||||
};
|
||||
|
||||
/*%
|
||||
* An IXFR size ratio: percentage, or "unlimited".
|
||||
*/
|
||||
|
||||
static isc_result_t
|
||||
parse_ixfrratio(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
return (cfg_parse_enum_or_other(pctx, type, &cfg_type_percentage, ret));
|
||||
}
|
||||
|
||||
static void
|
||||
doc_ixfrratio(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
UNUSED(type);
|
||||
cfg_print_cstr(pctx, "( unlimited | ");
|
||||
cfg_doc_terminal(pctx, &cfg_type_percentage);
|
||||
cfg_print_cstr(pctx, " )");
|
||||
}
|
||||
|
||||
static const char *ixfrratio_enums[] = { "unlimited", NULL };
|
||||
static cfg_type_t cfg_type_ixfrratio = { "ixfr_ratio", parse_ixfrratio,
|
||||
NULL, doc_ixfrratio,
|
||||
NULL, ixfrratio_enums };
|
||||
|
||||
/*%
|
||||
* optional_keyvalue
|
||||
*/
|
||||
|
||||
+56
-6
@@ -225,10 +225,10 @@ static rrstream_methods_t ixfr_rrstream_methods;
|
||||
|
||||
static isc_result_t
|
||||
ixfr_rrstream_create(isc_mem_t *mctx, const char *journal_filename,
|
||||
uint32_t begin_serial, uint32_t end_serial,
|
||||
uint32_t begin_serial, uint32_t end_serial, size_t *sizep,
|
||||
rrstream_t **sp) {
|
||||
ixfr_rrstream_t *s;
|
||||
isc_result_t result;
|
||||
ixfr_rrstream_t *s = NULL;
|
||||
|
||||
INSIST(sp != NULL && *sp == NULL);
|
||||
|
||||
@@ -240,7 +240,8 @@ ixfr_rrstream_create(isc_mem_t *mctx, const char *journal_filename,
|
||||
|
||||
CHECK(dns_journal_open(mctx, journal_filename, DNS_JOURNAL_READ,
|
||||
&s->journal));
|
||||
CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial));
|
||||
CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial,
|
||||
sizep));
|
||||
|
||||
*sp = (rrstream_t *)s;
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -663,6 +664,7 @@ typedef struct {
|
||||
bool shuttingdown;
|
||||
bool poll;
|
||||
const char *mnemonic; /* Style of transfer */
|
||||
uint32_t end_serial; /* Serial number after XFR is done */
|
||||
struct xfr_stats stats; /*%< Transfer statistics */
|
||||
} xfrout_ctx_t;
|
||||
|
||||
@@ -959,6 +961,26 @@ got_soa:
|
||||
|
||||
current_serial = dns_soa_getserial(¤t_soa_tuple->rdata);
|
||||
if (reqtype == dns_rdatatype_ixfr) {
|
||||
size_t jsize;
|
||||
uint64_t dbsize;
|
||||
|
||||
/*
|
||||
* Outgoing IXFR may have been disabled for this peer
|
||||
* or globally.
|
||||
*/
|
||||
if ((client->attributes & NS_CLIENTATTR_TCP) != 0) {
|
||||
bool provide_ixfr;
|
||||
|
||||
provide_ixfr = client->view->provideixfr;
|
||||
if (peer != NULL) {
|
||||
(void)dns_peer_getprovideixfr(peer,
|
||||
&provide_ixfr);
|
||||
}
|
||||
if (provide_ixfr == false) {
|
||||
goto axfr_fallback;
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_soa) {
|
||||
FAILC(DNS_R_FORMERR, "IXFR request missing SOA");
|
||||
}
|
||||
@@ -1010,7 +1032,7 @@ got_soa:
|
||||
if (journalfile != NULL) {
|
||||
result = ixfr_rrstream_create(
|
||||
mctx, journalfile, begin_serial, current_serial,
|
||||
&data_stream);
|
||||
&jsize, &data_stream);
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
@@ -1023,6 +1045,32 @@ got_soa:
|
||||
goto axfr_fallback;
|
||||
}
|
||||
CHECK(result);
|
||||
|
||||
result = dns_db_getsize(db, ver, NULL, &dbsize);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
uint32_t ratio = dns_zone_getixfrratio(zone);
|
||||
if (ratio != 0 && ((100 * jsize) / dbsize) > ratio) {
|
||||
data_stream->methods->destroy(&data_stream);
|
||||
data_stream = NULL;
|
||||
xfrout_log1(client, question_name,
|
||||
question_class, ISC_LOG_DEBUG(4),
|
||||
"IXFR delta size (%zu bytes) "
|
||||
"exceeds the maximum ratio to "
|
||||
"database size "
|
||||
"(%" PRIu64 " bytes), "
|
||||
"falling back to AXFR",
|
||||
jsize, dbsize);
|
||||
mnemonic = "AXFR-style IXFR";
|
||||
goto axfr_fallback;
|
||||
} else {
|
||||
xfrout_log1(client, question_name,
|
||||
question_class, ISC_LOG_DEBUG(4),
|
||||
"IXFR delta size (%zu bytes); "
|
||||
"database size "
|
||||
"(%" PRIu64 " bytes)",
|
||||
jsize, dbsize);
|
||||
}
|
||||
}
|
||||
is_ixfr = true;
|
||||
} else {
|
||||
axfr_fallback:
|
||||
@@ -1062,6 +1110,7 @@ have_stream:
|
||||
(format == dns_many_answers) ? true : false, &xfr);
|
||||
}
|
||||
|
||||
xfr->end_serial = current_serial;
|
||||
xfr->mnemonic = mnemonic;
|
||||
stream = NULL;
|
||||
quota = NULL;
|
||||
@@ -1675,10 +1724,11 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
||||
"%s ended: "
|
||||
"%" PRIu64 " messages, %" PRIu64 " records, "
|
||||
"%" PRIu64 " bytes, "
|
||||
"%u.%03u secs (%u bytes/sec)",
|
||||
"%u.%03u secs (%u bytes/sec) (serial %u)",
|
||||
xfr->mnemonic, xfr->stats.nmsg, xfr->stats.nrecs,
|
||||
xfr->stats.nbytes, (unsigned int)(msecs / 1000),
|
||||
(unsigned int)(msecs % 1000), (unsigned int)persec);
|
||||
(unsigned int)(msecs % 1000), (unsigned int)persec,
|
||||
xfr->end_serial);
|
||||
|
||||
/*
|
||||
* We're done, unreference the handle and destroy the xfr
|
||||
|
||||
Reference in New Issue
Block a user