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.17.7~31^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a6056bc8f95040cfb613b790fc966644558d2b1;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. --- diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index d5a167ad50c..9c5d3ad2ef9 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -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); diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 144380deaf9..bd3c2df771c 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 01974a53d15..a8a55c06b88 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -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);