From fa2cb06c753cdc947e914ddcaf135383d93f3897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 5 Apr 2023 22:35:00 +0200 Subject: [PATCH 1/4] Implement maximum global and idle time for incoming XFR After the dns_xfrin was changed to use network manager, the maximum global (max-transfer-time-in) and idle (max-transfer-idle-in) times for incoming transfers were turned inoperational because of missing implementation. Restore this functionality by implementing the timers for the incoming transfers. (cherry picked from commit d2377f8e044a4b1e534ec55b237bac4781936533) --- doc/arm/reference.rst | 6 +++ lib/dns/include/dns/xfrin.h | 1 + lib/dns/include/dns/zone.h | 6 +++ lib/dns/xfrin.c | 81 ++++++++++++++++++++++++++++++++++++- lib/dns/zone.c | 7 ++++ 5 files changed, 99 insertions(+), 2 deletions(-) diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 36ea3a5892..b76294c59d 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -3450,6 +3450,12 @@ options apply to zone transfers. terminated. The default is 60 minutes (1 hour). The maximum value is 28 days (40320 minutes). + .. note:: The inbound zone transfers are also affected by + ``tcp-idle-timeout``, the ``max-transfer-idle-in`` will close the + inbound zone transfer if there was no complete AXFR or no complete + IXFR chunk. The ``tcp-idle-timeout`` will close the connection if + there's no progress on the TCP level. + .. namedconf:statement:: max-transfer-time-out :tags: transfer :short: Specifies the number of minutes after which outbound zone transfers are terminated. diff --git a/lib/dns/include/dns/xfrin.h b/lib/dns/include/dns/xfrin.h index 70b601bb57..dd47c8cad2 100644 --- a/lib/dns/include/dns/xfrin.h +++ b/lib/dns/include/dns/xfrin.h @@ -27,6 +27,7 @@ ***/ #include +#include #include #include diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 447e8aa1b2..10ed86c4e3 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1769,6 +1769,12 @@ dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr); * Get the tasmkgr object attached to 'zmgr'. */ +isc_timermgr_t * +dns_zonemgr_gettimermgr(dns_zonemgr_t *zmgr); +/*% + * Get the timermgr object attached to 'zmgr'. + */ + void dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value); /*%< diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 16081863d8..b481368129 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -22,6 +22,8 @@ #include #include #include /* Required for HP/UX (and others?) */ +#include +#include #include #include @@ -185,6 +187,9 @@ struct dns_xfrin_ctx { unsigned char *firstsoa_data; isc_tlsctx_cache_t *tlsctx_cache; + + isc_timer_t *max_time_timer; + isc_timer_t *max_idle_timer; }; #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I') @@ -247,6 +252,10 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result, static void xfrin_destroy(dns_xfrin_ctx_t *xfr); +static void +xfrin_timedout(struct isc_task *, struct isc_event *); +static void +xfrin_idledout(struct isc_task *, struct isc_event *); static void xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg); static isc_result_t @@ -758,6 +767,28 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, static void xfrin_cancelio(dns_xfrin_ctx_t *xfr); +static void +xfrin_timedout(struct isc_task *task, struct isc_event *event) { + UNUSED(task); + + dns_xfrin_ctx_t *xfr = event->ev_arg; + REQUIRE(VALID_XFRIN(xfr)); + + xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum transfer time exceeded"); + isc_event_free(&event); +} + +static void +xfrin_idledout(struct isc_task *task, struct isc_event *event) { + UNUSED(task); + + dns_xfrin_ctx_t *xfr = event->ev_arg; + REQUIRE(VALID_XFRIN(xfr)); + + xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum idle time exceeded"); + isc_event_free(&event); +} + void dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) { REQUIRE(VALID_XFRIN(xfr)); @@ -833,6 +864,11 @@ xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) { if (atomic_compare_exchange_strong(&xfr->shuttingdown, &(bool){ false }, true)) { + (void)isc_timer_reset(xfr->max_time_timer, + isc_timertype_inactive, NULL, NULL, true); + (void)isc_timer_reset(xfr->max_idle_timer, + isc_timertype_inactive, NULL, NULL, true); + if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) { xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg, @@ -866,6 +902,9 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr, dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache, dns_xfrin_ctx_t **xfrp) { dns_xfrin_ctx_t *xfr = NULL; + dns_zonemgr_t *zmgr = dns_zone_getmgr(zone); + isc_timermgr_t *timermgr = dns_zonemgr_gettimermgr(zmgr); + isc_task_t *ztask = NULL; xfr = isc_mem_get(mctx, sizeof(*xfr)); *xfr = (dns_xfrin_ctx_t){ .netmgr = netmgr, @@ -876,7 +915,8 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr, .maxrecords = dns_zone_getmaxrecords(zone), .primaryaddr = *primaryaddr, .sourceaddr = *sourceaddr, - .firstsoa = DNS_RDATA_INIT }; + .firstsoa = DNS_RDATA_INIT, + .magic = XFRIN_MAGIC }; isc_mem_attach(mctx, &xfr->mctx); dns_zone_iattach(zone, &xfr->zone); @@ -923,7 +963,12 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr, isc_tlsctx_cache_attach(tlsctx_cache, &xfr->tlsctx_cache); - xfr->magic = XFRIN_MAGIC; + dns_zone_gettask(zone, &ztask); + isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, ztask, + xfrin_timedout, xfr, &xfr->max_time_timer); + isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, ztask, + xfrin_idledout, xfr, &xfr->max_idle_timer); + isc_task_detach(&ztask); /* dns_zone_task() attaches to the task */ *xfrp = xfr; } @@ -1146,6 +1191,8 @@ xfrin_start(dns_xfrin_ctx_t *xfr) { dns_transport_type_t transport_type = DNS_TRANSPORT_TCP; isc_tlsctx_t *tlsctx = NULL; isc_tlsctx_client_session_cache_t *sess_cache = NULL; + isc_interval_t interval; + isc_time_t next; (void)isc_refcount_increment0(&xfr->connects); dns_xfrin_attach(xfr, &connect_xfr); @@ -1154,6 +1201,20 @@ xfrin_start(dns_xfrin_ctx_t *xfr) { transport_type = dns_transport_get_type(xfr->transport); } + /* Set the maximum timer */ + isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0); + isc_time_nowplusinterval(&next, &interval); + result = isc_timer_reset(xfr->max_time_timer, isc_timertype_once, &next, + NULL, true); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* Set the idle timer */ + isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0); + isc_time_nowplusinterval(&next, &interval); + result = isc_timer_reset(xfr->max_idle_timer, isc_timertype_once, &next, + NULL, true); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + /* * XXX: timeouts are hard-coded to 30 seconds; this needs to be * configurable. @@ -1500,6 +1561,10 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result, result = ISC_R_SHUTTINGDOWN; } + /* Stop the idle timer */ + (void)isc_timer_reset(xfr->max_idle_timer, isc_timertype_inactive, NULL, + NULL, true); + CHECK(result); xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", region->length); @@ -1754,6 +1819,8 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result, } atomic_store(&xfr->shuttingdown, true); + (void)isc_timer_reset(xfr->max_time_timer, + isc_timertype_inactive, NULL, NULL, true); xfr->shutdown_result = ISC_R_SUCCESS; break; default: @@ -1765,6 +1832,13 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result, dns_message_detach(&msg); isc_refcount_increment0(&xfr->recvs); isc_nm_read(xfr->handle, xfrin_recv_done, xfr); + isc_time_t next; + isc_interval_t interval; + isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0); + isc_time_nowplusinterval(&next, &interval); + result = isc_timer_reset(xfr->max_idle_timer, + isc_timertype_once, &next, NULL, true); + RUNTIME_CHECK(result == ISC_R_SUCCESS); return; } @@ -1891,6 +1965,9 @@ xfrin_destroy(dns_xfrin_ctx_t *xfr) { isc_tlsctx_cache_detach(&xfr->tlsctx_cache); } + isc_timer_destroy(&xfr->max_idle_timer); + isc_timer_destroy(&xfr->max_time_timer); + isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); } diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 5f0c099dff..16f7708464 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -19215,6 +19215,13 @@ dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr) { return (zmgr->taskmgr); } +isc_timermgr_t * +dns_zonemgr_gettimermgr(dns_zonemgr_t *zmgr) { + REQUIRE(DNS_ZONEMGR_VALID(zmgr)); + + return (zmgr->timermgr); +} + /* * Try to start a new incoming zone transfer to fill a quota * slot that was just vacated. From 305bf677abc67c6ed4e19882eb1cddc6a36defc5 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 17 Apr 2023 12:22:38 +0000 Subject: [PATCH 2/4] Implement new -T options for xfer system tests '-T transferinsecs' makes named interpret the max-transfer-time-out, max-transfer-idle-out, max-transfer-time-in and max-transfer-idle-in configuration options as seconds instead of minutes. '-T transferslowly' makes named to sleep for one second for every xfrout message. '-T transferstuck' makes named to sleep for one minute for every xfrout message. (cherry picked from commit dfaecfd752b7e3a8fdaa4edb53d8c96c18cee8b9) --- bin/named/main.c | 18 ++++++++++++++++++ bin/named/zoneconf.c | 18 ++++++++++++++---- lib/ns/include/ns/server.h | 31 +++++++++++++++++-------------- lib/ns/xfrout.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 18 deletions(-) diff --git a/bin/named/main.c b/bin/named/main.c index 509da55446..bb7798c667 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -136,6 +136,9 @@ static bool nonearest = false; static bool nosoa = false; static bool notcp = false; static bool sigvalinsecs = false; +static bool transferinsecs = false; +static bool transferslowly = false; +static bool transferstuck = false; /* * -4 and -6 @@ -787,6 +790,12 @@ parse_T_opt(char *option) { } } else if (!strcmp(option, "sigvalinsecs")) { sigvalinsecs = true; + } else if (!strcmp(option, "transferinsecs")) { + transferinsecs = true; + } else if (!strcmp(option, "transferslowly")) { + transferslowly = true; + } else if (!strcmp(option, "transferstuck")) { + transferstuck = true; } else if (!strncmp(option, "tat=", 4)) { named_g_tat_interval = atoi(option + 4); } else { @@ -1371,6 +1380,15 @@ setup(void) { if (sigvalinsecs) { ns_server_setoption(sctx, NS_SERVER_SIGVALINSECS, true); } + if (transferinsecs) { + ns_server_setoption(sctx, NS_SERVER_TRANSFERINSECS, true); + } + if (transferslowly) { + ns_server_setoption(sctx, NS_SERVER_TRANSFERSLOWLY, true); + } + if (transferstuck) { + ns_server_setoption(sctx, NS_SERVER_TRANSFERSTUCK, true); + } } static void diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 627a931a8c..8b731adbb2 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -912,6 +912,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, int seconds; dns_ttl_t maxttl = 0; /* unlimited */ dns_zone_t *mayberaw = (raw != NULL) ? raw : zone; + bool transferinsecs = ns_server_getoption(named_g_server->sctx, + NS_SERVER_TRANSFERINSECS); i = 0; if (zconfig != NULL) { @@ -1322,12 +1324,16 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, obj = NULL; result = named_config_get(maps, "max-transfer-time-out", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); + dns_zone_setmaxxfrout( + zone, transferinsecs ? cfg_obj_asuint32(obj) + : cfg_obj_asuint32(obj) * 60); obj = NULL; result = named_config_get(maps, "max-transfer-idle-out", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); + dns_zone_setidleout(zone, transferinsecs + ? cfg_obj_asuint32(obj) + : cfg_obj_asuint32(obj) * 60); obj = NULL; result = named_config_get(maps, "max-journal-size", &obj); @@ -1896,12 +1902,16 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, obj = NULL; result = named_config_get(maps, "max-transfer-time-in", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60); + dns_zone_setmaxxfrin( + mayberaw, transferinsecs ? cfg_obj_asuint32(obj) + : cfg_obj_asuint32(obj) * 60); obj = NULL; result = named_config_get(maps, "max-transfer-idle-in", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60); + dns_zone_setidlein(mayberaw, + transferinsecs ? cfg_obj_asuint32(obj) + : cfg_obj_asuint32(obj) * 60); obj = NULL; result = named_config_get(maps, "max-refresh-time", &obj); diff --git a/lib/ns/include/ns/server.h b/lib/ns/include/ns/server.h index 4ea7a8bb47..206c495dc0 100644 --- a/lib/ns/include/ns/server.h +++ b/lib/ns/include/ns/server.h @@ -32,20 +32,23 @@ #include #include -#define NS_SERVER_LOGQUERIES 0x00000001U /*%< log queries */ -#define NS_SERVER_NOAA 0x00000002U /*%< -T noaa */ -#define NS_SERVER_NOSOA 0x00000004U /*%< -T nosoa */ -#define NS_SERVER_NONEAREST 0x00000008U /*%< -T nonearest */ -#define NS_SERVER_NOEDNS 0x00000020U /*%< -T noedns */ -#define NS_SERVER_DROPEDNS 0x00000040U /*%< -T dropedns */ -#define NS_SERVER_NOTCP 0x00000080U /*%< -T notcp */ -#define NS_SERVER_DISABLE4 0x00000100U /*%< -6 */ -#define NS_SERVER_DISABLE6 0x00000200U /*%< -4 */ -#define NS_SERVER_FIXEDLOCAL 0x00000400U /*%< -T fixedlocal */ -#define NS_SERVER_SIGVALINSECS 0x00000800U /*%< -T sigvalinsecs */ -#define NS_SERVER_EDNSFORMERR 0x00001000U /*%< -T ednsformerr (STD13) */ -#define NS_SERVER_EDNSNOTIMP 0x00002000U /*%< -T ednsnotimp */ -#define NS_SERVER_EDNSREFUSED 0x00004000U /*%< -T ednsrefused */ +#define NS_SERVER_LOGQUERIES 0x00000001U /*%< log queries */ +#define NS_SERVER_NOAA 0x00000002U /*%< -T noaa */ +#define NS_SERVER_NOSOA 0x00000004U /*%< -T nosoa */ +#define NS_SERVER_NONEAREST 0x00000008U /*%< -T nonearest */ +#define NS_SERVER_NOEDNS 0x00000020U /*%< -T noedns */ +#define NS_SERVER_DROPEDNS 0x00000040U /*%< -T dropedns */ +#define NS_SERVER_NOTCP 0x00000080U /*%< -T notcp */ +#define NS_SERVER_DISABLE4 0x00000100U /*%< -6 */ +#define NS_SERVER_DISABLE6 0x00000200U /*%< -4 */ +#define NS_SERVER_FIXEDLOCAL 0x00000400U /*%< -T fixedlocal */ +#define NS_SERVER_SIGVALINSECS 0x00000800U /*%< -T sigvalinsecs */ +#define NS_SERVER_EDNSFORMERR 0x00001000U /*%< -T ednsformerr (STD13) */ +#define NS_SERVER_EDNSNOTIMP 0x00002000U /*%< -T ednsnotimp */ +#define NS_SERVER_EDNSREFUSED 0x00004000U /*%< -T ednsrefused */ +#define NS_SERVER_TRANSFERINSECS 0x00008000U /*%< -T transferinsecs */ +#define NS_SERVER_TRANSFERSLOWLY 0x00010000U /*%< -T transferslowly */ +#define NS_SERVER_TRANSFERSTUCK 0x00020000U /*%< -T transferstuck */ /*% * Type for callback function to get hostname. diff --git a/lib/ns/xfrout.c b/lib/ns/xfrout.c index 827a7b68e0..9380924bf6 100644 --- a/lib/ns/xfrout.c +++ b/lib/ns/xfrout.c @@ -1561,6 +1561,22 @@ sendstream(xfrout_ctx_t *xfr) { xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending TCP message of %d bytes", used.length); + /* System test helper options to simulate network issues. */ + if (ns_server_getoption(xfr->client->manager->sctx, + NS_SERVER_TRANSFERSLOWLY)) + { + /* Sleep for a bit over a second. */ + select(0, NULL, NULL, NULL, + &(struct timeval){ 1, 1000 }); + } + if (ns_server_getoption(xfr->client->manager->sctx, + NS_SERVER_TRANSFERSTUCK)) + { + /* Sleep for a bit over a minute. */ + select(0, NULL, NULL, NULL, + &(struct timeval){ 60, 1000 }); + } + isc_nmhandle_attach(xfr->client->handle, &xfr->client->sendhandle); if (xfr->idletime > 0) { @@ -1573,6 +1589,23 @@ sendstream(xfrout_ctx_t *xfr) { xfr->cbytes = used.length; } else { xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); + + /* System test helper options to simulate network issues. */ + if (ns_server_getoption(xfr->client->manager->sctx, + NS_SERVER_TRANSFERSLOWLY)) + { + /* Sleep for a bit over a second. */ + select(0, NULL, NULL, NULL, + &(struct timeval){ 1, 1000 }); + } + if (ns_server_getoption(xfr->client->manager->sctx, + NS_SERVER_TRANSFERSTUCK)) + { + /* Sleep for a bit over a minute. */ + select(0, NULL, NULL, NULL, + &(struct timeval){ 60, 1000 }); + } + ns_client_send(xfr->client); xfr->stream->methods->pause(xfr->stream); isc_nmhandle_detach(&xfr->client->reqhandle); From bc0461d4aeb78f804352e56779799dfc34242fa5 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 17 Apr 2023 12:22:49 +0000 Subject: [PATCH 3/4] Implement new checks for the xfer system test Check the max-transfer-time-in and max-transfer-idle-in options. (cherry picked from commit 5324f047b22a82f5cf5e25c9672b8fcd21e870ac) --- bin/tests/system/xfer/clean.sh | 1 + .../system/xfer/ns1/axfr-max-idle-time.db | 15 +++++++ .../system/xfer/ns1/axfr-max-transfer-time.db | 15 +++++++ .../ns1/{named.conf.in => named1.conf.in} | 10 +++++ bin/tests/system/xfer/ns1/named2.conf.in | 40 ++++++++++++++++++ bin/tests/system/xfer/ns1/named3.conf.in | 40 ++++++++++++++++++ bin/tests/system/xfer/ns6/named.args | 1 + bin/tests/system/xfer/ns6/named.conf.in | 15 +++++++ bin/tests/system/xfer/setup.sh | 2 +- bin/tests/system/xfer/tests.sh | 41 +++++++++++++++++++ 10 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 bin/tests/system/xfer/ns1/axfr-max-idle-time.db create mode 100644 bin/tests/system/xfer/ns1/axfr-max-transfer-time.db rename bin/tests/system/xfer/ns1/{named.conf.in => named1.conf.in} (88%) create mode 100644 bin/tests/system/xfer/ns1/named2.conf.in create mode 100644 bin/tests/system/xfer/ns1/named3.conf.in create mode 100644 bin/tests/system/xfer/ns6/named.args diff --git a/bin/tests/system/xfer/clean.sh b/bin/tests/system/xfer/clean.sh index bf5016e8f9..effdda8a92 100644 --- a/bin/tests/system/xfer/clean.sh +++ b/bin/tests/system/xfer/clean.sh @@ -38,3 +38,4 @@ rm -f ns6/*.db ns6/*.bk ns6/*.jnl rm -f ns7/*.db ns7/*.bk ns7/*.jnl rm -f ns8/large.db ns8/small.db rm -f stats.* +rm -f wait_for_message.* diff --git a/bin/tests/system/xfer/ns1/axfr-max-idle-time.db b/bin/tests/system/xfer/ns1/axfr-max-idle-time.db new file mode 100644 index 0000000000..252925f8dc --- /dev/null +++ b/bin/tests/system/xfer/ns1/axfr-max-idle-time.db @@ -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-$ diff --git a/bin/tests/system/xfer/ns1/axfr-max-transfer-time.db b/bin/tests/system/xfer/ns1/axfr-max-transfer-time.db new file mode 100644 index 0000000000..252925f8dc --- /dev/null +++ b/bin/tests/system/xfer/ns1/axfr-max-transfer-time.db @@ -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-$ diff --git a/bin/tests/system/xfer/ns1/named.conf.in b/bin/tests/system/xfer/ns1/named1.conf.in similarity index 88% rename from bin/tests/system/xfer/ns1/named.conf.in rename to bin/tests/system/xfer/ns1/named1.conf.in index 1cd72719f8..8673a4027a 100644 --- a/bin/tests/system/xfer/ns1/named.conf.in +++ b/bin/tests/system/xfer/ns1/named1.conf.in @@ -44,6 +44,16 @@ zone "edns-expire" { file "edns-expire.db"; }; +zone "axfr-max-transfer-time" { + type primary; + file "axfr-max-transfer-time.db"; +}; + +zone "axfr-max-idle-time" { + type primary; + file "axfr-max-idle-time.db"; +}; + zone "axfr-too-big" { type primary; file "axfr-too-big.db"; diff --git a/bin/tests/system/xfer/ns1/named2.conf.in b/bin/tests/system/xfer/ns1/named2.conf.in new file mode 100644 index 0000000000..434743d101 --- /dev/null +++ b/bin/tests/system/xfer/ns1/named2.conf.in @@ -0,0 +1,40 @@ +/* + * 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. + */ + +include "../../common/rndc.key"; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +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; +}; + +zone "." { + type primary; + file "root.db"; +}; + +zone "axfr-max-transfer-time" { + type primary; + file "axfr-max-transfer-time.db"; +}; diff --git a/bin/tests/system/xfer/ns1/named3.conf.in b/bin/tests/system/xfer/ns1/named3.conf.in new file mode 100644 index 0000000000..4f6344c697 --- /dev/null +++ b/bin/tests/system/xfer/ns1/named3.conf.in @@ -0,0 +1,40 @@ +/* + * 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. + */ + +include "../../common/rndc.key"; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +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; +}; + +zone "." { + type primary; + file "root.db"; +}; + +zone "axfr-max-idle-time" { + type primary; + file "axfr-max-idle-time.db"; +}; diff --git a/bin/tests/system/xfer/ns6/named.args b/bin/tests/system/xfer/ns6/named.args new file mode 100644 index 0000000000..2be062bbdd --- /dev/null +++ b/bin/tests/system/xfer/ns6/named.args @@ -0,0 +1 @@ +-D xfer-ns6 -X named.lock -m record -c named.conf -d 99 -g -U 4 -T maxcachesize=2097152 -T transferinsecs diff --git a/bin/tests/system/xfer/ns6/named.conf.in b/bin/tests/system/xfer/ns6/named.conf.in index 636400cfce..d5b8710896 100644 --- a/bin/tests/system/xfer/ns6/named.conf.in +++ b/bin/tests/system/xfer/ns6/named.conf.in @@ -29,6 +29,7 @@ options { notify yes; ixfr-from-differences primary; check-integrity no; + tcp-idle-timeout 600; }; zone "." { @@ -54,6 +55,20 @@ zone "edns-expire" { file "edns-expire.bk"; }; +zone "axfr-max-transfer-time" { + type secondary; + max-transfer-time-in 1; # this is tested as seconds, when used with '-T transferinsecs' + primaries { 10.53.0.1; }; + file "axfr-max-transfer-time.bk"; +}; + +zone "axfr-max-idle-time" { + type secondary; + max-transfer-idle-in 50; # this is tested as seconds, when used with '-T transferinsecs' + primaries { 10.53.0.1; }; + file "axfr-max-idle-time.bk"; +}; + zone "axfr-too-big" { type secondary; max-records 30; diff --git a/bin/tests/system/xfer/setup.sh b/bin/tests/system/xfer/setup.sh index 092d798799..ff64d8fbdd 100644 --- a/bin/tests/system/xfer/setup.sh +++ b/bin/tests/system/xfer/setup.sh @@ -23,7 +23,7 @@ $SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 7 >ns7/primary2.db cp -f ns4/root.db.in ns4/root.db $PERL -e 'for ($i=0;$i<10000;$i++){ printf("x%u 0 in a 10.53.0.1\n", $i);}' >> ns4/root.db -copy_setports ns1/named.conf.in ns1/named.conf +copy_setports ns1/named1.conf.in ns1/named.conf copy_setports ns2/named.conf.in ns2/named.conf copy_setports ns3/named.conf.in ns3/named.conf copy_setports ns6/named.conf.in ns6/named.conf diff --git a/bin/tests/system/xfer/tests.sh b/bin/tests/system/xfer/tests.sh index 11096d08b9..ecdfc49c1f 100755 --- a/bin/tests/system/xfer/tests.sh +++ b/bin/tests/system/xfer/tests.sh @@ -15,6 +15,7 @@ DIGOPTS="+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd -p ${PORT}" RNDCCMD="$RNDC -c ../common/rndc.conf -p ${CONTROLPORT} -s" +NS_PARAMS="-X named.lock -m record -c named.conf -d 99 -g -U 4 -T maxcachesize=2097152" status=0 n=0 @@ -580,5 +581,45 @@ grep "10.53.0.3#${EXTRAPORT1} (primary): query 'primary/SOA/IN' approved" ns6/na if test $tmp != 0 ; then echo_i "failed"; fi status=$((status+tmp)) +wait_for_message() ( + nextpartpeek ns6/named.run > wait_for_message.$n + grep -F "$1" wait_for_message.$n >/dev/null +) + +nextpart ns6/named.run > /dev/null + +n=$((n+1)) +echo_i "test max-transfer-time-in with 1 second timeout ($n)" +stop_server ns1 +copy_setports ns1/named2.conf.in ns1/named.conf +start_server --noclean --restart --port ${PORT} ns1 -- "-D xfer-ns1 $NS_PARAMS -T transferinsecs -T transferslowly" +sleep 1 +$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 +status=$((status+tmp)) + +nextpart ns6/named.run > /dev/null + +n=$((n+1)) +echo_i "test max-transfer-idle-in with 50 seconds timeout ($n)" +stop_server ns1 +copy_setports ns1/named3.conf.in ns1/named.conf +start_server --noclean --restart --port ${PORT} ns1 -- "-D xfer-ns1 $NS_PARAMS -T transferinsecs -T transferstuck" +sleep 1 +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 [ $tmp -eq 0 ]; then + now=`date +%s` + diff=$((now - start)) + # we expect a timeout in 50 seconds + test $diff -lt 50 && tmp=1 + test $diff -ge 59 && tmp=1 + if test $tmp != 0 ; then echo_i "unexpected diff value: ${diff}"; fi +fi +status=$((status+tmp)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 From c71efbf45fd5619b6a09d88cc05f1100a615da91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 5 Apr 2023 23:07:44 +0200 Subject: [PATCH 4/4] Add CHANGES note for [GL #4004] (cherry picked from commit 713e2021105fe2e5584769646427cb05537ea355) --- CHANGES | 3 +++ doc/notes/notes-current.rst | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGES b/CHANGES index 02066bfd83..cf820319cf 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +6156. [bug] Reimplement the maximum and idle timeouts for incoming + zone tranfers. [GL #4004] + 6155. [bug] Treat ISC_R_INVALIDPROTO as a networking error in the dispatch code to avoid retrying with the same server. [GL #4005]< diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 212fdb166b..bb0ff4bc37 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -39,6 +39,12 @@ Bug Fixes libuv, treat it as a network failure, mark the server as broken and don't try again. :gl:`#4005` +- The :any:`max-transfer-time-in` and :any:`max-transfer-idle-in` options + were not implemented when the BIND 9 networking stack was refactored + in 9.16. The missing functionality has been re-implemented and + incoming zone transfers now time out properly when not progressing. + :gl:`#4004` + Known Issues ~~~~~~~~~~~~