2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Fix TCPDNS and TLSDNS timers

After the TCPDNS refactoring the initial and idle timers were broken and
only the tcp-initial-timeout was always applied on the whole TCP
connection.

This broke any TCP connection that took longer than tcp-initial-timeout,
most often this would affect large zone AXFRs.

This commit changes the timeout logic in this way:

  * On TCP connection accept the tcp-initial-timeout is applied
    and the timer is started
  * When we are processing and/or sending any DNS message the timer is
    stopped
  * When we stop processing all DNS messages, the tcp-idle-timeout
    is applied and the timer is started again
This commit is contained in:
Ondřej Surý
2021-03-16 09:03:02 +01:00
parent 64cff61c02
commit caa5b6548a
10 changed files with 538 additions and 315 deletions

View File

@@ -596,7 +596,7 @@ udp_send_cb(uv_udp_send_t *req, int status) {
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_SENDFAIL]);
}
isc__nm_sendcb(sock, uvreq, result);
isc__nm_sendcb(sock, uvreq, result, false);
}
/*
@@ -900,6 +900,11 @@ failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
}
}
void
isc__nm_udp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
failed_read_cb(sock, result);
}
static void
failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
isc_result_t eresult) {
@@ -907,7 +912,7 @@ failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
REQUIRE(VALID_UVREQ(req));
if (req->cb.send != NULL) {
isc__nm_sendcb(sock, req, eresult);
isc__nm_sendcb(sock, req, eresult, true);
} else {
isc__nm_uvreq_put(&req, sock);
}
@@ -930,20 +935,6 @@ get_read_req(isc_nmsocket_t *sock, isc_sockaddr_t *sockaddr) {
return req;
}
static void
readtimeout_cb(uv_timer_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)handle);
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(sock->reading);
/*
* Timeout; stop reading and process whatever we have.
*/
failed_read_cb(sock, ISC_R_TIMEDOUT);
}
/*
* Asynchronous 'udpread' call handler: start or resume reading on a
* socket; pause reading and call the 'recv' callback after each
@@ -966,21 +957,7 @@ isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
}
start_reading(sock);
}
static void
start_sock_timer(isc_nmsocket_t *sock) {
if (sock->read_timeout > 0) {
int r = uv_timer_start(&sock->timer, readtimeout_cb,
sock->read_timeout, 0);
REQUIRE(r == 0);
}
}
static void
stop_sock_timer(isc_nmsocket_t *sock) {
int r = uv_timer_stop(&sock->timer);
REQUIRE(r == 0);
isc__nmsocket_timer_start(sock);
}
static void
@@ -993,8 +970,6 @@ start_reading(isc_nmsocket_t *sock) {
udp_read_cb);
REQUIRE(r == 0);
sock->reading = true;
start_sock_timer(sock);
}
static void
@@ -1007,7 +982,7 @@ stop_reading(isc_nmsocket_t *sock) {
REQUIRE(r == 0);
sock->reading = false;
stop_sock_timer(sock);
isc__nmsocket_timer_stop(sock);
}
void
@@ -1263,16 +1238,3 @@ isc__nm_async_udpcancel(isc__networker_t *worker, isc__netievent_t *ev0) {
failed_read_cb(sock, ISC_R_EOF);
}
void
isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
isc_nmsocket_t *sock = handle->sock;
sock->read_timeout = timeout;
if (uv_is_active((uv_handle_t *)&sock->timer)) {
start_sock_timer(sock);
}
}