2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 15:45:25 +00:00

netmgr: actively close all sockets when shutting down server

without this change, named could sometimes lag for a while on shutdown
while it waited for open TCP connections to time out.
This commit is contained in:
Witold Kręcicki
2019-11-22 14:13:19 +01:00
committed by Evan Hunt
parent 37354ee225
commit d6c5052f7e
3 changed files with 56 additions and 6 deletions

View File

@@ -116,12 +116,9 @@ typedef enum isc__netievent_type {
netievent_tcpstoplisten, netievent_tcpstoplisten,
netievent_tcpclose, netievent_tcpclose,
netievent_closecb, netievent_closecb,
netievent_shutdown,
} isc__netievent_type; } isc__netievent_type;
typedef struct isc__netievent_stop {
isc__netievent_type type;
} isc__netievent_stop_t;
/* /*
* We have to split it because we can read and write on a socket * We have to split it because we can read and write on a socket
* simultaneously. * simultaneously.
@@ -209,10 +206,13 @@ typedef struct isc__netievent {
isc__netievent_type type; isc__netievent_type type;
} isc__netievent_t; } isc__netievent_t;
typedef isc__netievent_t isc__netievent_shutdown_t;
typedef isc__netievent_t isc__netievent_stop_t;
typedef union { typedef union {
isc__netievent_t ni; isc__netievent_t ni;
isc__netievent_stop_t nis; isc__netievent__socket_t nis;
isc__netievent_udplisten_t niul; isc__netievent__socket_req_t nisr;
isc__netievent_udpsend_t nius; isc__netievent_udpsend_t nius;
} isc__netievent_storage_t; } isc__netievent_storage_t;
@@ -523,6 +523,13 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ievent0);
* Issue a 'handle closed' callback on the socket. * Issue a 'handle closed' callback on the socket.
*/ */
void
isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ievent0);
/*%<
* Walk through all uv handles, get the underlying sockets and issue
* close on them.
*/
isc_result_t isc_result_t
isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region,
isc_nm_cb_t cb, void *cbarg); isc_nm_cb_t cb, void *cbarg);
@@ -555,6 +562,12 @@ isc__nm_tcp_close(isc_nmsocket_t *sock);
* Close a TCP socket. * Close a TCP socket.
*/ */
void
isc__nm_tcp_shutdown(isc_nmsocket_t *sock);
/*%<
* Called on shutdown to close and clean up a listening TCP socket.
*/
void void
isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ievent0); isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ievent0);
void void

View File

@@ -309,6 +309,12 @@ isc_nm_destroy(isc_nm_t **mgr0) {
mgr = *mgr0; mgr = *mgr0;
*mgr0 = NULL; *mgr0 = NULL;
for (size_t i = 0; i < mgr->nworkers; i++) {
isc__netievent_t *event = NULL;
event = isc__nm_get_ievent(mgr, netievent_shutdown);
isc__nm_enqueue_ievent(&mgr->workers[i], event);
}
/* /*
* Wait for the manager to be dereferenced elsehwere. * Wait for the manager to be dereferenced elsehwere.
*/ */
@@ -512,6 +518,9 @@ async_cb(uv_async_t *handle) {
case netievent_closecb: case netievent_closecb:
isc__nm_async_closecb(worker, ievent); isc__nm_async_closecb(worker, ievent);
break; break;
case netievent_shutdown:
isc__nm_async_shutdown(worker, ievent);
break;
default: default:
INSIST(0); INSIST(0);
ISC_UNREACHABLE(); ISC_UNREACHABLE();
@@ -1174,6 +1183,27 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ievent0) {
isc_nmsocket_detach(&ievent->sock); isc_nmsocket_detach(&ievent->sock);
} }
static void
shutdown_walk_cb(uv_handle_t *handle, void *arg) {
isc_nmsocket_t *sock = NULL;
UNUSED(arg);
switch(handle->type) {
case UV_TCP:
isc__nm_tcp_shutdown((isc_nmsocket_t *) handle->data);
break;
default:
break;
}
}
void
isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ievent0) {
UNUSED(ievent0);
uv_walk(&worker->loop, shutdown_walk_cb, NULL);
}
bool bool
isc__nm_acquire_interlocked(isc_nm_t *mgr) { isc__nm_acquire_interlocked(isc_nm_t *mgr) {
LOCK(&mgr->lock); LOCK(&mgr->lock);

View File

@@ -688,3 +688,10 @@ isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ievent0) {
tcp_close_direct(ievent->sock); tcp_close_direct(ievent->sock);
} }
void
isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock));
sock->rcb.recv(sock->tcphandle, NULL, sock->rcbarg);
}