]> 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>
Sat, 7 Nov 2020 19:49:53 +0000 (20:49 +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.

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 e99631d15170d4b58a9c266018b66a294b414ed1..f4ff2186b1d3f3f32e66974979f58d31b8bc7e9c 100644 (file)
@@ -748,6 +748,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);
@@ -813,6 +822,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);
@@ -858,6 +876,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 96073495323af5c912d26a341443e90dce55bb5f..a5981c217eef41c6b049ead12bbf7ebe8871c7d4 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 d0e753e534b28a7571f38f2390bef6e4d0fef336..83236e4aeb16d79c03a544ea99901584cde5d1ed 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 2dcd48f46ec03120ef57a01a71e6950c722860ff..5d8cbebb221b03ad52b6f64b57f4b0a291703d55 100644 (file)
@@ -1146,3 +1146,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 9ee446ca3911528bd5b3b0713f2712f3490521d5..d696169ea7f1792fe588bb4b8b6ed5478f440013 100644 (file)
@@ -443,6 +443,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