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:
committed by
Evan Hunt
parent
37354ee225
commit
d6c5052f7e
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user