mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
new: usr: Implement the min-transfer-rate-in configuration option
A new option 'min-transfer-rate-in <bytes> <minutes>' has been added to the view and zone configurations. It can abort incoming zone transfers which run very slowly due to network related issues, for example. The default value is set to 10240 bytes in 5 minutes. Closes #3914 Merge branch '3914-detect-and-restart-stalled-zone-transfers' into 'main' See merge request isc-projects/bind9!9098
This commit is contained in:
commit
a282f1ba3f
@ -931,6 +931,7 @@
|
||||
<th>Messages Received</th>
|
||||
<th>Records Received</th>
|
||||
<th>Bytes Received</th>
|
||||
<th>Transfer Rate (B/s)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -959,6 +960,7 @@
|
||||
<td><xsl:value-of select="nmsg"/></td>
|
||||
<td><xsl:value-of select="nrecs"/></td>
|
||||
<td><xsl:value-of select="nbytes"/></td>
|
||||
<td><xsl:value-of select="rate"/></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
|
@ -232,6 +232,7 @@ options {\n\
|
||||
max-transfer-time-out 120;\n\
|
||||
min-refresh-time 300;\n\
|
||||
min-retry-time 500;\n\
|
||||
min-transfer-rate-in 10240 5;\n\
|
||||
multi-master no;\n\
|
||||
notify yes;\n\
|
||||
notify-delay 5;\n\
|
||||
|
@ -1488,6 +1488,7 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
|
||||
unsigned int nmsg = 0;
|
||||
unsigned int nrecs = 0;
|
||||
uint64_t nbytes = 0;
|
||||
uint64_t rate = 0;
|
||||
|
||||
statlevel = dns_zone_getstatlevel(zone);
|
||||
if (statlevel == dns_zonestat_none) {
|
||||
@ -1701,7 +1702,7 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
|
||||
TRY0(xmlTextWriterEndElement(writer));
|
||||
|
||||
if (is_running) {
|
||||
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes);
|
||||
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes, &rate);
|
||||
}
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nmsg"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%u", nmsg));
|
||||
@ -1712,6 +1713,9 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nbytes"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, nbytes));
|
||||
TRY0(xmlTextWriterEndElement(writer));
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rate"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, rate));
|
||||
TRY0(xmlTextWriterEndElement(writer));
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ixfr"));
|
||||
if (is_running && is_first_data_received) {
|
||||
@ -2559,6 +2563,7 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
|
||||
unsigned int nmsg = 0;
|
||||
unsigned int nrecs = 0;
|
||||
uint64_t nbytes = 0;
|
||||
uint64_t rate = 0;
|
||||
|
||||
statlevel = dns_zone_getstatlevel(zone);
|
||||
if (statlevel == dns_zonestat_none) {
|
||||
@ -2756,7 +2761,7 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
|
||||
}
|
||||
|
||||
if (is_running) {
|
||||
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes);
|
||||
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes, &rate);
|
||||
}
|
||||
json_object_object_add(xfrinobj, "nmsg",
|
||||
json_object_new_int64((int64_t)nmsg));
|
||||
@ -2766,6 +2771,10 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
|
||||
xfrinobj, "nbytes",
|
||||
json_object_new_int64(nbytes > INT64_MAX ? INT64_MAX
|
||||
: (int64_t)nbytes));
|
||||
json_object_object_add(xfrinobj, "rate",
|
||||
json_object_new_int64(rate > INT64_MAX
|
||||
? INT64_MAX
|
||||
: (int64_t)rate));
|
||||
|
||||
if (is_running && is_first_data_received) {
|
||||
json_object_object_add(
|
||||
|
@ -1874,6 +1874,33 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
}
|
||||
dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "min-transfer-rate-in", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
uint32_t traffic_bytes =
|
||||
cfg_obj_asuint32(cfg_tuple_get(obj, "traffic_bytes"));
|
||||
uint32_t time_minutes =
|
||||
cfg_obj_asuint32(cfg_tuple_get(obj, "time_minutes"));
|
||||
if (traffic_bytes == 0) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"zone '%s': 'min-transfer-rate-in' bytes"
|
||||
"value can not be '0'",
|
||||
zname);
|
||||
CHECK(ISC_R_FAILURE);
|
||||
}
|
||||
/* Max. 28 days (in minutes). */
|
||||
const unsigned int time_minutes_max = 28 * 24 * 60;
|
||||
if (time_minutes < 1 || time_minutes > time_minutes_max) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"zone '%s': 'min-transfer-rate-in' minutes"
|
||||
"value is out of range (1..%u)",
|
||||
zname, time_minutes_max);
|
||||
CHECK(ISC_R_FAILURE);
|
||||
}
|
||||
dns_zone_setminxfrratein(mayberaw, traffic_bytes,
|
||||
transferinsecs ? time_minutes
|
||||
: time_minutes * 60);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-transfer-time-in", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
|
15
bin/tests/system/xfer/ns1/axfr-min-transfer-rate.db
Normal file
15
bin/tests/system/xfer/ns1/axfr-min-transfer-rate.db
Normal file
@ -0,0 +1,15 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; 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 https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 3600
|
||||
@ IN SOA . . 0 0 0 0 0
|
||||
@ IN NS .
|
||||
$GENERATE 1-5000 host$ TXT data-$
|
@ -47,6 +47,10 @@ zone "edns-expire" {
|
||||
file "edns-expire.db";
|
||||
};
|
||||
|
||||
zone "axfr-min-transfer-rate" {
|
||||
type primary;
|
||||
file "axfr-min-transfer-rate.db";
|
||||
};
|
||||
|
||||
zone "axfr-max-transfer-time" {
|
||||
type primary;
|
||||
|
@ -36,6 +36,11 @@ zone "." {
|
||||
file "root.db";
|
||||
};
|
||||
|
||||
zone "axfr-min-transfer-rate" {
|
||||
type primary;
|
||||
file "axfr-min-transfer-rate.db";
|
||||
};
|
||||
|
||||
zone "axfr-max-transfer-time" {
|
||||
type primary;
|
||||
file "axfr-max-transfer-time.db";
|
||||
|
@ -32,6 +32,7 @@ options {
|
||||
ixfr-from-differences primary;
|
||||
check-integrity no;
|
||||
tcp-idle-timeout 600;
|
||||
min-transfer-rate-in 10240 300; # this is tested as seconds, when used with '-T transferinsecs' (i.e. convert the default '10240 5' back so that it doesn't interfere with other tests)
|
||||
};
|
||||
|
||||
zone "." {
|
||||
@ -57,6 +58,13 @@ zone "edns-expire" {
|
||||
file "edns-expire.bk";
|
||||
};
|
||||
|
||||
zone "axfr-min-transfer-rate" {
|
||||
type secondary;
|
||||
min-transfer-rate-in 100000 5; # this is tested as seconds, when used with '-T transferinsecs' (i.e. 100000 bytes in 5 seconds)
|
||||
primaries { 10.53.0.1; };
|
||||
file "axfr-min-transfer-rate.bk";
|
||||
};
|
||||
|
||||
zone "axfr-max-transfer-time" {
|
||||
type secondary;
|
||||
max-transfer-time-in 1; # this is tested as seconds, when used with '-T transferinsecs'
|
||||
|
@ -709,11 +709,22 @@ status=$((status + tmp))
|
||||
|
||||
nextpart ns6/named.run >/dev/null
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "test min-transfer-rate-in with 5 seconds timeout ($n)"
|
||||
$RNDCCMD 10.53.0.6 retransfer axfr-min-transfer-rate 2>&1 | sed 's/^/ns6 /' | cat_i
|
||||
tmp=0
|
||||
retry_quiet 10 wait_for_message "minimum transfer rate reached: timed out" || tmp=1
|
||||
if test $tmp != 0; then echo_i "failed"; fi
|
||||
status=$((status + tmp))
|
||||
|
||||
nextpart ns6/named.run >/dev/null
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "test max-transfer-time-in with 1 second timeout ($n)"
|
||||
$RNDCCMD 10.53.0.6 retransfer axfr-max-transfer-time 2>&1 | sed 's/^/ns6 /' | cat_i
|
||||
tmp=0
|
||||
retry_quiet 10 wait_for_message "maximum transfer time exceeded: timed out" || tmp=1
|
||||
if test $tmp != 0; then echo_i "failed"; fi
|
||||
status=$((status + tmp))
|
||||
|
||||
# Restart ns1 with -T transferstuck
|
||||
@ -730,6 +741,7 @@ start=$(date +%s)
|
||||
$RNDCCMD 10.53.0.6 retransfer axfr-max-idle-time 2>&1 | sed 's/^/ns6 /' | cat_i
|
||||
tmp=0
|
||||
retry_quiet 60 wait_for_message "maximum idle time exceeded: timed out" || tmp=1
|
||||
if test $tmp != 0; then echo_i "failed"; fi
|
||||
if [ $tmp -eq 0 ]; then
|
||||
now=$(date +%s)
|
||||
diff=$((now - start))
|
||||
|
@ -41,6 +41,7 @@ pytestmark = pytest.mark.extra_artifacts(
|
||||
"ns4/root.db",
|
||||
"ns6/axfr-max-idle-time.bk",
|
||||
"ns6/axfr-max-transfer-time.bk",
|
||||
"ns6/axfr-min-transfer-rate.bk",
|
||||
"ns6/axfr-rndc-retransfer-force.bk",
|
||||
"ns6/edns-expire.bk",
|
||||
"ns6/ixfr-too-big.bk",
|
||||
|
@ -3324,6 +3324,16 @@ options apply to zone transfers.
|
||||
global :any:`also-notify` list are not sent NOTIFY messages for that
|
||||
zone. The default is the empty list (no global notification list).
|
||||
|
||||
.. namedconf:statement:: min-transfer-rate-in
|
||||
:tags: transfer
|
||||
:short: Specifies the minimum traffic rate below which inbound zone transfers are terminated.
|
||||
|
||||
Inbound zone transfers running slower than the given amount of bytes in the
|
||||
given amount of minutes are terminated. This option takes two non-zero integer values.
|
||||
A check is performed periodically every time the configured time interval
|
||||
passes. The default value is ``10240 5``, i.e. 10240 bytes in 5 minutes.
|
||||
The maximum time value is 28 days (40320 minutes).
|
||||
|
||||
.. namedconf:statement:: max-transfer-time-in
|
||||
:tags: transfer
|
||||
:short: Specifies the number of minutes after which inbound zone transfers are terminated.
|
||||
@ -7068,6 +7078,9 @@ Zone Options
|
||||
:any:`max-records`
|
||||
See the description of :any:`max-records` in :ref:`server_resource_limits`.
|
||||
|
||||
:any:`min-transfer-rate-in`
|
||||
See the description of :any:`min-transfer-rate-in` in :ref:`zone_transfers`.
|
||||
|
||||
:any:`max-transfer-time-in`
|
||||
See the description of :any:`max-transfer-time-in` in :ref:`zone_transfers`.
|
||||
|
||||
@ -7822,6 +7835,12 @@ Incoming Zone Transfers
|
||||
64-bit unsigned Integer. This is the number of usable bytes
|
||||
of DNS data. It does not include transport overhead.
|
||||
|
||||
``Transfer Rate (B/s)`` (``rate``)
|
||||
64 bit unsigned Integer. This is the average zone transfer rate in
|
||||
bytes-per-second during the latest full interval that is configured by the
|
||||
:any:`min-transfer-rate-in` configuration option. If no such interval
|
||||
has passed yet, then the overall average rate is reported instead.
|
||||
|
||||
.. note::
|
||||
Depending on the current state of the transfer, some of the
|
||||
values may be empty or set to ``-`` (meaning "not available").
|
||||
|
@ -26,6 +26,7 @@ zone <string> [ <class> ] {
|
||||
max-types-per-name <integer>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
min-transfer-rate-in <integer> <integer>;
|
||||
multi-master <boolean>;
|
||||
notify ( explicit | master-only | primary-only | <boolean> );
|
||||
notify-delay <integer>;
|
||||
|
@ -202,6 +202,7 @@ options {
|
||||
min-ncache-ttl <duration>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
min-transfer-rate-in <integer> <integer>;
|
||||
minimal-any <boolean>;
|
||||
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
|
||||
multi-master <boolean>;
|
||||
@ -484,6 +485,7 @@ view <string> [ <class> ] {
|
||||
min-ncache-ttl <duration>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
min-transfer-rate-in <integer> <integer>;
|
||||
minimal-any <boolean>;
|
||||
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
|
||||
multi-master <boolean>;
|
||||
|
@ -38,6 +38,7 @@ zone <string> [ <class> ] {
|
||||
max-types-per-name <integer>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
min-transfer-rate-in <integer> <integer>;
|
||||
multi-master <boolean>;
|
||||
notify ( explicit | master-only | primary-only | <boolean> );
|
||||
notify-delay <integer>;
|
||||
|
@ -18,6 +18,7 @@ zone <string> [ <class> ] {
|
||||
max-types-per-name <integer>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
min-transfer-rate-in <integer> <integer>;
|
||||
multi-master <boolean>;
|
||||
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||
transfer-source ( <ipv4_address> | * );
|
||||
|
@ -140,10 +140,13 @@ dns_xfrin_getendserial(dns_xfrin_t *xfr);
|
||||
|
||||
void
|
||||
dns_xfrin_getstats(dns_xfrin_t *xfr, unsigned int *nmsgp, unsigned int *nrecsp,
|
||||
uint64_t *nbytesp);
|
||||
uint64_t *nbytesp, uint64_t *ratep);
|
||||
/*%<
|
||||
* Get various statistics values of the xfrin object: number of the received
|
||||
* messages, number of the received records, number of the received bytes.
|
||||
* messages, number of the received records, number of the received bytes,
|
||||
* and the average transfer rate (in bytes-per-second) during the last full
|
||||
* 'min-transfer-rate-in <bytes> <minutes>' minutes interval. If no such
|
||||
* interval has passed yet, then the overall average rate is reported instead.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'xfr' is a valid dns_xfrin_t.
|
||||
|
@ -1233,6 +1233,36 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
||||
*\li DNS_R_SUCCESS
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setminxfrratein(dns_zone_t *zone, uint32_t bytes, uint32_t seconds);
|
||||
/*%<
|
||||
* Set the minumum traffic rate (in bytes per seconds) that a zone transfer in
|
||||
* (AXFR/IXFR) of this zone will use before being aborted.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'zone' to be valid initialised zone.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_zone_getminxfrratebytesin(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Returns the 'bytes' portion of the minimum traffic rate for the transfer in
|
||||
* for this zone.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'zone' to be valid initialised zone.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_zone_getminxfrratesecondsin(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Returns the 'seconds' portion of the minimum traffic rate for the transfer in
|
||||
* for this zone.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'zone' to be valid initialised zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin);
|
||||
/*%<
|
||||
|
@ -154,11 +154,13 @@ struct dns_xfrin {
|
||||
atomic_uint nrecs; /*%< Number of records recvd */
|
||||
atomic_uint_fast64_t nbytes; /*%< Number of bytes received */
|
||||
_Atomic(isc_time_t) start; /*%< Start time of the transfer */
|
||||
atomic_uint_fast64_t rate_bytes_per_second;
|
||||
_Atomic(dns_transport_type_t) soa_transport_type;
|
||||
atomic_uint_fast32_t end_serial;
|
||||
|
||||
unsigned int maxrecords; /*%< The maximum number of
|
||||
* records set for the zone */
|
||||
uint64_t nbytes_saved; /*%< For enforcing the minimum transfer rate */
|
||||
|
||||
dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
|
||||
isc_buffer_t *lasttsig; /*%< The last TSIG */
|
||||
@ -192,6 +194,7 @@ struct dns_xfrin {
|
||||
|
||||
isc_loop_t *loop;
|
||||
|
||||
isc_timer_t *min_rate_timer;
|
||||
isc_timer_t *max_time_timer;
|
||||
isc_timer_t *max_idle_timer;
|
||||
|
||||
@ -269,6 +272,8 @@ xfrin_timedout(void *);
|
||||
static void
|
||||
xfrin_idledout(void *);
|
||||
static void
|
||||
xfrin_minratecheck(void *);
|
||||
static void
|
||||
xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg);
|
||||
static isc_result_t
|
||||
render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
|
||||
@ -963,6 +968,32 @@ xfrin_idledout(void *xfr) {
|
||||
xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum idle time exceeded");
|
||||
}
|
||||
|
||||
static void
|
||||
xfrin_minratecheck(void *arg) {
|
||||
dns_xfrin_t *xfr = arg;
|
||||
|
||||
REQUIRE(VALID_XFRIN(xfr));
|
||||
|
||||
const uint64_t nbytes = atomic_load_relaxed(&xfr->nbytes);
|
||||
const uint64_t min = dns_zone_getminxfrratebytesin(xfr->zone);
|
||||
uint64_t rate = nbytes - xfr->nbytes_saved;
|
||||
|
||||
if (rate < min) {
|
||||
isc_timer_stop(xfr->min_rate_timer);
|
||||
xfrin_fail(xfr, ISC_R_TIMEDOUT,
|
||||
"minimum transfer rate reached");
|
||||
} else {
|
||||
xfr->nbytes_saved = nbytes;
|
||||
|
||||
/*
|
||||
* Calculate and store for the statistics channel the transfer
|
||||
* rate in bytes-per-second for the latest interval.
|
||||
*/
|
||||
rate /= dns_zone_getminxfrratesecondsin(xfr->zone);
|
||||
atomic_store_relaxed(&xfr->rate_bytes_per_second, rate);
|
||||
}
|
||||
}
|
||||
|
||||
isc_time_t
|
||||
dns_xfrin_getstarttime(dns_xfrin_t *xfr) {
|
||||
REQUIRE(VALID_XFRIN(xfr));
|
||||
@ -1024,13 +1055,29 @@ dns_xfrin_getendserial(dns_xfrin_t *xfr) {
|
||||
|
||||
void
|
||||
dns_xfrin_getstats(dns_xfrin_t *xfr, unsigned int *nmsgp, unsigned int *nrecsp,
|
||||
uint64_t *nbytesp) {
|
||||
uint64_t *nbytesp, uint64_t *ratep) {
|
||||
REQUIRE(VALID_XFRIN(xfr));
|
||||
REQUIRE(nmsgp != NULL && nrecsp != NULL && nbytesp != NULL);
|
||||
|
||||
uint64_t rate = atomic_load_relaxed(&xfr->rate_bytes_per_second);
|
||||
if (rate == 0) {
|
||||
/*
|
||||
* Likely the first 'min-transfer-rate-in <bytes> <minutes>'
|
||||
* minutes interval hasn't passed yet. Calculate the overall
|
||||
* average transfer rate instead.
|
||||
*/
|
||||
isc_time_t now = isc_time_now();
|
||||
isc_time_t start = atomic_load_relaxed(&xfr->start);
|
||||
uint64_t sec = isc_time_microdiff(&now, &start) / US_PER_SEC;
|
||||
if (sec > 0) {
|
||||
rate = atomic_load_relaxed(&xfr->nbytes) / sec;
|
||||
}
|
||||
}
|
||||
|
||||
SET_IF_NOT_NULL(nmsgp, atomic_load_relaxed(&xfr->nmsg));
|
||||
SET_IF_NOT_NULL(nrecsp, atomic_load_relaxed(&xfr->nrecs));
|
||||
SET_IF_NOT_NULL(nbytesp, atomic_load_relaxed(&xfr->nbytes));
|
||||
SET_IF_NOT_NULL(ratep, rate);
|
||||
}
|
||||
|
||||
const isc_sockaddr_t *
|
||||
@ -1326,6 +1373,15 @@ xfrin_start(dns_xfrin_t *xfr) {
|
||||
isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
|
||||
isc_timer_start(xfr->max_idle_timer, isc_timertype_once, &interval);
|
||||
|
||||
/* Set the minimum transfer rate checking timer */
|
||||
if (xfr->min_rate_timer == NULL) {
|
||||
isc_timer_create(dns_zone_getloop(xfr->zone),
|
||||
xfrin_minratecheck, xfr, &xfr->min_rate_timer);
|
||||
}
|
||||
isc_interval_set(&interval, dns_zone_getminxfrratesecondsin(xfr->zone),
|
||||
0);
|
||||
isc_timer_start(xfr->min_rate_timer, isc_timertype_ticker, &interval);
|
||||
|
||||
/*
|
||||
* The connect has to be the last thing that is called before returning,
|
||||
* as it can end synchronously and destroy the xfr object.
|
||||
@ -1606,6 +1662,8 @@ xfrin_send_request(dns_xfrin_t *xfr) {
|
||||
atomic_store_relaxed(&xfr->nbytes, 0);
|
||||
atomic_store_relaxed(&xfr->start, isc_time_now());
|
||||
|
||||
xfr->nbytes_saved = 0;
|
||||
|
||||
msg->id = xfr->id;
|
||||
if (xfr->tsigctx != NULL) {
|
||||
dst_context_destroy(&xfr->tsigctx);
|
||||
@ -1724,6 +1782,10 @@ xfrin_end(dns_xfrin_t *xfr, isc_result_t result) {
|
||||
isc_timer_stop(xfr->max_idle_timer);
|
||||
isc_timer_destroy(&xfr->max_idle_timer);
|
||||
}
|
||||
if (xfr->min_rate_timer != NULL) {
|
||||
isc_timer_stop(xfr->min_rate_timer);
|
||||
isc_timer_destroy(&xfr->min_rate_timer);
|
||||
}
|
||||
|
||||
if (xfr->shutdown_result == ISC_R_UNSET) {
|
||||
xfr->shutdown_result = result;
|
||||
@ -2017,6 +2079,7 @@ xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg) {
|
||||
case XFRST_AXFR_END:
|
||||
case XFRST_IXFR_END:
|
||||
/* We are at the end, cancel the timers and IO */
|
||||
isc_timer_stop(xfr->min_rate_timer);
|
||||
isc_timer_stop(xfr->max_idle_timer);
|
||||
isc_timer_stop(xfr->max_time_timer);
|
||||
xfrin_cancelio(xfr);
|
||||
@ -2182,6 +2245,7 @@ xfrin_destroy(dns_xfrin_t *xfr) {
|
||||
|
||||
INSIST(xfr->max_time_timer == NULL);
|
||||
INSIST(xfr->max_idle_timer == NULL);
|
||||
INSIST(xfr->min_rate_timer == NULL);
|
||||
|
||||
isc_loop_detach(&xfr->loop);
|
||||
|
||||
|
@ -361,6 +361,8 @@ struct dns_zone {
|
||||
dns_request_t *request;
|
||||
dns_loadctx_t *loadctx;
|
||||
dns_dumpctx_t *dumpctx;
|
||||
uint32_t minxfrratebytesin;
|
||||
uint32_t minxfrratesecondsin;
|
||||
uint32_t maxxfrin;
|
||||
uint32_t maxxfrout;
|
||||
uint32_t idlein;
|
||||
@ -16154,6 +16156,28 @@ message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) {
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setminxfrratein(dns_zone_t *zone, uint32_t bytes, uint32_t seconds) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
zone->minxfrratebytesin = bytes;
|
||||
zone->minxfrratesecondsin = seconds;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_zone_getminxfrratebytesin(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
return zone->minxfrratebytesin;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_zone_getminxfrratesecondsin(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
return zone->minxfrratesecondsin;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
@ -2211,6 +2211,20 @@ static cfg_clausedef_t dnssecpolicy_clauses[] = {
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* For min-transfer-rate-in.
|
||||
*/
|
||||
static cfg_tuplefielddef_t min_transfer_rate_fields[] = {
|
||||
{ "traffic_bytes", &cfg_type_uint32, 0 },
|
||||
{ "time_minutes", &cfg_type_uint32, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static cfg_type_t cfg_type_min_transfer_rate_in = {
|
||||
"min-transfer-rate-in", cfg_parse_tuple, cfg_print_tuple,
|
||||
cfg_doc_tuple, &cfg_rep_tuple, min_transfer_rate_fields
|
||||
};
|
||||
|
||||
/*%
|
||||
* Clauses that can be found in a 'zone' statement,
|
||||
* with defaults in the 'view' or 'options' statement.
|
||||
@ -2304,6 +2318,8 @@ static cfg_clausedef_t zone_clauses[] = {
|
||||
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
|
||||
{ "max-retry-time", &cfg_type_uint32,
|
||||
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
|
||||
{ "min-transfer-rate-in", &cfg_type_min_transfer_rate_in,
|
||||
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
|
||||
{ "max-transfer-idle-in", &cfg_type_uint32,
|
||||
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
|
||||
{ "max-transfer-idle-out", &cfg_type_uint32,
|
||||
|
Loading…
x
Reference in New Issue
Block a user