From: Artem Boldariev Date: Tue, 11 Jun 2024 14:20:22 +0000 (+0300) Subject: Do not un-throttle TCP connections on isc_nm_read() X-Git-Tag: v9.20.0~5^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=55b1a093ea97aa6d355dfc63dfc89f9c69a4fa4c;p=thirdparty%2Fbind9.git Do not un-throttle TCP connections on isc_nm_read() Due to omission it was possible to un-throttle a TCP connection previously throttled due to the peer not reading back data we are sending. In particular, that affected DoH code, but it could also affect other transports (the current or future ones) that pause/resume reading according to its internal state. --- diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index f5d8c114189..51bcf9430e9 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -585,6 +585,12 @@ struct isc_nmsocket { */ uint64_t write_timeout; + /* + * Reading was throttled over TCP as the peer does not read the + * data we are sending back. + */ + bool reading_throttled; + /*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */ isc_nmsocket_t *outer; diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 45e1c79c733..71eee4a2d9c 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -697,9 +697,11 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { goto failure; } - result = isc__nm_start_reading(sock); - if (result != ISC_R_SUCCESS) { - goto failure; + if (!sock->reading_throttled) { + result = isc__nm_start_reading(sock); + if (result != ISC_R_SUCCESS) { + goto failure; + } } sock->reading = true; @@ -791,6 +793,7 @@ isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { "throttling TCP connection, the other side is " "not reading the data (%zu)", write_queue_size); + sock->reading_throttled = true; isc__nm_stop_reading(sock); } } else if (uv_is_active(&sock->uv_handle.handle) && @@ -1042,6 +1045,7 @@ tcp_maybe_restart_reading(isc_nmsocket_t *sock) { "is reading the data again (%zu)", write_queue_size); isc__nm_start_reading(sock); + sock->reading_throttled = false; } } } @@ -1064,6 +1068,11 @@ tcp_send_cb(uv_write_t *req, int status) { isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(status), false); if (!sock->client && sock->reading) { + /* + * As we are resuming reading, it is not throttled + * anymore (technically). + */ + sock->reading_throttled = false; isc__nm_start_reading(sock); isc__nmsocket_reset(sock); }