]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
DoH: introduce manual read timer control
authorArtem Boldariev <artem@isc.org>
Tue, 9 Jul 2024 20:23:11 +0000 (23:23 +0300)
committerAndoni Duarte Pintado <andoni@isc.org>
Wed, 15 Jan 2025 15:05:47 +0000 (16:05 +0100)
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

index c97595a783274c9b858b28c6a0288c82c2c7df50..aed8dacfcaa0eab5cee1da713ca1721c245a33fe 100644 (file)
@@ -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;