]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
TCP: add manual read timer control mode
authorArtem Boldariev <artem@boldariev.com>
Tue, 18 Oct 2022 12:21:10 +0000 (15:21 +0300)
committerArtem Boldariev <artem@boldariev.com>
Tue, 20 Dec 2022 19:24:44 +0000 (21:24 +0200)
This commit adds a manual read timer control mode to the TCP
code (adding isc__nmhandle_set_manual_timer() as the interface to it).

Manual read timer control mode suppresses read timer restarting the
read timer when receiving any amount of data. This way the read timer
can be controlled manually using:

* isc__nmsocket_timer_start();
* isc__nmsocket_timer_stop();
* isc__nmsocket_timer_restart().

The change is required to make it possible to implement more
sophisticated read timer control policies in DNS transports, built on
top of TCP.

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

index c23a53731aeffbb7ca6f402eb71f55b9b6c5cbdd..18833bfbde20deee9e415c0818cbd901696e2c21 100644 (file)
@@ -1062,6 +1062,7 @@ struct isc_nmsocket {
        atomic_int_fast32_t active_child_connections;
 
        bool barrier_initialised;
+       bool manual_read_timer;
 #ifdef NETMGR_TRACE
        void *backtrace[TRACE_SIZE];
        int backtrace_size;
@@ -1354,6 +1355,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_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0);
 void
@@ -2008,3 +2012,10 @@ isc__nmsocket_log(const isc_nmsocket_t *sock, int level, const char *fmt, ...)
 void
 isc__nmhandle_log(const isc_nmhandle_t *handle, int level, const char *fmt, ...)
        ISC_FORMAT_PRINTF(3, 4);
+
+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 fa9f60ec18afad5d45a7c53d964d128b370457af..350e3ba96390132325271a75762ac48b053b86f0 100644 (file)
@@ -2898,6 +2898,25 @@ isc__nmhandle_log(const isc_nmhandle_t *handle, int level, const char *fmt,
        isc__nmsocket_log(handle->sock, level, "handle %p: %s", handle, msgbuf);
 }
 
+void
+isc__nmhandle_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));
+
+       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 52e5abac16b82501f5c6ccbb188305d8fed19413..c994622d0c588df4258a36fd9d75e0a54f957392 100644 (file)
@@ -762,7 +762,9 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
                goto failure;
        }
 
-       isc__nmsocket_timer_start(sock);
+       if (!sock->manual_read_timer) {
+               isc__nmsocket_timer_start(sock);
+       }
 
        return;
 failure:
@@ -831,7 +833,7 @@ isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
        isc__nm_readcb(sock, req, ISC_R_SUCCESS, false);
 
        /* The readcb could have paused the reading */
-       if (sock->reading) {
+       if (sock->reading && !sock->manual_read_timer) {
                /* The timer will be updated */
                isc__nmsocket_timer_restart(sock);
        }
@@ -1225,3 +1227,18 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
                isc__nmsocket_prep_destroy(sock);
        }
 }
+
+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);
+       REQUIRE(sock->tid == isc_tid());
+       REQUIRE(!sock->reading);
+       REQUIRE(!sock->recv_read);
+
+       sock->manual_read_timer = manual;
+}