From: Ondřej Surý Date: Mon, 26 Oct 2020 11:30:54 +0000 (+0100) Subject: Add isc__nm_udp_shutdown() function X-Git-Tag: v9.16.11~17^2~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e9354e7bfed3ab2201b0ae03fe1e6aaca159d112;p=thirdparty%2Fbind9.git Add isc__nm_udp_shutdown() function This function will be called during isc_nm_closedown() to ensure that all UDP sockets are closed and detached. (cherry picked from commit 7a6056bc8f95040cfb613b790fc966644558d2b1) --- diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 96fc5064aa2..2aac00e2dd5 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -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); diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 2428a2a3fbc..82c356154ec 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -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; diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index afe97a7e364..a133e7c0cb8 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -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);