]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Convert starting UDP children to to isc_async callback
authorOndřej Surý <ondrej@isc.org>
Thu, 23 Mar 2023 10:48:04 +0000 (11:48 +0100)
committerOndřej Surý <ondrej@isc.org>
Fri, 24 Mar 2023 06:58:52 +0000 (07:58 +0100)
Simplify the starting of the UDP children by using the isc_async API
from the loopmgr instead of using the asychronous netievent mechanism in
the netmgr.

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

index ef48f89eb0c52fe6bfafbae32b47983cc0efde64..d9bc96cb48da0ce244d68998160117e41e1c796d 100644 (file)
@@ -269,7 +269,6 @@ typedef enum isc__netievent_type {
        netievent_settlsctx,
        netievent_sockstop, /* for multilayer sockets */
 
-       netievent_udplisten,
        netievent_udpstop,
 
        netievent_tcplisten,
@@ -1237,8 +1236,6 @@ isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
  * Set or clear the recv timeout for the UDP socket associated with 'handle'.
  */
 
-void
-isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0);
 void
 isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0);
 void
@@ -1708,7 +1705,6 @@ NETIEVENT_SOCKET_TYPE(tlsclose);
 /* NETIEVENT_SOCKET_TYPE(tlsconnect); */ /* unique type, defined independently
                                          */
 NETIEVENT_SOCKET_TYPE(tlsdobio);
-NETIEVENT_SOCKET_TYPE(udplisten);
 NETIEVENT_SOCKET_TYPE(udpstop);
 
 #ifdef HAVE_LIBNGHTTP2
@@ -1738,7 +1734,6 @@ NETIEVENT_SOCKET_DECL(tcpstop);
 NETIEVENT_SOCKET_DECL(tlsclose);
 NETIEVENT_SOCKET_DECL(tlsconnect);
 NETIEVENT_SOCKET_DECL(tlsdobio);
-NETIEVENT_SOCKET_DECL(udplisten);
 NETIEVENT_SOCKET_DECL(udpstop);
 
 #ifdef HAVE_LIBNGHTTP2
index de66cdb9dcdd29a340c8d785bc7198b1170a0734..9acb16c69b4a3ff132cc672c9ea87024fc703a21 100644 (file)
@@ -439,7 +439,6 @@ process_netievent(void *arg) {
        isc__networker_t *worker = ievent->worker;
 
        switch (ievent->type) {
-               NETIEVENT_CASE(udplisten);
                NETIEVENT_CASE(udpstop);
                NETIEVENT_CASE(udpcancel);
 
@@ -489,7 +488,6 @@ NETIEVENT_SOCKET_DEF(tcpstop);
 NETIEVENT_SOCKET_DEF(tlsclose);
 NETIEVENT_SOCKET_DEF(tlsconnect);
 NETIEVENT_SOCKET_DEF(tlsdobio);
-NETIEVENT_SOCKET_DEF(udplisten);
 NETIEVENT_SOCKET_DEF(udpstop);
 NETIEVENT_SOCKET_HANDLE_DEF(udpcancel);
 
index be043c14a4236c91f0ae9461f1eba8246f09f12b..55d8936ecf944d9aec6a6fd47979586c05dc6174 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <unistd.h>
 
+#include <isc/async.h>
 #include <isc/atomic.h>
 #include <isc/barrier.h>
 #include <isc/buffer.h>
@@ -88,23 +89,112 @@ isc__nm_udp_lb_socket(isc_nm_t *mgr, sa_family_t sa_family) {
        return (sock);
 }
 
+/*
+ * Asynchronous 'udplisten' call handler: start listening on a UDP socket.
+ */
+static void
+start_udp_child_job(void *arg) {
+       isc_nmsocket_t *sock = arg;
+
+       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(VALID_NMSOCK(sock->parent));
+       REQUIRE(sock->type == isc_nm_udpsocket);
+       REQUIRE(sock->tid == isc_tid());
+
+       int r, uv_bind_flags = 0;
+       int uv_init_flags = 0;
+       sa_family_t sa_family = sock->iface.type.sa.sa_family;
+       isc_result_t result = ISC_R_UNSET;
+       isc_nm_t *mgr = sock->worker->netmgr;
+       isc_loop_t *loop = sock->worker->loop;
+
+       (void)isc__nm_socket_min_mtu(sock->fd, sa_family);
+
+#if HAVE_DECL_UV_UDP_RECVMMSG
+       uv_init_flags |= UV_UDP_RECVMMSG;
+#endif
+       r = uv_udp_init_ex(&loop->loop, &sock->uv_handle.udp, uv_init_flags);
+       UV_RUNTIME_CHECK(uv_udp_init_ex, r);
+       uv_handle_set_data(&sock->uv_handle.handle, sock);
+       /* This keeps the socket alive after everything else is gone */
+       isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
+
+       r = uv_timer_init(&loop->loop, &sock->read_timer);
+       UV_RUNTIME_CHECK(uv_timer_init, r);
+       uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
+
+       r = uv_udp_open(&sock->uv_handle.udp, sock->fd);
+       if (r < 0) {
+               isc__nm_closesocket(sock->fd);
+               isc__nm_incstats(sock, STATID_OPENFAIL);
+               goto done;
+       }
+       isc__nm_incstats(sock, STATID_OPEN);
+
+       if (sa_family == AF_INET6) {
+               uv_bind_flags |= UV_UDP_IPV6ONLY;
+       }
+
+       if (mgr->load_balance_sockets) {
+               r = isc__nm_udp_freebind(&sock->uv_handle.udp,
+                                        &sock->parent->iface.type.sa,
+                                        uv_bind_flags);
+               if (r < 0) {
+                       isc__nm_incstats(sock, STATID_BINDFAIL);
+                       goto done;
+               }
+       } else if (sock->tid == 0) {
+               /* This thread is first, bind the socket */
+               r = isc__nm_udp_freebind(&sock->uv_handle.udp,
+                                        &sock->parent->iface.type.sa,
+                                        uv_bind_flags);
+               if (r < 0) {
+                       isc__nm_incstats(sock, STATID_BINDFAIL);
+                       goto done;
+               }
+               sock->parent->uv_handle.udp.flags = sock->uv_handle.udp.flags;
+       } else {
+               /* The socket is already bound, just copy the flags */
+               sock->uv_handle.udp.flags = sock->parent->uv_handle.udp.flags;
+       }
+
+       isc__nm_set_network_buffers(mgr, &sock->uv_handle.handle);
+
+       r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
+                             isc__nm_udp_read_cb);
+       if (r != 0) {
+               isc__nm_incstats(sock, STATID_BINDFAIL);
+               goto done;
+       }
+
+       sock->reading = true;
+
+       atomic_store(&sock->listening, true);
+
+done:
+       result = isc_uverr2result(r);
+       atomic_fetch_add(&sock->parent->rchildren, 1);
+
+       sock->result = result;
+
+       REQUIRE(!loop->paused);
+
+       if (sock->tid != 0) {
+               isc_barrier_wait(&sock->parent->listen_barrier);
+       }
+}
+
 static void
 start_udp_child(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nmsocket_t *sock,
                uv_os_sock_t fd, int tid) {
-       isc_nmsocket_t *csock;
-       isc__netievent_udplisten_t *ievent = NULL;
        isc__networker_t *worker = &mgr->workers[tid];
-
-       csock = &sock->children[tid];
+       isc_nmsocket_t *csock = &sock->children[tid];
 
        isc__nmsocket_init(csock, worker, isc_nm_udpsocket, iface, sock);
        csock->recv_cb = sock->recv_cb;
        csock->recv_cbarg = sock->recv_cbarg;
 
-       csock->reading = true;
-
        if (mgr->load_balance_sockets) {
-               UNUSED(fd);
                csock->fd = isc__nm_udp_lb_socket(mgr,
                                                  iface->type.sa.sa_family);
        } else {
@@ -112,14 +202,10 @@ start_udp_child(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nmsocket_t *sock,
        }
        INSIST(csock->fd >= 0);
 
-       ievent = isc__nm_get_netievent_udplisten(worker, csock);
-
        if (tid == 0) {
-               isc__nm_process_ievent(&mgr->workers[tid],
-                                      (isc__netievent_t *)ievent);
+               start_udp_child_job(csock);
        } else {
-               isc__nm_enqueue_ievent(&mgr->workers[tid],
-                                      (isc__netievent_t *)ievent);
+               isc_async_run(worker->loop, start_udp_child_job, csock);
        }
 }
 
@@ -329,104 +415,6 @@ isc_nm_routeconnect(isc_nm_t *mgr, isc_nm_cb_t cb, void *cbarg) {
 #endif /* USE_ROUTE_SOCKET */
 }
 
-/*
- * Asynchronous 'udplisten' call handler: start listening on a UDP socket.
- */
-void
-isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
-       isc__netievent_udplisten_t *ievent = (isc__netievent_udplisten_t *)ev0;
-       isc_nmsocket_t *sock = NULL;
-       int r, uv_bind_flags = 0;
-       int uv_init_flags = 0;
-       sa_family_t sa_family;
-       isc_result_t result = ISC_R_UNSET;
-       isc_nm_t *mgr = NULL;
-
-       REQUIRE(VALID_NMSOCK(ievent->sock));
-       REQUIRE(VALID_NMSOCK(ievent->sock->parent));
-
-       sock = ievent->sock;
-       sa_family = sock->iface.type.sa.sa_family;
-       mgr = sock->worker->netmgr;
-
-       REQUIRE(sock->type == isc_nm_udpsocket);
-       REQUIRE(sock->tid == isc_tid());
-
-       (void)isc__nm_socket_min_mtu(sock->fd, sa_family);
-
-#if HAVE_DECL_UV_UDP_RECVMMSG
-       uv_init_flags |= UV_UDP_RECVMMSG;
-#endif
-       r = uv_udp_init_ex(&worker->loop->loop, &sock->uv_handle.udp,
-                          uv_init_flags);
-       UV_RUNTIME_CHECK(uv_udp_init_ex, r);
-       uv_handle_set_data(&sock->uv_handle.handle, sock);
-       /* This keeps the socket alive after everything else is gone */
-       isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
-
-       r = uv_timer_init(&worker->loop->loop, &sock->read_timer);
-       UV_RUNTIME_CHECK(uv_timer_init, r);
-       uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
-
-       r = uv_udp_open(&sock->uv_handle.udp, sock->fd);
-       if (r < 0) {
-               isc__nm_closesocket(sock->fd);
-               isc__nm_incstats(sock, STATID_OPENFAIL);
-               goto done;
-       }
-       isc__nm_incstats(sock, STATID_OPEN);
-
-       if (sa_family == AF_INET6) {
-               uv_bind_flags |= UV_UDP_IPV6ONLY;
-       }
-
-       if (mgr->load_balance_sockets) {
-               r = isc__nm_udp_freebind(&sock->uv_handle.udp,
-                                        &sock->parent->iface.type.sa,
-                                        uv_bind_flags);
-               if (r < 0) {
-                       isc__nm_incstats(sock, STATID_BINDFAIL);
-                       goto done;
-               }
-       } else if (sock->tid == 0) {
-               /* This thread is first, bind the socket */
-               r = isc__nm_udp_freebind(&sock->uv_handle.udp,
-                                        &sock->parent->iface.type.sa,
-                                        uv_bind_flags);
-               if (r < 0) {
-                       isc__nm_incstats(sock, STATID_BINDFAIL);
-                       goto done;
-               }
-               sock->parent->uv_handle.udp.flags = sock->uv_handle.udp.flags;
-       } else {
-               /* The socket is already bound, just copy the flags */
-               sock->uv_handle.udp.flags = sock->parent->uv_handle.udp.flags;
-       }
-
-       isc__nm_set_network_buffers(mgr, &sock->uv_handle.handle);
-
-       r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
-                             isc__nm_udp_read_cb);
-       if (r != 0) {
-               isc__nm_incstats(sock, STATID_BINDFAIL);
-               goto done;
-       }
-
-       atomic_store(&sock->listening, true);
-
-done:
-       result = isc_uverr2result(r);
-       atomic_fetch_add(&sock->parent->rchildren, 1);
-
-       sock->result = result;
-
-       REQUIRE(!worker->loop->paused);
-
-       if (sock->tid != 0) {
-               isc_barrier_wait(&sock->parent->listen_barrier);
-       }
-}
-
 static void
 stop_udp_child(isc_nmsocket_t *sock, uint32_t tid) {
        isc_nmsocket_t *csock = NULL;