]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
netmgr: actively close all sockets when shutting down server
authorWitold Kręcicki <wpk@isc.org>
Fri, 22 Nov 2019 13:13:19 +0000 (14:13 +0100)
committerEvan Hunt <each@isc.org>
Sat, 23 Nov 2019 00:46:32 +0000 (16:46 -0800)
without this change, named could sometimes lag for a while on shutdown
while it waited for open TCP connections to time out.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tcp.c

index 0844cdcbb7d16517785af3cb9e7c1a67bac39a46..f2aa88af1a3f0eda370a64760be2a2fc27ce28ee 100644 (file)
@@ -116,12 +116,9 @@ typedef enum isc__netievent_type {
        netievent_tcpstoplisten,
        netievent_tcpclose,
        netievent_closecb,
+       netievent_shutdown,
 } 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
  * simultaneously.
@@ -209,10 +206,13 @@ typedef struct isc__netievent {
        isc__netievent_type     type;
 } isc__netievent_t;
 
+typedef isc__netievent_t isc__netievent_shutdown_t;
+typedef isc__netievent_t isc__netievent_stop_t;
+
 typedef union {
                isc__netievent_t                  ni;
-               isc__netievent_stop_t             nis;
-               isc__netievent_udplisten_t        niul;
+               isc__netievent__socket_t          nis;
+               isc__netievent__socket_req_t      nisr;
                isc__netievent_udpsend_t          nius;
 } 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.
  */
 
+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__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region,
                 isc_nm_cb_t cb, void *cbarg);
@@ -555,6 +562,12 @@ isc__nm_tcp_close(isc_nmsocket_t *sock);
  * 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
 isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ievent0);
 void
index d7699e6d97e79d56ffa5fc324d6527b9361c9adc..2b02a54734dc364758a31939c6885cf8ebec941c 100644 (file)
@@ -309,6 +309,12 @@ isc_nm_destroy(isc_nm_t **mgr0) {
        mgr = *mgr0;
        *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.
         */
@@ -512,6 +518,9 @@ async_cb(uv_async_t *handle) {
                case netievent_closecb:
                        isc__nm_async_closecb(worker, ievent);
                        break;
+               case netievent_shutdown:
+                       isc__nm_async_shutdown(worker, ievent);
+                       break;
                default:
                        INSIST(0);
                        ISC_UNREACHABLE();
@@ -1174,6 +1183,27 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ievent0) {
        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
 isc__nm_acquire_interlocked(isc_nm_t *mgr) {
        LOCK(&mgr->lock);
index 5283740f5ebd54ba8f98df1497e34e43984c2d0f..bfe4af956d31b232ad3c20cab7f48ef3f23b9122 100644 (file)
@@ -688,3 +688,10 @@ isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ievent0) {
 
        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);
+}