From 36e9720d24a6c7d7174cdf38ff9ec51bd1ef802d Mon Sep 17 00:00:00 2001 From: Artem Boldariev Date: Tue, 9 Jul 2024 23:23:11 +0300 Subject: [PATCH] DoH: introduce manual read timer control This commit introduces manual read timer control as used by StreamDNS and its underlying transports. Before that, DoH code would rely on the timer control provided by TCP, which would reset the timer any time some data arrived. Now, the timer is restarted only when a full DNS message is processed in line with other DNS transports. That change is required because we should not stop the timer when reading from the network is paused due to throttling. We need a way to drop timed-out clients, particularly those who refuse to read the data we send. (cherry picked from commit 609a41517b1631c320876a41c43c68c9a0ee0f9f) --- lib/isc/netmgr/http.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c index c97595a783..aed8dacfca 100644 --- a/lib/isc/netmgr/http.c +++ b/lib/isc/netmgr/http.c @@ -560,6 +560,8 @@ finish_http_session(isc_nm_http_session_t *session) { if (!session->closed) { session->closed = true; session->reading = false; + isc_nm_read_stop(session->handle); + isc__nmsocket_timer_stop(session->handle->sock); isc_nmhandle_close(session->handle); } @@ -694,6 +696,9 @@ call_unlink_cstream_readcb(http_cstream_t *cstream, isc_buffer_usedregion(cstream->rbuf, &read_data); cstream->read_cb(session->client_httphandle, result, &read_data, cstream->read_cbarg); + if (result == ISC_R_SUCCESS) { + isc__nmsocket_timer_restart(session->handle->sock); + } put_http_cstream(session->mctx, cstream); } @@ -1570,6 +1575,7 @@ http_do_bio(isc_nm_http_session_t *session, isc_nmhandle_t *send_httphandle, if (nghttp2_session_want_read(session->ngsession) != 0) { if (!session->reading) { /* We have not yet started reading from this handle */ + isc__nmsocket_timer_start(session->handle->sock); isc_nm_read(session->handle, http_readcb, session); session->reading = true; } else if (session->buf != NULL) { @@ -1627,6 +1633,7 @@ http_do_bio(isc_nm_http_session_t *session, isc_nmhandle_t *send_httphandle, /* * Resume reading, it's idempotent, wait for more */ + isc__nmsocket_timer_start(session->handle->sock); isc_nm_read(session->handle, http_readcb, session); } } else { @@ -1803,6 +1810,7 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { } http_transpost_tcp_nodelay(handle); + isc__nmhandle_set_manual_timer(session->handle, true); http_call_connect_cb(http_sock, session, result); @@ -2454,6 +2462,8 @@ server_call_cb(isc_nmsocket_t *socket, const isc_result_t result, handle = isc__nmhandle_get(socket, NULL, NULL); if (result != ISC_R_SUCCESS) { data = NULL; + } else if (socket->h2->session->handle != NULL) { + isc__nmsocket_timer_restart(socket->h2->session->handle->sock); } if (result == ISC_R_SUCCESS) { socket->h2->request_received = true; @@ -2860,6 +2870,8 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { isc__nmsocket_attach(httpserver, &session->serversocket); server_send_connection_header(session); + isc__nmhandle_set_manual_timer(session->handle, true); + /* TODO H2 */ http_do_bio(session, NULL, NULL, NULL); return ISC_R_SUCCESS;