]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Implement TCP manual read timer control functionality
authorArtem Boldariev <artem@isc.org>
Wed, 4 Sep 2024 15:53:35 +0000 (18:53 +0300)
committerAndoni Duarte <andoni@isc.org>
Wed, 15 Jan 2025 15:34:43 +0000 (15:34 +0000)
This commit adds a manual TCP read timer control mode which is
supposed to override automatic resetting of the timer when any data is
received. That can be accomplished by
`isc__nmhandle_set_manual_timer()`.

This functionality is supposed to be used by multilevel networking
transports which require finer grained control over the read
timer (TLS Stream, DoH).

The commit is essentially an implementation of the functionality from
newer versions of BIND.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tcp.c

index a99153a8f2311fc0148cc65f1a6c19d39acbfe03..48f2ef99f003db4fcb7d4552f9c936a72bbccdf3 100644 (file)
@@ -1229,6 +1229,7 @@ struct isc_nmsocket {
 
        isc_barrier_t barrier;
        bool barrier_initialised;
+       atomic_bool manual_read_timer;
 #ifdef NETMGR_TRACE
        void *backtrace[TRACE_SIZE];
        int backtrace_size;
@@ -1547,6 +1548,9 @@ isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
  * Set the read timeout for the TCP socket associated with 'handle'.
  */
 
+void
+isc__nmhandle_tcp_set_manual_timer(isc_nmhandle_t *handle, const bool manual);
+
 void
 isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0);
 void
@@ -2278,3 +2282,10 @@ isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult);
 
 void
 isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls);
+
+void
+isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual);
+/*
+ * Set manual read timer control mode - so that it will not get reset
+ * automatically on read nor get started when read is initiated.
+ */
index a7b82ce69b9004188e4d24fae1290a26c5772707..49982767bc78522e0e034f0a13d395a3fffd6ce4 100644 (file)
@@ -1627,6 +1627,7 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
        atomic_init(&sock->keepalive, false);
        atomic_init(&sock->connected, false);
        atomic_init(&sock->timedout, false);
+       atomic_init(&sock->manual_read_timer, false);
 
        atomic_init(&sock->active_child_connections, 0);
 
@@ -3932,6 +3933,24 @@ isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls) {
                      client_sabuf, local_sabuf);
 }
 
+void
+isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual) {
+       REQUIRE(VALID_NMHANDLE(handle));
+       REQUIRE(VALID_NMSOCK(handle->sock));
+
+       isc_nmsocket_t *sock = handle->sock;
+
+       switch (sock->type) {
+       case isc_nm_tcpsocket:
+               isc__nmhandle_tcp_set_manual_timer(handle, manual);
+               return;
+       default:
+               break;
+       };
+
+       UNREACHABLE();
+}
+
 #ifdef NETMGR_TRACE
 /*
  * Dump all active sockets in netmgr. We output to stderr
index db589aecc7278955e31e1ccf6a7c5d7def591fa0..fbe1394ab9421ef384ada05cb38fd82bae99f14b 100644 (file)
@@ -784,7 +784,9 @@ isc__nm_async_tcpstartread(isc__networker_t *worker, isc__netievent_t *ev0) {
                return;
        }
 
-       isc__nmsocket_timer_start(sock);
+       if (!atomic_load(&sock->manual_read_timer)) {
+               isc__nmsocket_timer_start(sock);
+       }
 }
 
 void
@@ -822,7 +824,9 @@ isc__nm_async_tcppauseread(isc__networker_t *worker, isc__netievent_t *ev0) {
        REQUIRE(sock->tid == isc_nm_tid());
        UNUSED(worker);
 
-       isc__nmsocket_timer_stop(sock);
+       if (!atomic_load(&sock->manual_read_timer)) {
+               isc__nmsocket_timer_stop(sock);
+       }
        isc__nm_stop_reading(sock);
 }
 
@@ -931,8 +935,10 @@ isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
                        }
                }
 
-               /* The timer will be updated */
-               isc__nmsocket_timer_restart(sock);
+               if (!atomic_load(&sock->manual_read_timer)) {
+                       /* The timer will be updated */
+                       isc__nmsocket_timer_restart(sock);
+               }
        }
 
 free:
@@ -1521,3 +1527,15 @@ isc__nm_tcp_listener_nactive(isc_nmsocket_t *listener) {
        INSIST(nactive >= 0);
        return nactive;
 }
+
+void
+isc__nmhandle_tcp_set_manual_timer(isc_nmhandle_t *handle, const bool manual) {
+       isc_nmsocket_t *sock;
+
+       REQUIRE(VALID_NMHANDLE(handle));
+       sock = handle->sock;
+       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(sock->type == isc_nm_tcpsocket);
+
+       atomic_store(&sock->manual_read_timer, manual);
+}