]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make isc_nm_proxyudplistener into its own type
authorAlessio Podda <alessio@isc.org>
Tue, 28 Jul 2026 13:08:56 +0000 (15:08 +0200)
committerAlessio Podda <alessio@isc.org>
Wed, 12 Aug 2026 12:12:45 +0000 (14:12 +0200)
Keeping isc_nm_proxyudplistener as an instance of socket means that
proxyudp users would be slowed down by contention on high core count
machines.
It also leads to awkward code as you have an isc_nm_socket_t wrapping
a non-socket which itself wraps more isc_nm_socket_t.

With this commit, we apply the same change we did for isc_nm_udplistener
to isc_nm_proxyudplistener.

lib/isc/include/isc/netmgr.h
lib/isc/include/isc/types.h
lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/proxyudp.c
lib/isc/netmgr/udp.c
lib/ns/client.c
lib/ns/include/ns/interfacemgr.h
lib/ns/interfacemgr.c
tests/isc/netmgr_common.c
tests/isc/netmgr_common.h

index 283606d6d72b32cca66212eecf7676f4951454a4..90e10e1b4893f8e95bc2cc9a92740f823f3c19a9 100644 (file)
@@ -321,12 +321,25 @@ isc_nm_routeconnect(isc_nm_cb_t cb, void *cbarg);
 
 isc_result_t
 isc_nm_listenproxyudp(uint32_t workers, isc_sockaddr_t *iface,
-                     isc_nm_recv_cb_t cb, void *cbarg, isc_nmsocket_t **sockp);
+                     isc_nm_recv_cb_t cb, void *cbarg,
+                     isc_nm_proxyudplistener_t **listenerp);
 /*%<
  * The same as `isc_nm_listenudp()`, but PROXYv2 headers are
  * expected at the beginning of the received datagrams.
  */
 
+void
+isc_nm_proxyudplistener_stop(isc_nm_proxyudplistener_t *listener);
+/*%<
+ * Stop a PROXY UDP listener and close its per-worker sockets. This must be
+ * called before detaching the final listener reference.
+ */
+
+ISC_REFCOUNT_DECL(isc_nm_proxyudplistener);
+/*%<
+ * Increment or decrement a PROXY UDP listener reference.
+ */
+
 void
 isc_nm_proxyudpconnect(isc_sockaddr_t *local, isc_sockaddr_t *peer,
                       isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
index e268a2807f75f7e34d8672c11558d137c24d1567..9bcd44f8dd94be1c5ece53e59362dfd67dd2b2b3 100644 (file)
@@ -55,20 +55,21 @@ typedef struct isc_mempool   isc_mempool_t;       /*%< Memory Pool */
 typedef struct isc_netaddr      isc_netaddr_t;       /*%< Net Address */
 typedef struct isc_netaddrlink  isc_netaddrlink_t; /*%< Linkable Net Address */
 typedef ISC_LIST(isc_netaddrlink_t) isc_netaddrlist_t; /*%< Net Address List */
-typedef struct isc_netprefix     isc_netprefix_t;     /*%< Net Prefix */
-typedef struct isc_nmsocket      isc_nmsocket_t; /*%< Network manager socket */
-typedef struct isc_nmhandle      isc_nmhandle_t; /*%< Network manager handle */
-typedef struct isc_nm_udplistener isc_nm_udplistener_t;
-typedef struct isc_portset       isc_portset_t;     /*%< Port Set */
-typedef struct isc_quota         isc_quota_t;       /*%< Quota */
-typedef struct isc_ratelimiter   isc_ratelimiter_t; /*%< Rate Limiter */
-typedef struct isc_region        isc_region_t;      /*%< Region */
-typedef struct isc_rlevent       isc_rlevent_t;     /*%< Rate Limiter Event */
-typedef struct isc_signal        isc_signal_t;      /*%< Signal handler */
-typedef struct isc_sockaddr      isc_sockaddr_t;    /*%< Socket Address */
-typedef ISC_LIST(isc_sockaddr_t) isc_sockaddrlist_t; /*%< Socket Address List
-                                                     * */
-typedef struct isc_stats      isc_stats_t;          /*%< Statistics */
+typedef struct isc_netprefix isc_netprefix_t;         /*%< Net Prefix */
+typedef struct isc_nmsocket  isc_nmsocket_t; /*%< Network manager socket */
+typedef struct isc_nmhandle  isc_nmhandle_t; /*%< Network manager handle */
+typedef struct isc_nm_proxyudplistener isc_nm_proxyudplistener_t;
+typedef struct isc_nm_udplistener      isc_nm_udplistener_t;
+typedef struct isc_portset            isc_portset_t;     /*%< Port Set */
+typedef struct isc_quota              isc_quota_t;       /*%< Quota */
+typedef struct isc_ratelimiter        isc_ratelimiter_t; /*%< Rate Limiter */
+typedef struct isc_region             isc_region_t;      /*%< Region */
+typedef struct isc_rlevent            isc_rlevent_t; /*%< Rate Limiter Event */
+typedef struct isc_signal             isc_signal_t;  /*%< Signal handler */
+typedef struct isc_sockaddr           isc_sockaddr_t; /*%< Socket Address */
+typedef ISC_LIST(isc_sockaddr_t) isc_sockaddrlist_t;   /*%< Socket Address List
+                                                       * */
+typedef struct isc_stats      isc_stats_t;            /*%< Statistics */
 typedef int_fast64_t         isc_statscounter_t;
 typedef atomic_int_fast64_t   isc_atomic_statscounter_t;
 typedef struct isc_symtab     isc_symtab_t;    /*%< Symbol Table */
@@ -111,8 +112,7 @@ typedef enum isc_nmsocket_type {
        isc_nm_tlslistener,
        isc_nm_httplistener,
        isc_nm_streamdnslistener,
-       isc_nm_proxystreamlistener,
-       isc_nm_proxyudplistener
+       isc_nm_proxystreamlistener
 } isc_nmsocket_type;
 
 typedef isc_nmsocket_type isc_nmsocket_type_t;
index 2137ec8123a1a5822d3540014eb22933c5e670b8..28aedd765415ca49c97d4294a4e4b3d5915e48f1 100644 (file)
@@ -571,7 +571,6 @@ struct isc_nmsocket {
 
        struct {
                isc_nmsocket_t *sock;
-               isc_nm_udplistener_t *udp_listener;
                bool reading;
                size_t nsending;
                void *send_req;
@@ -581,8 +580,6 @@ struct isc_nmsocket {
                } proxy2;
                bool header_processed;
                bool extra_processed; /* data arrived past header processed */
-               isc_nmsocket_t **udp_server_socks; /* UDP sockets */
-               size_t udp_server_socks_num;
        } proxy;
 
        /*%
@@ -894,9 +891,6 @@ isc__nm_udp_shutdown(isc_nmsocket_t *sock);
  * sockets.
  */
 
-uint32_t
-isc__nm_udplistener_nchildren(const isc_nm_udplistener_t *listener);
-
 void
 isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
 /*%<
@@ -1279,9 +1273,6 @@ void
 isc__nm_proxyudp_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result,
                                const bool async);
 
-void
-isc__nm_proxyudp_stoplistening(isc_nmsocket_t *listener);
-
 void
 isc__nm_proxyudp_cleanup_data(isc_nmsocket_t *sock);
 
index 4fe1cd614414df2f110210e5a6e39912ee479f5f..e08c9289f4671b8a1d07ebf4d49075dcfaa228dc 100644 (file)
@@ -693,8 +693,7 @@ isc_nmsocket_close(isc_nmsocket_t **sockp) {
                (*sockp)->type == isc_nm_streamdnslistener ||
                (*sockp)->type == isc_nm_tlslistener ||
                (*sockp)->type == isc_nm_httplistener ||
-               (*sockp)->type == isc_nm_proxystreamlistener ||
-               (*sockp)->type == isc_nm_proxyudplistener);
+               (*sockp)->type == isc_nm_proxystreamlistener);
 
        isc__nmsocket_detach(sockp);
 }
@@ -1825,9 +1824,6 @@ isc_nm_stoplistening(isc_nmsocket_t *sock) {
        case isc_nm_proxystreamlistener:
                isc__nm_proxystream_stoplistening(sock);
                break;
-       case isc_nm_proxyudplistener:
-               isc__nm_proxyudp_stoplistening(sock);
-               break;
        default:
                UNREACHABLE();
        }
@@ -1841,8 +1837,7 @@ isc__nmsocket_stop(isc_nmsocket_t *listener) {
        REQUIRE(listener->type == isc_nm_httplistener ||
                listener->type == isc_nm_tlslistener ||
                listener->type == isc_nm_streamdnslistener ||
-               listener->type == isc_nm_proxystreamlistener ||
-               listener->type == isc_nm_proxyudplistener);
+               listener->type == isc_nm_proxystreamlistener);
        REQUIRE(!listener->closing);
 
        listener->closing = true;
@@ -2954,8 +2949,6 @@ nmsocket_type_totext(isc_nmsocket_type type) {
                return "isc_nm_proxystreamlistener";
        case isc_nm_proxystreamsocket:
                return "isc_nm_proxystreamsocket";
-       case isc_nm_proxyudplistener:
-               return "isc_nm_proxyudplistener";
        case isc_nm_proxyudpsocket:
                return "isc_nm_proxyudpsocket";
        default:
index 1c4749f899dcbd6269e5064c4eae4190089d85d9..e531faa9a9259915dc5688d1df64ca350e68dfd5 100644 (file)
@@ -22,6 +22,28 @@ typedef struct proxyudp_send_req {
        isc_buffer_t *outbuf; /* PROXY header followed by data (client only) */
 } proxyudp_send_req_t;
 
+#define PROXYUDP_LISTENER_MAGIC ISC_MAGIC('P', 'U', 'D', 'L')
+#define VALID_PROXYUDP_LISTENER(listener)                      \
+       (ISC_MAGIC_VALID(listener, PROXYUDP_LISTENER_MAGIC) && \
+        isc_refcount_current(&(listener)->references) > 0)
+
+struct isc_nm_proxyudplistener {
+       int magic;
+       isc_refcount_t references;
+       isc_mem_t *mctx;
+       isc_nm_udplistener_t *udp_listener; /* Raw UDP transport listener */
+       bool closing;
+
+       /* Per-worker PROXY socket wrappers */
+       uint32_t nproxy_sockets;
+       isc_nmsocket_t *proxy_sockets[] ISC_ATTR_COUNTED_BY(nproxy_sockets);
+};
+
+typedef struct proxyudp_child_job {
+       isc_nm_proxyudplistener_t *listener;
+       isc_tid_t tid;
+} proxyudp_child_job_t;
+
 static bool
 proxyudp_closing(isc_nmsocket_t *sock);
 
@@ -37,12 +59,20 @@ proxyudp_on_header_data_cb(const isc_result_t result,
                           const isc_region_t *restrict extra, void *cbarg);
 
 static isc_nmsocket_t *
-proxyudp_sock_new(isc__networker_t *worker, const isc_nmsocket_type_t type,
-                 isc_sockaddr_t *addr, const bool is_server);
+proxyudp_sock_new(isc__networker_t *worker, isc_sockaddr_t *addr,
+                 const bool is_server);
+
+static void
+proxyudp_listener_read_cb(isc_nmhandle_t *handle, isc_result_t result,
+                         isc_region_t *region, void *cbarg);
 
 static void
-proxyudp_read_cb(isc_nmhandle_t *handle, isc_result_t result,
-                isc_region_t *region, void *cbarg);
+proxyudp_socket_read_cb(isc_nmhandle_t *handle, isc_result_t result,
+                       isc_region_t *region, void *cbarg);
+
+static void
+proxyudp_read(isc_nmsocket_t *proxysock, isc_nmhandle_t *handle,
+             isc_result_t result, isc_region_t *region);
 
 static void
 proxyudp_call_connect_cb(isc_nmsocket_t *sock, isc_nmhandle_t *handle,
@@ -58,7 +88,7 @@ static void
 stop_proxyudp_child_job(void *arg);
 
 static void
-stop_proxyudp_child(isc_nmsocket_t *sock);
+stop_proxyudp_child(isc_nm_proxyudplistener_t *listener, isc_tid_t tid);
 
 static void
 proxyudp_clear_proxy_header_data(isc_nmsocket_t *sock);
@@ -75,6 +105,26 @@ proxyudp_put_send_req(isc_mem_t *mctx, proxyudp_send_req_t *send_req,
 static void
 proxyudp_send_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg);
 
+static void
+proxyudp_listener_destroy(isc_nm_proxyudplistener_t *listener) {
+       isc_mem_t *mctx = listener->mctx;
+       size_t size = sizeof(*listener) +
+                     ISC_CHECKED_MUL(listener->nproxy_sockets,
+                                     sizeof(listener->proxy_sockets[0]));
+
+       REQUIRE(listener->closing);
+       REQUIRE(listener->udp_listener == NULL);
+       for (size_t i = 0; i < listener->nproxy_sockets; i++) {
+               INSIST(listener->proxy_sockets[i] == NULL);
+       }
+
+       isc_refcount_destroy(&listener->references);
+       listener->magic = 0;
+       isc_mem_putanddetach(&mctx, listener, size);
+}
+
+ISC_REFCOUNT_IMPL(isc_nm_proxyudplistener, proxyudp_listener_destroy);
+
 static bool
 proxyudp_closing(isc_nmsocket_t *sock) {
        return isc__nmsocket_closing(sock) ||
@@ -203,56 +253,61 @@ unexpected:
 }
 
 static isc_nmsocket_t *
-proxyudp_sock_new(isc__networker_t *worker, const isc_nmsocket_type_t type,
-                 isc_sockaddr_t *addr, const bool is_server) {
+proxyudp_sock_new(isc__networker_t *worker, isc_sockaddr_t *addr,
+                 const bool is_server) {
        isc_nmsocket_t *sock;
-       INSIST(type == isc_nm_proxyudpsocket ||
-              type == isc_nm_proxyudplistener);
 
        sock = isc_mempool_get(worker->nmsocket_pool);
-       isc__nmsocket_init(sock, worker, type, addr, NULL);
+       isc__nmsocket_init(sock, worker, isc_nm_proxyudpsocket, addr, NULL);
        sock->result = ISC_R_UNSET;
-       if (type == isc_nm_proxyudpsocket) {
-               sock->read_timeout = isc_nm_getinitialtimeout();
-               sock->client = !is_server;
-               sock->connecting = !is_server;
-               if (!is_server) {
-                       isc_buffer_allocate(worker->mctx,
-                                           &sock->proxy.proxy2.outbuf,
-                                           ISC_NM_PROXY2_DEFAULT_BUFFER_SIZE);
-               }
-       } else if (type == isc_nm_proxyudplistener) {
-               size_t nworkers = isc_loopmgr_nloops();
-               sock->proxy.udp_server_socks_num = nworkers;
-               sock->proxy.udp_server_socks = isc_mem_cget(
-                       worker->mctx, nworkers, sizeof(isc_nmsocket_t *));
+       sock->read_timeout = isc_nm_getinitialtimeout();
+       sock->client = !is_server;
+       sock->connecting = !is_server;
+       if (!is_server) {
+               isc_buffer_allocate(worker->mctx, &sock->proxy.proxy2.outbuf,
+                                   ISC_NM_PROXY2_DEFAULT_BUFFER_SIZE);
        }
 
        return sock;
 }
 
 static void
-proxyudp_read_cb(isc_nmhandle_t *handle, isc_result_t result,
-                isc_region_t *region, void *cbarg) {
-       isc_nmsocket_t *sock = (isc_nmsocket_t *)cbarg;
+proxyudp_listener_read_cb(isc_nmhandle_t *handle, isc_result_t result,
+                         isc_region_t *region, void *cbarg) {
+       isc_nm_proxyudplistener_t *listener = cbarg;
        isc_nmsocket_t *proxysock = NULL;
 
-       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(VALID_PROXYUDP_LISTENER(listener));
        REQUIRE(VALID_NMHANDLE(handle));
 
-       if (sock->client) {
-               proxysock = sock;
-       } else {
-               INSIST(sock->type == isc_nm_proxyudplistener);
-               proxysock = sock->proxy.udp_server_socks[handle->sock->tid];
-               if (proxysock->outerhandle == NULL) {
-                       isc_nmhandle_attach(handle, &proxysock->outerhandle);
-               }
-
-               proxysock->iface = isc_nmhandle_localaddr(handle);
-               proxysock->peer = isc_nmhandle_peeraddr(handle);
+       INSIST(handle->sock->tid >= 0);
+       INSIST((uint32_t)handle->sock->tid < listener->nproxy_sockets);
+       proxysock = listener->proxy_sockets[handle->sock->tid];
+       if (proxysock->outerhandle == NULL) {
+               isc_nmhandle_attach(handle, &proxysock->outerhandle);
        }
 
+       proxysock->iface = isc_nmhandle_localaddr(handle);
+       proxysock->peer = isc_nmhandle_peeraddr(handle);
+
+       proxyudp_read(proxysock, handle, result, region);
+}
+
+static void
+proxyudp_socket_read_cb(isc_nmhandle_t *handle, isc_result_t result,
+                       isc_region_t *region, void *cbarg) {
+       isc_nmsocket_t *proxysock = cbarg;
+
+       REQUIRE(VALID_NMSOCK(proxysock));
+       REQUIRE(VALID_NMHANDLE(handle));
+       INSIST(proxysock->client);
+
+       proxyudp_read(proxysock, handle, result, region);
+}
+
+static void
+proxyudp_read(isc_nmsocket_t *proxysock, isc_nmhandle_t *handle,
+             isc_result_t result, isc_region_t *region) {
        INSIST(proxysock->tid == isc_tid());
 
        if (result != ISC_R_SUCCESS) {
@@ -317,57 +372,52 @@ failed:
 isc_result_t
 isc_nm_listenproxyudp(uint32_t workers, isc_sockaddr_t *iface,
                      isc_nm_recv_cb_t cb, void *cbarg,
-                     isc_nmsocket_t **sockp) {
+                     isc_nm_proxyudplistener_t **listenerp) {
        isc_result_t result;
-       isc_nmsocket_t *listener = NULL;
+       isc_nm_proxyudplistener_t *listener = NULL;
        isc__networker_t *worker = isc__networker_current();
+       uint32_t nproxy_sockets = (workers == ISC_NM_LISTEN_ALL)
+                                         ? (uint32_t)isc_loopmgr_nloops()
+                                         : workers;
+       size_t size = sizeof(*listener) +
+                     ISC_CHECKED_MUL(nproxy_sockets,
+                                     sizeof(listener->proxy_sockets[0]));
 
        REQUIRE(isc_tid() == 0);
-       REQUIRE(sockp != NULL && *sockp == NULL);
+       REQUIRE(listenerp != NULL && *listenerp == NULL);
 
        if (isc__nm_closing(worker)) {
                return ISC_R_SHUTTINGDOWN;
        }
 
-       listener = proxyudp_sock_new(worker, isc_nm_proxyudplistener, iface,
-                                    true);
-       listener->recv_cb = cb;
-       listener->recv_cbarg = cbarg;
-
-       for (size_t i = 0; i < listener->proxy.udp_server_socks_num; i++) {
-               listener->proxy.udp_server_socks[i] =
-                       proxyudp_sock_new(isc__networker_get(i),
-                                         isc_nm_proxyudpsocket, iface, true);
-
-               listener->proxy.udp_server_socks[i]->recv_cb =
-                       listener->recv_cb;
-
-               listener->proxy.udp_server_socks[i]->recv_cbarg =
-                       listener->recv_cbarg;
+       listener = isc_mem_get(worker->mctx, size);
+       *listener = (isc_nm_proxyudplistener_t){
+               .magic = PROXYUDP_LISTENER_MAGIC,
+               .references = ISC_REFCOUNT_INITIALIZER(1),
+               .mctx = isc_mem_ref(worker->mctx),
+               .nproxy_sockets = nproxy_sockets,
+       };
+       REQUIRE(listener->nproxy_sockets > 0);
+       REQUIRE(listener->nproxy_sockets <= isc_loopmgr_nloops());
 
-               isc__nmsocket_attach(
-                       listener,
-                       &listener->proxy.udp_server_socks[i]->listener);
+       for (size_t i = 0; i < listener->nproxy_sockets; i++) {
+               listener->proxy_sockets[i] =
+                       proxyudp_sock_new(isc__networker_get(i), iface, true);
+               listener->proxy_sockets[i]->recv_cb = cb;
+               listener->proxy_sockets[i]->recv_cbarg = cbarg;
        }
 
-       result = isc_nm_listenudp(workers, iface, proxyudp_read_cb, listener,
-                                 &listener->proxy.udp_listener);
+       result = isc_nm_listenudp(workers, iface, proxyudp_listener_read_cb,
+                                 listener, &listener->udp_listener);
 
        if (result == ISC_R_SUCCESS) {
-               listener->active = true;
-               listener->result = result;
-               listener->nchildren = isc__nm_udplistener_nchildren(
-                       listener->proxy.udp_listener);
-               *sockp = listener;
+               *listenerp = listener;
        } else {
-               for (size_t i = 0; i < listener->proxy.udp_server_socks_num;
-                    i++)
-               {
-                       stop_proxyudp_child(
-                               listener->proxy.udp_server_socks[i]);
+               listener->closing = true;
+               for (size_t i = 0; i < listener->nproxy_sockets; i++) {
+                       stop_proxyudp_child(listener, i);
                }
-               listener->closed = true;
-               isc__nmsocket_detach(&listener);
+               isc_nm_proxyudplistener_detach(&listener);
        }
 
        return result;
@@ -454,7 +504,7 @@ isc_nm_proxyudpconnect(isc_sockaddr_t *local, isc_sockaddr_t *peer,
                return;
        }
 
-       nsock = proxyudp_sock_new(worker, isc_nm_proxyudpsocket, local, false);
+       nsock = proxyudp_sock_new(worker, local, false);
        nsock->connect_cb = cb;
        nsock->connect_cbarg = cbarg;
        nsock->read_timeout = timeout;
@@ -486,66 +536,64 @@ isc_nm_proxyudpconnect(isc_sockaddr_t *local, isc_sockaddr_t *peer,
  */
 static void
 stop_proxyudp_child_job(void *arg) {
-       isc_nmsocket_t *listener = NULL;
-       isc_nmsocket_t *sock = arg;
-       isc_tid_t tid = 0;
-
-       if (sock == NULL) {
-               return;
-       }
+       proxyudp_child_job_t *job = arg;
+       isc_nm_proxyudplistener_t *listener = job->listener;
+       isc_nmsocket_t *sock = listener->proxy_sockets[job->tid];
+       isc_mem_t *mctx = listener->mctx;
 
+       INSIST(VALID_PROXYUDP_LISTENER(listener));
        INSIST(VALID_NMSOCK(sock));
        INSIST(sock->tid == isc_tid());
-
-       listener = sock->listener;
-       sock->listener = NULL;
-
-       INSIST(VALID_NMSOCK(listener));
-       INSIST(listener->type == isc_nm_proxyudplistener);
+       INSIST(sock->tid == job->tid);
 
        if (sock->outerhandle != NULL) {
                proxyudp_stop_reading(sock);
                isc_nmhandle_detach(&sock->outerhandle);
        }
 
-       tid = sock->tid;
        isc__nmsocket_prep_destroy(sock);
-       isc__nmsocket_detach(&listener->proxy.udp_server_socks[tid]);
-       isc__nmsocket_detach(&listener);
+       isc__nmsocket_detach(&listener->proxy_sockets[job->tid]);
+       isc_mem_put(mctx, job, sizeof(*job));
+       isc_nm_proxyudplistener_detach(&listener);
 }
 
 static void
-stop_proxyudp_child(isc_nmsocket_t *sock) {
+stop_proxyudp_child(isc_nm_proxyudplistener_t *listener, isc_tid_t tid) {
+       isc_nmsocket_t *sock = NULL;
+       proxyudp_child_job_t *job = NULL;
+
+       REQUIRE(VALID_PROXYUDP_LISTENER(listener));
+       REQUIRE(tid >= 0);
+       REQUIRE((uint32_t)tid < listener->nproxy_sockets);
+
+       sock = listener->proxy_sockets[tid];
        REQUIRE(VALID_NMSOCK(sock));
+       job = isc_mem_get(listener->mctx, sizeof(*job));
+       *job = (proxyudp_child_job_t){ .tid = tid };
+       isc_nm_proxyudplistener_attach(listener, &job->listener);
 
        if (sock->tid == 0) {
-               stop_proxyudp_child_job(sock);
+               stop_proxyudp_child_job(job);
        } else {
-               isc_async_run(sock->worker->loop, stop_proxyudp_child_job,
-                             sock);
+               isc_async_run(sock->worker->loop, stop_proxyudp_child_job, job);
        }
 }
 
 void
-isc__nm_proxyudp_stoplistening(isc_nmsocket_t *listener) {
-       REQUIRE(VALID_NMSOCK(listener));
-       REQUIRE(listener->type == isc_nm_proxyudplistener);
-       REQUIRE(listener->proxy.sock == NULL);
+isc_nm_proxyudplistener_stop(isc_nm_proxyudplistener_t *listener) {
+       REQUIRE(VALID_PROXYUDP_LISTENER(listener));
+       REQUIRE(isc_tid() == 0);
        REQUIRE(!listener->closing);
 
        listener->closing = true;
-       listener->active = false;
-       isc_nm_udplistener_stop(listener->proxy.udp_listener);
-       isc_nm_udplistener_detach(&listener->proxy.udp_listener);
-       listener->recv_cb = NULL;
-       listener->recv_cbarg = NULL;
-       listener->closed = true;
+       isc_nm_udplistener_stop(listener->udp_listener);
+       isc_nm_udplistener_detach(&listener->udp_listener);
 
-       for (size_t i = 1; i < listener->proxy.udp_server_socks_num; i++) {
-               stop_proxyudp_child(listener->proxy.udp_server_socks[i]);
+       for (size_t i = 1; i < listener->nproxy_sockets; i++) {
+               stop_proxyudp_child(listener, (isc_tid_t)i);
        }
 
-       stop_proxyudp_child(listener->proxy.udp_server_socks[0]);
+       stop_proxyudp_child(listener, 0);
 }
 
 static void
@@ -566,12 +614,6 @@ isc__nm_proxyudp_cleanup_data(isc_nmsocket_t *sock) {
 
                proxyudp_clear_proxy_header_data(sock);
                break;
-       case isc_nm_proxyudplistener:
-               INSIST(sock->proxy.udp_listener == NULL);
-               isc_mem_cput(sock->worker->mctx, sock->proxy.udp_server_socks,
-                            sock->proxy.udp_server_socks_num,
-                            sizeof(isc_nmsocket_t *));
-               break;
        case isc_nm_udpsocket:
                INSIST(sock->proxy.sock == NULL);
                break;
@@ -717,7 +759,7 @@ isc__nm_proxyudp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb,
                return;
        }
 
-       isc_nm_read(sock->outerhandle, proxyudp_read_cb, sock);
+       isc_nm_read(sock->outerhandle, proxyudp_socket_read_cb, sock);
 }
 
 static proxyudp_send_req_t *
index 65ee0267408015e2c8b0aad2351a68c0d14a2aba..7674c98d21f66e07949d4a4d23e343319d74a89c 100644 (file)
@@ -143,13 +143,6 @@ udp_listener_destroy(isc_nm_udplistener_t *listener) {
 
 ISC_REFCOUNT_IMPL(isc_nm_udplistener, udp_listener_destroy);
 
-uint32_t
-isc__nm_udplistener_nchildren(const isc_nm_udplistener_t *listener) {
-       REQUIRE(VALID_UDP_LISTENER(listener));
-
-       return listener->nchildren;
-}
-
 static uv_os_sock_t
 isc__nm_udp_lb_socket(sa_family_t sa_family) {
        isc_result_t result;
index ee1c37e5a2bcbae5dfac89ba3a6e53c95c072e26..cf8a401e71254ba580f72a7e811d10fe0799ed8d 100644 (file)
@@ -149,7 +149,6 @@ ns_client_transport_type(const ns_client_t *client) {
        switch (isc_nm_socket_type(client->inner.handle)) {
        case isc_nm_udpsocket:
        case isc_nm_proxyudpsocket:
-       case isc_nm_proxyudplistener:
                return DNS_TRANSPORT_UDP;
        case isc_nm_tlssocket:
        case isc_nm_tlslistener:
index 9c4a33c5d7ddea66b63ecf7d9e24ce3b199e36fc..bb428596e80d2258ee609937bbdd6c04bbee9d03 100644 (file)
 #define NS_INTERFACEFLAG_LISTENING 0x02U /*%< listening */
 /*% The nameserver interface structure */
 struct ns_interface {
-       unsigned int          magic; /*%< Magic number. */
-       ns_interfacemgr_t    *mgr;   /*%< Interface manager. */
-       isc_mutex_t           lock;
-       unsigned int          generation; /*%< Generation number. */
-       isc_sockaddr_t        addr;       /*%< Address and port. */
-       unsigned int          flags;      /*%< Interface flags */
-       char                  name[32];   /*%< Null terminated. */
-       isc_nm_udplistener_t *udplistener;
-       isc_nmsocket_t       *proxyudplistensocket;
-       isc_nmsocket_t       *tcplistensocket;
-       isc_nmsocket_t       *tlslistensocket;
-       isc_nmsocket_t       *http_listensocket;
-       isc_nmsocket_t       *http_secure_listensocket;
-       isc_quota_t          *http_quota;
-       isc_refcount_t        ntcpaccepting; /*%< Number of clients
-                                             *   ready to accept new
-                                             *   TCP connections on this
-                                             *   interface */
-       isc_refcount_t ntcpactive;           /*%< Number of clients
-                                             *   servicing TCP queries
-                                             *   (whether accepting or
-                                             *   connected) */
-       ns_clientmgr_t     *clientmgr;       /*%< Client manager. */
+       unsigned int               magic; /*%< Magic number. */
+       ns_interfacemgr_t         *mgr;   /*%< Interface manager. */
+       isc_mutex_t                lock;
+       unsigned int               generation; /*%< Generation number. */
+       isc_sockaddr_t             addr;       /*%< Address and port. */
+       unsigned int               flags;      /*%< Interface flags */
+       char                       name[32];   /*%< Null terminated. */
+       isc_nm_udplistener_t      *udplistener;
+       isc_nm_proxyudplistener_t *proxyudplistener;
+       isc_nmsocket_t            *tcplistensocket;
+       isc_nmsocket_t            *tlslistensocket;
+       isc_nmsocket_t            *http_listensocket;
+       isc_nmsocket_t            *http_secure_listensocket;
+       isc_quota_t               *http_quota;
+       isc_refcount_t             ntcpaccepting; /*%< Number of clients
+                                                  *   ready to accept new
+                                                  *   TCP connections on this
+                                                  *   interface */
+       isc_refcount_t ntcpactive;                /*%< Number of clients
+                                                  *   servicing TCP queries
+                                                  *   (whether accepting or
+                                                  *   connected) */
+       ns_clientmgr_t     *clientmgr;            /*%< Client manager. */
        isc_nm_proxy_type_t proxy_type;
        ISC_LINK(ns_interface_t) link;
 };
index e439de9dce9172c1e1af94e6a356b1a1c20df5e1..eda77e034e5c499298820e184cd5853411f24ba9 100644 (file)
@@ -485,7 +485,7 @@ ns_interface_listenudp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy) {
                INSIST(proxy == ISC_NM_PROXY_PLAIN);
                result = isc_nm_listenproxyudp(ISC_NM_LISTEN_ALL, &ifp->addr,
                                               ns_client_request, ifp,
-                                              &ifp->proxyudplistensocket);
+                                              &ifp->proxyudplistener);
        }
        return result;
 }
@@ -734,9 +734,9 @@ ns_interface_shutdown(ns_interface_t *ifp) {
                isc_nm_udplistener_stop(ifp->udplistener);
                isc_nm_udplistener_detach(&ifp->udplistener);
        }
-       if (ifp->proxyudplistensocket != NULL) {
-               isc_nm_stoplistening(ifp->proxyudplistensocket);
-               isc_nmsocket_close(&ifp->proxyudplistensocket);
+       if (ifp->proxyudplistener != NULL) {
+               isc_nm_proxyudplistener_stop(ifp->proxyudplistener);
+               isc_nm_proxyudplistener_detach(&ifp->proxyudplistener);
        }
        if (ifp->tcplistensocket != NULL) {
                isc_nm_stoplistening(ifp->tcplistensocket);
@@ -1014,8 +1014,7 @@ same_listener_type(ns_interface_t *ifp, ns_listenelt_t *new_le) {
                /* TLS/DoT */
                same_transport_type = true;
        } else if (new_le->sslctx == NULL &&
-                  (ifp->udplistener != NULL ||
-                   ifp->proxyudplistensocket != NULL ||
+                  (ifp->udplistener != NULL || ifp->proxyudplistener != NULL ||
                    ifp->tcplistensocket != NULL))
        {
                /* "plain" DNS/Do53 */
index cd7d600ed46ea55bc3a209e06e73b0e39bf4b921..518f84b3aa3172cf0a5777ef226a60e51d350800 100644 (file)
@@ -98,6 +98,7 @@ isc_refcount_t active_sreads = 0;
 
 isc_nmsocket_t *listen_sock = NULL;
 isc_nm_udplistener_t *udp_listen_sock = NULL;
+isc_nm_proxyudplistener_t *proxyudp_listen_sock = NULL;
 
 isc_quota_t listener_quota;
 atomic_bool check_listener_quota = false;
@@ -246,6 +247,13 @@ stop_udp_listening(void *arg ISC_ATTR_UNUSED) {
        assert_null(udp_listen_sock);
 }
 
+static void
+stop_proxyudp_listening(void *arg ISC_ATTR_UNUSED) {
+       isc_nm_proxyudplistener_stop(proxyudp_listen_sock);
+       isc_nm_proxyudplistener_detach(&proxyudp_listen_sock);
+       assert_null(proxyudp_listen_sock);
+}
+
 /* Callbacks */
 
 void
@@ -1352,7 +1360,7 @@ udp_start_listening(uint32_t nworkers, isc_nm_recv_cb_t cb) {
 
        if (udp_use_PROXY) {
                result = isc_nm_listenproxyudp(nworkers, &udp_listen_addr, cb,
-                                              NULL, &listen_sock);
+                                              NULL, &proxyudp_listen_sock);
        } else {
                result = isc_nm_listenudp(nworkers, &udp_listen_addr, cb, NULL,
                                          &udp_listen_sock);
@@ -1361,7 +1369,8 @@ udp_start_listening(uint32_t nworkers, isc_nm_recv_cb_t cb) {
        assert_int_equal(result, ISC_R_SUCCESS);
 
        if (udp_use_PROXY) {
-               isc_loop_teardown(isc_loop_main(), stop_listening, listen_sock);
+               isc_loop_teardown(isc_loop_main(), stop_proxyudp_listening,
+                                 proxyudp_listen_sock);
        } else {
                isc_loop_teardown(isc_loop_main(), stop_udp_listening,
                                  udp_listen_sock);
index 0cb072510dce31573eba82d1237d29690551ee2e..20951591bc48b570f5afff6eda2d463f5135892d 100644 (file)
@@ -125,6 +125,7 @@ extern isc_refcount_t active_sreads;
 
 extern isc_nmsocket_t *listen_sock;
 extern isc_nm_udplistener_t *udp_listen_sock;
+extern isc_nm_proxyudplistener_t *proxyudp_listen_sock;
 
 extern isc_quota_t listener_quota;
 extern atomic_bool check_listener_quota;