]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add isc_nmhandle_settimeout() function
authorEvan Hunt <each@isc.org>
Tue, 3 Nov 2020 03:58:05 +0000 (19:58 -0800)
committerOndřej Surý <ondrej@sury.org>
Wed, 9 Dec 2020 09:46:16 +0000 (10:46 +0100)
this function sets the read timeout for the socket associated
with a netmgr handle and, if the timer is running, resets it.
for TCPDNS sockets it also sets the read timeout and resets the
timer on the outer TCP socket.

(cherry picked from commit 4be63c5b00700f83a96da67cc092bb3b87efaf15)

lib/isc/include/isc/netmgr.h
lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tcp.c
lib/isc/netmgr/tcpdns.c
lib/isc/netmgr/udp.c
lib/isc/win32/libisc.def.in

index 063b5f41c3ddc5d52ed2eb78d5f44707cc73959a..2cd65eb99a9190423dd3cd321d59a7616eb5f6ce 100644 (file)
@@ -135,16 +135,27 @@ isc_nmhandle_getextra(isc_nmhandle_t *handle);
 bool
 isc_nmhandle_is_stream(isc_nmhandle_t *handle);
 
-/*
- * isc_nmhandle_t has a void * opaque field (usually - ns_client_t).
+void
+isc_nmhandle_setdata(isc_nmhandle_t *handle, void *arg,
+                    isc_nm_opaquecb_t doreset, isc_nm_opaquecb_t dofree);
+/*%<
+ * isc_nmhandle_t has a void* opaque field (for example, ns_client_t).
  * We reuse handle and `opaque` can also be reused between calls.
  * This function sets this field and two callbacks:
  * - doreset resets the `opaque` to initial state
  * - dofree frees everything associated with `opaque`
  */
+
 void
-isc_nmhandle_setdata(isc_nmhandle_t *handle, void *arg,
-                    isc_nm_opaquecb_t doreset, isc_nm_opaquecb_t dofree);
+isc_nmhandle_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the read/recv timeout for the socket connected to 'handle'
+ * to 'timeout', and reset the timer.
+ *
+ * When this is called on a 'wrapper' socket handle (for example,
+ * a TCPDNS socket wrapping a TCP connection), the timer is set for
+ * both socket layers.
+ */
 
 isc_sockaddr_t
 isc_nmhandle_peeraddr(isc_nmhandle_t *handle);
@@ -359,9 +370,9 @@ isc_nm_tcpdns_sequential(isc_nmhandle_t *handle);
  */
 
 void
-isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle);
+isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle, bool value);
 /*%<
- * Enable keepalive on this connection.
+ * Enable/disable keepalive on this connection by setting it to 'value'.
  *
  * When keepalive is active, we switch to using the keepalive timeout
  * to determine when to close a connection, rather than the idle timeout.
index e6d5cf697171cbf099582a68a29c539a0ea58a2e..d7bdecc633b83827a7d2769dc49d46f2aae6ea53 100644 (file)
@@ -750,6 +750,15 @@ isc__nm_udp_shutdown(isc_nmsocket_t *sock);
 
 void
 isc__nm_udp_stoplistening(isc_nmsocket_t *sock);
+/*%<
+ * Stop listening on 'sock'.
+ */
+
+void
+isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the recv timeout for the UDP socket associated with 'handle'.
+ */
 
 void
 isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0);
@@ -815,6 +824,15 @@ isc__nm_tcp_cancelread(isc_nmhandle_t *handle);
 
 void
 isc__nm_tcp_stoplistening(isc_nmsocket_t *sock);
+/*%<
+ * Stop listening on 'sock'.
+ */
+
+void
+isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the read timeout for the TCP socket associated with 'handle'.
+ */
 
 void
 isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0);
@@ -860,6 +878,16 @@ isc__nm_tcpdns_close(isc_nmsocket_t *sock);
 
 void
 isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock);
+/*%<
+ * Stop listening on 'sock'.
+ */
+
+void
+isc__nm_tcpdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the read timeout and reset the timer for the TCPDNS socket
+ * associated with 'handle', and the TCP socket it wraps around.
+ */
 
 void
 isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0);
index ebc9cd37b9919a059e713f9a410111b9940c6f32..42aeb12e32357fcd7dddfdf011412c9ecfa85f5b 100644 (file)
@@ -1385,6 +1385,26 @@ isc_nmhandle_setdata(isc_nmhandle_t *handle, void *arg,
        handle->dofree = dofree;
 }
 
+void
+isc_nmhandle_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+       REQUIRE(VALID_NMHANDLE(handle));
+
+       switch (handle->sock->type) {
+       case isc_nm_udpsocket:
+               isc__nm_udp_settimeout(handle, timeout);
+               break;
+       case isc_nm_tcpsocket:
+               isc__nm_tcp_settimeout(handle, timeout);
+               break;
+       case isc_nm_tcpdnssocket:
+               isc__nm_tcpdns_settimeout(handle, timeout);
+               break;
+       default:
+               INSIST(0);
+               ISC_UNREACHABLE();
+       }
+}
+
 void *
 isc_nmhandle_getextra(isc_nmhandle_t *handle) {
        REQUIRE(VALID_NMHANDLE(handle));
index 86b4eda80cab1d8393713caa84ff1dbb69c76486..448ffc5f7c0725b8dc94e74daa8a5ca1ebb1a331 100644 (file)
@@ -813,6 +813,10 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
        sock->recv_cb = cb;
        sock->recv_cbarg = cbarg;
 
+       sock->read_timeout = (atomic_load(&sock->keepalive)
+                                     ? sock->mgr->keepalive
+                                     : sock->mgr->idle);
+
        ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstartread);
        ievent->sock = sock;
 
@@ -885,9 +889,9 @@ isc__nm_async_tcp_startread(isc__networker_t *worker, isc__netievent_t *ev0) {
        if (sock->read_timeout != 0) {
                if (!sock->timer_initialized) {
                        uv_timer_init(&worker->loop, &sock->timer);
-                       uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
                        sock->timer_initialized = true;
                }
+               uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
                uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout,
                               0);
                sock->timer_running = true;
@@ -987,10 +991,6 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
                        cb(sock->statichandle, ISC_R_SUCCESS, &region, cbarg);
                }
 
-               sock->read_timeout = (atomic_load(&sock->keepalive)
-                                             ? sock->mgr->keepalive
-                                             : sock->mgr->idle);
-
                if (sock->timer_initialized && sock->read_timeout != 0) {
                        /* The timer will be updated */
                        uv_timer_start(&sock->timer, readtimeout_cb,
@@ -1471,3 +1471,18 @@ isc__nm_async_tcpcancel(isc__networker_t *worker, isc__netievent_t *ev0) {
 
        isc_nmhandle_detach(&handle);
 }
+
+void
+isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+       isc_nmsocket_t *sock = NULL;
+
+       REQUIRE(VALID_NMHANDLE(handle));
+
+       sock = handle->sock;
+
+       sock->read_timeout = timeout;
+       if (sock->timer_running) {
+               uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout,
+                              0);
+       }
+}
index ad85928d17c30efb6cb4ab1f7ba9958ef5b010f4..b06d56415da3b5247a97c628db559ccf74d497bb 100644 (file)
@@ -470,7 +470,7 @@ isc_nm_tcpdns_sequential(isc_nmhandle_t *handle) {
 }
 
 void
-isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle) {
+isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle, bool value) {
        REQUIRE(VALID_NMHANDLE(handle));
 
        if (handle->sock->type != isc_nm_tcpdnssocket ||
@@ -479,8 +479,8 @@ isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle) {
                return;
        }
 
-       atomic_store(&handle->sock->keepalive, true);
-       atomic_store(&handle->sock->outerhandle->sock->keepalive, true);
+       atomic_store(&handle->sock->keepalive, value);
+       atomic_store(&handle->sock->outerhandle->sock->keepalive, value);
 }
 
 static void
@@ -831,6 +831,10 @@ isc__nm_tcpdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
        sock->recv_cb = cb;
        sock->recv_cbarg = cbarg;
 
+       sock->read_timeout = (atomic_load(&sock->keepalive)
+                                     ? sock->mgr->keepalive
+                                     : sock->mgr->idle);
+
        /*
         * Add a reference to the handle to keep it from being freed by
         * the caller; it will be detached in in isc__nm_async_tcpdnsread().
@@ -943,3 +947,22 @@ isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
 
        isc_nmhandle_detach(&handle);
 }
+
+void
+isc__nm_tcpdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+       isc_nmsocket_t *sock = NULL;
+
+       REQUIRE(VALID_NMHANDLE(handle));
+
+       sock = handle->sock;
+
+       if (sock->outerhandle != NULL) {
+               isc__nm_tcp_settimeout(sock->outerhandle, timeout);
+       }
+
+       sock->read_timeout = timeout;
+       if (sock->timer_running) {
+               uv_timer_start(&sock->timer, dnstcp_readtimeout,
+                              sock->read_timeout, 0);
+       }
+}
index 7f710e0b4628fe39e603ea19d58cdb4768868ed6..7cc78f0e3dbd66ec91d6880d57a090f96711f3e2 100644 (file)
@@ -1144,3 +1144,18 @@ isc__nm_async_udpcancel(isc__networker_t *worker, isc__netievent_t *ev0) {
 
        isc_nmhandle_detach(&handle);
 }
+
+void
+isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+       isc_nmsocket_t *sock = NULL;
+
+       REQUIRE(VALID_NMHANDLE(handle));
+
+       sock = handle->sock;
+
+       sock->read_timeout = timeout;
+       if (sock->timer_running) {
+               uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout,
+                              0);
+       }
+}
index 5e6e22efb0105eac521ffc9c8266b3d527c625f3..99cfb966ec7d200beb29c0ea32d78d20a5db902a 100644 (file)
@@ -453,6 +453,7 @@ isc_nmhandle_netmgr
 isc_nmhandle_localaddr
 isc_nmhandle_peeraddr
 isc_nmhandle_setdata
+isc_nmhandle_settimeout
 isc_nm_cancelread
 isc_nm_closedown
 isc_nm_destroy