]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add isc__nm_udp_shutdown() function
authorOndřej Surý <ondrej@sury.org>
Mon, 26 Oct 2020 11:30:54 +0000 (12:30 +0100)
committerOndřej Surý <ondrej@sury.org>
Wed, 9 Dec 2020 09:46:16 +0000 (10:46 +0100)
This function will be called during isc_nm_closedown() to ensure
that all UDP sockets are closed and detached.

(cherry picked from commit 7a6056bc8f95040cfb613b790fc966644558d2b1)

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

index 96fc5064aa20300209b6dcb9e255359a8ea4a36d..2aac00e2dd5632189778223b70b9148f82e75e0a 100644 (file)
@@ -739,6 +739,13 @@ isc__nm_udp_cancelread(isc_nmhandle_t *handle);
  * Stop reading on a connected UDP handle.
  */
 
+void
+isc__nm_udp_shutdown(isc_nmsocket_t *sock);
+/*%<
+ * Called during the shutdown process to close and clean up connected
+ * sockets.
+ */
+
 void
 isc__nm_udp_stoplistening(isc_nmsocket_t *sock);
 
index 2428a2a3fbcf0a8740570ba6f506f5cb565997d7..82c356154ec435fb5fc154618b28991a0a033d44 100644 (file)
@@ -1615,6 +1615,9 @@ shutdown_walk_cb(uv_handle_t *handle, void *arg) {
        UNUSED(arg);
 
        switch (handle->type) {
+       case UV_UDP:
+               isc__nm_udp_shutdown(uv_handle_get_data(handle));
+               break;
        case UV_TCP:
                isc__nm_tcp_shutdown(uv_handle_get_data(handle));
                break;
index afe97a7e3646cafa89c62ea3fe869450539bd5a9..a133e7c0cb8dce79e80be7759504a314534c2cf2 100644 (file)
@@ -654,6 +654,7 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
                return (r);
        }
        isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]);
+       atomic_store(&sock->connecting, false);
 
 #ifdef ISC_RECV_BUFFER_SIZE
        uv_recv_buffer_size(&sock->uv_handle.handle,
@@ -817,28 +818,39 @@ udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
 }
 
 static void
-readtimeout_cb(uv_timer_t *handle) {
-       isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)handle);
+failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
        isc_nm_recv_cb_t cb;
        void *cbarg = NULL;
 
-       REQUIRE(VALID_NMSOCK(sock));
-       REQUIRE(sock->tid == isc_nm_tid());
-
-       /*
-        * Timeout; stop reading and process whatever we have.
-        */
        uv_udp_recv_stop(&sock->uv_handle.udp);
 
+       if (sock->timer_initialized) {
+               uv_timer_stop(&sock->timer);
+               sock->timer_running = false;
+       }
+
        cb = sock->recv_cb;
        cbarg = sock->recv_cbarg;
        isc__nmsocket_clearcb(sock);
 
        if (cb != NULL) {
-               cb(sock->statichandle, ISC_R_TIMEDOUT, NULL, cbarg);
+               cb(sock->statichandle, result, NULL, cbarg);
        }
 }
 
+static void
+readtimeout_cb(uv_timer_t *handle) {
+       isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)handle);
+
+       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(sock->tid == isc_nm_tid());
+
+       /*
+        * Timeout; stop reading and process whatever we have.
+        */
+       failed_read_cb(sock, ISC_R_TIMEDOUT);
+}
+
 /*
  * Asynchronous 'udpread' call handler: start or resume reading on a socket;
  * pause reading and call the 'recv' callback after each datagram.
@@ -957,6 +969,41 @@ isc__nm_udp_close(isc_nmsocket_t *sock) {
        }
 }
 
+void
+isc__nm_udp_shutdown(isc_nmsocket_t *sock) {
+       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(sock->tid == isc_nm_tid());
+
+       if (atomic_load(&sock->connecting)) {
+               isc__nm_uvreq_t *req = NULL;
+
+               atomic_store(&sock->connecting, false);
+               req = uv_handle_get_data((uv_handle_t *)&sock->timer);
+               uv_timer_stop(&sock->timer);
+               sock->timer_running = false;
+
+               isc__nmsocket_clearcb(sock);
+               if (sock->connect_cb != NULL) {
+                       sock->connect_cb(NULL, ISC_R_CANCELED,
+                                        sock->connect_cbarg);
+               }
+
+               isc__nm_uvreq_put(&req, sock);
+               isc__nmsocket_detach(&sock);
+       } else if (sock->type == isc_nm_udpsocket && sock->statichandle != NULL)
+       {
+               /*
+                * If the socket is active, mark it inactive and
+                * continue. If it isn't active, stop now.
+                */
+               if (!isc__nmsocket_deactivate(sock)) {
+                       return;
+               }
+
+               failed_read_cb(sock, ISC_R_CANCELED);
+       }
+}
+
 void
 isc__nm_udp_cancelread(isc_nmhandle_t *handle) {
        isc_nmsocket_t *sock = NULL;
@@ -988,16 +1035,7 @@ isc__nm_async_udpcancel(isc__networker_t *worker, isc__netievent_t *ev0) {
        uv_udp_recv_stop(&sock->uv_handle.udp);
 
        if (atomic_load(&sock->client)) {
-               isc_nm_recv_cb_t cb;
-               void *cbarg = NULL;
-
-               cb = sock->recv_cb;
-               cbarg = sock->recv_cbarg;
-               isc__nmsocket_clearcb(sock);
-
-               if (cb != NULL) {
-                       cb(handle, ISC_R_EOF, NULL, cbarg);
-               }
+               failed_read_cb(sock, ISC_R_EOF);
        }
 
        isc_nmhandle_detach(&handle);