]> 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@isc.org>
Fri, 30 Oct 2020 10:11:54 +0000 (11:11 +0100)
This function will be called during isc_nm_closedown() to ensure
that all UDP sockets are closed and detached.

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

index d5a167ad50ca3cdedf02df8666c1d196056fcc96..9c5d3ad2ef932169516efe6ce9f8ce245a4b1044 100644 (file)
@@ -737,6 +737,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 144380deaf99cb1b5ca4b39d64f042c2bc3a2683..bd3c2df771c33888f41220e7bc5180de1407b496 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 01974a53d1540bb4bbf74a0bb640e24737bed715..a8a55c06b885849044fd4a3191fc2ebf78ce4f32 100644 (file)
@@ -656,6 +656,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,
@@ -819,28 +820,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.
@@ -959,6 +971,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;
@@ -990,16 +1037,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);