2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

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.
This commit is contained in:
Evan Hunt
2020-11-02 19:58:05 -08:00
committed by Ondřej Surý
parent e12dc1faa2
commit 4be63c5b00
7 changed files with 127 additions and 14 deletions

View 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.

View 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);

View 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));

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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