From: Evan Hunt Date: Tue, 3 Nov 2020 03:58:05 +0000 (-0800) Subject: add isc_nmhandle_settimeout() function X-Git-Tag: v9.16.11~17^2~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4598d7b30d21aeb45a7bc22ef913c1b710b1edf5;p=thirdparty%2Fbind9.git add isc_nmhandle_settimeout() function 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) --- diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index 063b5f41c3d..2cd65eb99a9 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -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. diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index e6d5cf69717..d7bdecc633b 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -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); diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index ebc9cd37b99..42aeb12e323 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -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)); diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 86b4eda80ca..448ffc5f7c0 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -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, ®ion, 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); + } +} diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index ad85928d17c..b06d56415da 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -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); + } +} diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 7f710e0b462..7cc78f0e3db 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -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); + } +} diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 5e6e22efb01..99cfb966ec7 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -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