]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Revert the tree to allow cherry-picking netmgr changes from main
authorOndřej Surý <ondrej@isc.org>
Thu, 1 Oct 2020 12:58:39 +0000 (14:58 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 1 Oct 2020 14:44:43 +0000 (16:44 +0200)
The following reverted changes will be picked again as part of the
netmgr sync with main branch.

Revert "Merge branch '1996-confidential-issue-v9_16' into 'security-v9_16'"

This reverts commit e160b1509fd5027db283617baec2f7c616ba381a, reversing
changes made to c01e6437155e14fbed37e19c2bd7c49ae366c0ac.

Revert "Merge branch '2038-use-freebind-when-bind-fails-v9_16' into 'v9_16'"

This reverts commit 5f8ecfb9182e9bcd706e33fe78e247690c5bd65c, reversing
changes made to 23021385d5453807a741d31ed75627f9bf90a93d.

Revert "Merge branch '1936-blackhole-fix-v9_16' into 'v9_16'"

This reverts commit f20bc90a727bb100275197cac16da88f9795b946, reversing
changes made to 490016ebf126ea3d77261effb4c06791dc71b11d.

Revert "Merge branch '1938-fix-udp-race' into 'v9_16'"

This reverts commit 0a6c7ab2a960b2a9e418a9785869cad42e3451fd, reversing
changes made to 4ea84740e64f44ff1d397f1a317682633f174b0d.

Revert "Merge branch '1947-fix-tcpdns-race' into 'v9_16'"

This reverts commit 4ea84740e64f44ff1d397f1a317682633f174b0d, reversing
changes made to d761cd576bd61f6118341aa35edf4870f8775f8c.

13 files changed:
bin/tests/system/acl/ns2/named5.conf.in
bin/tests/system/acl/tests.sh
lib/isc/include/isc/netmgr.h
lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tcp.c
lib/isc/netmgr/tcpdns.c
lib/isc/netmgr/udp.c
lib/ns/client.c
lib/ns/include/ns/client.h
lib/ns/include/ns/interfacemgr.h
lib/ns/interfacemgr.c
lib/ns/win32/libns.def

index 7e20bac49dc2f4e9b346fb4b97272ce6cf6e7238..4b4e05027aad474bb5f7bc6473ca3e588fb4a81b 100644 (file)
@@ -31,7 +31,6 @@ options {
        ixfr-from-differences yes;
        check-integrity no;
        allow-query-on { 10.53.0.2; };
-       blackhole { 10.53.0.8; };
 };
 
 key one {
index b4d30451d1bb0e345ec53a65f74715596454dffc..9fc600dd2583ab30c2c9655d590da2d97a53da60 100644 (file)
@@ -144,26 +144,6 @@ $DIG -p ${PORT} +tcp soa example. \
        @10.53.0.2 -b 10.53.0.3 > dig.out.${t}
 grep "status: NOERROR" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
 
-echo_i "testing blackhole ACL processing"
-t=`expr $t + 1`
-ret=0
-$DIG -p ${PORT} +tcp soa example. \
-       @10.53.0.2 -b 10.53.0.3 > dig.out.1.${t}
-grep "status: NOERROR" dig.out.1.${t} > /dev/null 2>&1 || ret=1
-$DIG -p ${PORT} +tcp soa example. \
-       @10.53.0.2 -b 10.53.0.8 > dig.out.2.${t}
-grep "status: NOERROR" dig.out.2.${t} > /dev/null 2>&1 && ret=1
-grep "communications error" dig.out.2.${t} > /dev/null 2>&1 || ret=1
-$DIG -p ${PORT} soa example. \
-       @10.53.0.2 -b 10.53.0.3 > dig.out.3.${t}
-grep "status: NOERROR" dig.out.3.${t} > /dev/null 2>&1 || ret=1
-$DIG -p ${PORT} soa example. \
-       @10.53.0.2 -b 10.53.0.8 > dig.out.4.${t}
-grep "status: NOERROR" dig.out.4.${t} > /dev/null 2>&1 && ret=1
-grep "connection timed out" dig.out.4.${t} > /dev/null 2>&1 || ret=1
-[ $ret -eq 0 ] || echo_i "failed"
-status=`expr $status + $ret`
-
 # AXFR tests against ns3
 
 echo_i "testing allow-transfer ACLs against ns3 (no existing zones)"
index ebc851599ee0e074b8905cbb142470cae9261a8a..54e1e9b08802fbecdfde7a3e88180f3e5677aadd 100644 (file)
@@ -24,47 +24,6 @@ typedef enum {
        NMEV_SHUTDOWN
 } isc_nm_eventtype;
 
-typedef void (*isc_nm_recv_cb_t)(isc_nmhandle_t *handle, isc_region_t *region,
-                                void *cbarg);
-/*%<
- * Callback function to be used when receiving a packet.
- *
- * 'handle' the handle that can be used to send back the answer.
- * 'region' contains the received data. It will be freed after
- *          return by caller.
- * 'cbarg'  the callback argument passed to isc_nm_listenudp(),
- *          isc_nm_listentcpdns(), or isc_nm_read().
- */
-
-typedef isc_result_t (*isc_nm_accept_cb_t)(isc_nmhandle_t *handle,
-                                          isc_result_t result, void *cbarg);
-/*%<
- * Callback function to be used when accepting a connection. (This differs
- * from isc_nm_cb_t below in that it returns a result code.)
- *
- * 'handle' the handle that can be used to send back the answer.
- * 'eresult' the result of the event.
- * 'cbarg'  the callback argument passed to isc_nm_listentcp() or
- * isc_nm_listentcpdns().
- */
-
-typedef void (*isc_nm_cb_t)(isc_nmhandle_t *handle, isc_result_t result,
-                           void *cbarg);
-/*%<
- * Callback function for other network completion events (send, connect).
- *
- * 'handle' the handle on which the event took place.
- * 'eresult' the result of the event.
- * 'cbarg'  the callback argument passed to isc_nm_send(),
- *          isc_nm_tcp_connect(), or isc_nm_listentcp()
- */
-
-typedef void (*isc_nm_opaquecb_t)(void *arg);
-/*%<
- * Opaque callback function, used for isc_nmhandle 'reset' and 'free'
- * callbacks.
- */
-
 isc_nm_t *
 isc_nm_start(isc_mem_t *mctx, uint32_t workers);
 /*%<
@@ -143,6 +102,8 @@ isc_nmhandle_getdata(isc_nmhandle_t *handle);
 void *
 isc_nmhandle_getextra(isc_nmhandle_t *handle);
 
+typedef void (*isc_nm_opaquecb_t)(void *arg);
+
 bool
 isc_nmhandle_is_stream(isc_nmhandle_t *handle);
 
@@ -174,6 +135,30 @@ isc_nmhandle_netmgr(isc_nmhandle_t *handle);
  * Return a pointer to the netmgr object for the given handle.
  */
 
+typedef void (*isc_nm_recv_cb_t)(isc_nmhandle_t *handle, isc_region_t *region,
+                                void *cbarg);
+/*%<
+ * Callback function to be used when receiving a packet.
+ *
+ * 'handle' the handle that can be used to send back the answer.
+ * 'region' contains the received data. It will be freed after
+ *          return by caller.
+ * 'cbarg'  the callback argument passed to isc_nm_listenudp(),
+ *          isc_nm_listentcpdns(), or isc_nm_read().
+ */
+
+typedef void (*isc_nm_cb_t)(isc_nmhandle_t *handle, isc_result_t result,
+                           void *cbarg);
+/*%<
+ * Callback function for other network completion events (send, connect,
+ * accept).
+ *
+ * 'handle' the handle on which the event took place.
+ * 'result' the result of the event.
+ * 'cbarg'  the callback argument passed to isc_nm_send(),
+ *          isc_nm_tcp_connect(), or isc_nm_listentcp()
+ */
+
 isc_result_t
 isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
                 void *cbarg, size_t extrasize, isc_nmsocket_t **sockp);
@@ -242,10 +227,9 @@ isc_nm_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
  */
 
 isc_result_t
-isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
-                isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
-                size_t extrahandlesize, int backlog, isc_quota_t *quota,
-                isc_nmsocket_t **sockp);
+isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_cb_t cb,
+                void *cbarg, size_t extrahandlesize, int backlog,
+                isc_quota_t *quota, isc_nmsocket_t **sockp);
 /*%<
  * Start listening for raw messages over the TCP interface 'iface', using
  * net manager 'mgr'.
@@ -253,8 +237,8 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
  * On success, 'sockp' will be updated to contain a new listening TCP
  * socket.
  *
- * When connection is accepted on the socket, 'accept_cb' will be called with
- * 'accept_cbarg' as its argument. The callback is expected to start a read.
+ * When a message is received on the socket, 'cb' will be called with 'cbarg'
+ * as its argument.
  *
  * When handles are allocated for the socket, 'extrasize' additional bytes
  * will be allocated along with the handle for an associated object.
@@ -269,9 +253,9 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
 
 isc_result_t
 isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
-                   void *cbarg, isc_nm_accept_cb_t accept_cb,
-                   void *accept_cbarg, size_t extrahandlesize, int backlog,
-                   isc_quota_t *quota, isc_nmsocket_t **sockp);
+                   void *cbarg, isc_nm_cb_t accept_cb, void *accept_cbarg,
+                   size_t extrahandlesize, int backlog, isc_quota_t *quota,
+                   isc_nmsocket_t **sockp);
 /*%<
  * Start listening for DNS messages over the TCP interface 'iface', using
  * net manager 'mgr'.
@@ -285,7 +269,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
  * When a complete DNS message is received on the socket, 'cb' will be
  * called with 'cbarg' as its argument.
  *
- * When a new TCPDNS connection is accepted, 'accept_cb' will be called
+ * When a new TCP connection is accepted, 'accept_cb' will be called
  * with 'accept_cbarg' as its argument.
  *
  * When handles are allocated for the socket, 'extrasize' additional bytes
index bb5b8f7960fa0aa4165526be0cf051937e54edba..7539f5d3d5c394d71bb9b485c912d502f95efc0e 100644 (file)
@@ -136,9 +136,7 @@ typedef enum isc__netievent_type {
        netievent_tcpaccept,
        netievent_tcpstop,
        netievent_tcpclose,
-
        netievent_tcpdnsclose,
-       netievent_tcpdnssend,
 
        netievent_closecb,
        netievent_shutdown,
@@ -158,7 +156,7 @@ typedef enum isc__netievent_type {
  */
 typedef union {
        isc_nm_recv_cb_t recv;
-       isc_nm_accept_cb_t accept;
+       isc_nm_cb_t accept;
 } isc__nm_readcb_t;
 
 typedef union {
@@ -168,7 +166,7 @@ typedef union {
 
 typedef union {
        isc_nm_recv_cb_t recv;
-       isc_nm_accept_cb_t accept;
+       isc_nm_cb_t accept;
        isc_nm_cb_t send;
        isc_nm_cb_t connect;
 } isc__nm_cb_t;
@@ -229,7 +227,6 @@ typedef struct isc__netievent__socket_req {
 typedef isc__netievent__socket_req_t isc__netievent_tcpconnect_t;
 typedef isc__netievent__socket_req_t isc__netievent_tcplisten_t;
 typedef isc__netievent__socket_req_t isc__netievent_tcpsend_t;
-typedef isc__netievent__socket_req_t isc__netievent_tcpdnssend_t;
 
 typedef struct isc__netievent__socket_streaminfo_quota {
        isc__netievent_type type;
@@ -560,6 +557,16 @@ isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event);
  * way to use an isc__networker_t from another thread.)
  */
 
+void
+isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf);
+/*%<
+ * Allocator for recv operations.
+ *
+ * Note that as currently implemented, this doesn't actually
+ * allocate anything, it just assigns the the isc__networker's UDP
+ * receive buffer to a socket, and marks it as "in use".
+ */
+
 void
 isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf);
 /*%<
@@ -739,9 +746,6 @@ isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock);
 void
 isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0);
 
-void
-isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0);
-
 #define isc__nm_uverr2result(x) \
        isc___nm_uverr2result(x, true, __FILE__, __LINE__)
 isc_result_t
@@ -783,9 +787,3 @@ isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid);
 /*%<
  * Decrement socket-related statistics counters.
  */
-
-isc_result_t
-isc__nm_socket_freebind(const uv_handle_t *handle);
-/*%<
- * Set the IP_FREEBIND (or equivalent) socket option on the uv_handle
- */
index c261808b177d7a4354f99aeaba7f1c5e7f291d27..c1dfe121de154866dfb8dde5f25ba4ffffc93cd4 100644 (file)
@@ -621,9 +621,6 @@ process_queue(isc__networker_t *worker, isc_queue_t *queue) {
                case netievent_tcpsend:
                        isc__nm_async_tcpsend(worker, ievent);
                        break;
-               case netievent_tcpdnssend:
-                       isc__nm_async_tcpdnssend(worker, ievent);
-                       break;
                case netievent_tcpstop:
                        isc__nm_async_tcpstop(worker, ievent);
                        break;
@@ -830,13 +827,10 @@ nmsocket_maybe_destroy(isc_nmsocket_t *sock) {
        if (active_handles == 0 || sock->tcphandle != NULL) {
                destroy = true;
        }
+       UNLOCK(&sock->lock);
 
        if (destroy) {
-               atomic_store(&sock->destroying, true);
-               UNLOCK(&sock->lock);
                nmsocket_cleanup(sock, true);
-       } else {
-               UNLOCK(&sock->lock);
        }
 }
 
@@ -976,6 +970,23 @@ isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
        sock->magic = NMSOCK_MAGIC;
 }
 
+void
+isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
+       isc_nmsocket_t *sock = uv_handle_get_data(handle);
+       isc__networker_t *worker = NULL;
+
+       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(isc__nm_in_netthread());
+       REQUIRE(size <= ISC_NETMGR_RECVBUF_SIZE);
+
+       worker = &sock->mgr->workers[sock->tid];
+       INSIST(!worker->recvbuf_inuse);
+
+       buf->base = worker->recvbuf;
+       worker->recvbuf_inuse = true;
+       buf->len = ISC_NETMGR_RECVBUF_SIZE;
+}
+
 void
 isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf) {
        isc__networker_t *worker = NULL;
@@ -988,7 +999,7 @@ isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf) {
        worker = &sock->mgr->workers[sock->tid];
 
        REQUIRE(worker->recvbuf_inuse);
-       if (sock->type == isc_nm_udpsocket && buf->base > worker->recvbuf &&
+       if (buf->base > worker->recvbuf &&
            buf->base <= worker->recvbuf + ISC_NETMGR_RECVBUF_SIZE)
        {
                /* Can happen in case of out-of-order recvmmsg in libuv1.36 */
@@ -1457,54 +1468,3 @@ isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid) {
                isc_stats_decrement(mgr->stats, counterid);
        }
 }
-
-#define setsockopt_on(socket, level, name) \
-       setsockopt(socket, level, name, &(int){ 1 }, sizeof(int))
-
-isc_result_t
-isc__nm_socket_freebind(const uv_handle_t *handle) {
-       /*
-        * Set the IP_FREEBIND (or equivalent option) on the uv_handle.
-        */
-       isc_result_t result = ISC_R_SUCCESS;
-       uv_os_fd_t fd;
-       if (uv_fileno(handle, &fd) != 0) {
-               return (ISC_R_FAILURE);
-       }
-#ifdef IP_FREEBIND
-       if (setsockopt_on(fd, IPPROTO_IP, IP_FREEBIND) == -1) {
-               return (ISC_R_FAILURE);
-       }
-#elif defined(IP_BINDANY) || defined(IPV6_BINDANY)
-       struct sockaddr_in sockfd;
-
-       if (getsockname(fd, (struct sockaddr *)&sockfd,
-                       &(socklen_t){ sizeof(sockfd) }) == -1)
-       {
-               return (ISC_R_FAILURE);
-       }
-#if defined(IP_BINDANY)
-       if (sockfd.sin_family == AF_INET) {
-               if (setsockopt_on(fd, IPPROTO_IP, IP_BINDANY) == -1) {
-                       return (ISC_R_FAILURE);
-               }
-       }
-#endif
-#if defined(IPV6_BINDANY)
-       if (sockfd.sin_family == AF_INET6) {
-               if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_BINDANY) == -1) {
-                       return (ISC_R_FAILURE);
-               }
-       }
-#endif
-#elif defined(SO_BINDANY)
-       if (setsockopt_on(fd, SOL_SOCKET, SO_BINDANY) == -1) {
-               return (ISC_R_FAILURE);
-       }
-#else
-       UNUSED(handle);
-       UNUSED(fd);
-       result = ISC_R_NOTIMPLEMENTED;
-#endif
-       return (result);
-}
index 0bf86a07b218923daadf96c3a891bf8b9dca62ef..27017cc6c5401a573ec26620bba249d5d31e8734 100644 (file)
@@ -160,10 +160,9 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) {
 }
 
 isc_result_t
-isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
-                isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
-                size_t extrahandlesize, int backlog, isc_quota_t *quota,
-                isc_nmsocket_t **sockp) {
+isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_cb_t cb,
+                void *cbarg, size_t extrahandlesize, int backlog,
+                isc_quota_t *quota, isc_nmsocket_t **sockp) {
        isc_nmsocket_t *nsock = NULL;
        isc__netievent_tcplisten_t *ievent = NULL;
 
@@ -171,8 +170,8 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
 
        nsock = isc_mem_get(mgr->mctx, sizeof(*nsock));
        isc__nmsocket_init(nsock, mgr, isc_nm_tcplistener, iface);
-       nsock->accept_cb.accept = accept_cb;
-       nsock->accept_cbarg = accept_cbarg;
+       nsock->rcb.accept = cb;
+       nsock->rcbarg = cbarg;
        nsock->extrahandlesize = extrahandlesize;
        nsock->backlog = backlog;
        nsock->result = ISC_R_SUCCESS;
@@ -249,19 +248,6 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
 
        r = uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa,
                        flags);
-       if (r == UV_EADDRNOTAVAIL &&
-           isc__nm_socket_freebind(&sock->uv_handle.handle) == ISC_R_SUCCESS)
-       {
-               /*
-                * Retry binding with IP_FREEBIND (or equivalent option) if the
-                * address is not available. This helps with IPv6 tentative
-                * addresses which are reported by the route socket, although
-                * named is not yet able to properly bind to them.
-                */
-               r = uv_tcp_bind(&sock->uv_handle.tcp,
-                               &sock->iface->addr.type.sa, flags);
-       }
-
        if (r != 0) {
                isc__nm_incstats(sock->mgr, sock->statsindex[STATID_BINDFAIL]);
                uv_close(&sock->uv_handle.handle, tcp_close_cb);
@@ -397,9 +383,9 @@ isc__nm_async_tcpchildaccept(isc__networker_t *worker, isc__netievent_t *ev0) {
 
        handle = isc__nmhandle_get(csock, NULL, &local);
 
-       INSIST(ssock->accept_cb.accept != NULL);
+       INSIST(ssock->rcb.accept != NULL);
        csock->read_timeout = ssock->mgr->init;
-       ssock->accept_cb.accept(handle, ISC_R_SUCCESS, ssock->accept_cbarg);
+       ssock->rcb.accept(handle, ISC_R_SUCCESS, ssock->rcbarg);
        isc_nmsocket_detach(&csock);
        return;
 
@@ -532,30 +518,6 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
        return (ISC_R_SUCCESS);
 }
 
-/*%<
- * Allocator for TCP read operations. Limited to size 2^16.
- *
- * Note this doesn't actually allocate anything, it just assigns the
- * worker's receive buffer to a socket, and marks it as "in use".
- */
-static void
-tcp_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
-       isc_nmsocket_t *sock = uv_handle_get_data(handle);
-       isc__networker_t *worker = NULL;
-
-       REQUIRE(VALID_NMSOCK(sock));
-       REQUIRE(sock->type == isc_nm_tcpsocket);
-       REQUIRE(isc__nm_in_netthread());
-       REQUIRE(size <= 65536);
-
-       worker = &sock->mgr->workers[sock->tid];
-       INSIST(!worker->recvbuf_inuse);
-
-       buf->base = worker->recvbuf;
-       buf->len = size;
-       worker->recvbuf_inuse = true;
-}
-
 void
 isc__nm_async_tcp_startread(isc__networker_t *worker, isc__netievent_t *ev0) {
        isc__netievent_startread_t *ievent = (isc__netievent_startread_t *)ev0;
@@ -573,7 +535,7 @@ isc__nm_async_tcp_startread(isc__networker_t *worker, isc__netievent_t *ev0) {
                               0);
        }
 
-       r = uv_read_start(&sock->uv_handle.stream, tcp_alloc_cb, read_cb);
+       r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb, read_cb);
        if (r != 0) {
                isc__nm_incstats(sock->mgr, sock->statsindex[STATID_RECVFAIL]);
        }
index 172dcc8581b52950ede37206ea82a48ec4f705ae..2d9d1f1c3ec5761044d61bd8059f34a95b32a716 100644 (file)
@@ -98,7 +98,7 @@ dnstcp_readtimeout(uv_timer_t *timer) {
 /*
  * Accept callback for TCP-DNS connection.
  */
-static isc_result_t
+static void
 dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
        isc_nmsocket_t *dnslistensock = (isc_nmsocket_t *)cbarg;
        isc_nmsocket_t *dnssock = NULL;
@@ -106,16 +106,14 @@ dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
        REQUIRE(VALID_NMSOCK(dnslistensock));
        REQUIRE(dnslistensock->type == isc_nm_tcpdnslistener);
 
+       /* If accept() was unnsuccessful we can't do anything */
        if (result != ISC_R_SUCCESS) {
-               return (result);
+               return;
        }
 
        if (dnslistensock->accept_cb.accept != NULL) {
-               result = dnslistensock->accept_cb.accept(
-                       handle, ISC_R_SUCCESS, dnslistensock->accept_cbarg);
-               if (result != ISC_R_SUCCESS) {
-                       return (result);
-               }
+               dnslistensock->accept_cb.accept(handle, ISC_R_SUCCESS,
+                                               dnslistensock->accept_cbarg);
        }
 
        /* We need to create a 'wrapper' dnssocket for this connection */
@@ -139,8 +137,6 @@ dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
                       dnssock->read_timeout, 0);
 
        isc_nm_read(handle, dnslisten_readcb, dnssock);
-
-       return (ISC_R_SUCCESS);
 }
 
 /*
@@ -287,9 +283,9 @@ dnslisten_readcb(isc_nmhandle_t *handle, isc_region_t *region, void *arg) {
  */
 isc_result_t
 isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
-                   void *cbarg, isc_nm_accept_cb_t accept_cb,
-                   void *accept_cbarg, size_t extrahandlesize, int backlog,
-                   isc_quota_t *quota, isc_nmsocket_t **sockp) {
+                   void *cbarg, isc_nm_cb_t accept_cb, void *accept_cbarg,
+                   size_t extrahandlesize, int backlog, isc_quota_t *quota,
+                   isc_nmsocket_t **sockp) {
        /* A 'wrapper' socket object with outer set to true TCP socket */
        isc_nmsocket_t *dnslistensock = isc_mem_get(mgr->mctx,
                                                    sizeof(*dnslistensock));
@@ -369,6 +365,15 @@ isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle) {
        atomic_store(&handle->sock->outer->keepalive, true);
 }
 
+typedef struct tcpsend {
+       isc_mem_t *mctx;
+       isc_nmhandle_t *handle;
+       isc_region_t region;
+       isc_nmhandle_t *orighandle;
+       isc_nm_cb_t cb;
+       void *cbarg;
+} tcpsend_t;
+
 static void
 resume_processing(void *arg) {
        isc_nmsocket_t *sock = (isc_nmsocket_t *)arg;
@@ -440,40 +445,15 @@ resume_processing(void *arg) {
 
 static void
 tcpdnssend_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
-       isc__nm_uvreq_t *req = (isc__nm_uvreq_t *)cbarg;
+       tcpsend_t *ts = (tcpsend_t *)cbarg;
 
        UNUSED(handle);
 
-       req->cb.send(req->handle, result, req->cbarg);
-       isc_mem_put(req->sock->mgr->mctx, req->uvbuf.base, req->uvbuf.len);
-       isc__nm_uvreq_put(&req, req->handle->sock);
-}
-
-void
-isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
-       isc_result_t result;
-       isc__netievent_tcpdnssend_t *ievent =
-               (isc__netievent_tcpdnssend_t *)ev0;
-       isc__nm_uvreq_t *req = ievent->req;
-       isc_nmsocket_t *sock = ievent->sock;
-
-       REQUIRE(worker->id == sock->tid);
-
-       result = ISC_R_NOTCONNECTED;
-       if (atomic_load(&sock->active)) {
-               isc_region_t r;
-
-               r.base = (unsigned char *)req->uvbuf.base;
-               r.length = req->uvbuf.len;
-               result = isc__nm_tcp_send(sock->outer->tcphandle, &r,
-                                         tcpdnssend_cb, req);
-       }
+       ts->cb(ts->orighandle, result, ts->cbarg);
+       isc_mem_put(ts->mctx, ts->region.base, ts->region.length);
 
-       if (result != ISC_R_SUCCESS) {
-               req->cb.send(req->handle, result, req->cbarg);
-               isc_mem_put(sock->mgr->mctx, req->uvbuf.base, req->uvbuf.len);
-               isc__nm_uvreq_put(&req, sock);
-       }
+       isc_nmhandle_unref(ts->orighandle);
+       isc_mem_putanddetach(&ts->mctx, ts, sizeof(*ts));
 }
 
 /*
@@ -482,7 +462,7 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
 isc_result_t
 isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
                    isc_nm_cb_t cb, void *cbarg) {
-       isc__nm_uvreq_t *uvreq = NULL;
+       tcpsend_t *t = NULL;
 
        REQUIRE(VALID_NMHANDLE(handle));
 
@@ -491,46 +471,36 @@ isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(sock->type == isc_nm_tcpdnssocket);
 
-       uvreq = isc__nm_uvreq_get(sock->mgr, sock);
-       uvreq->handle = handle;
-       isc_nmhandle_ref(uvreq->handle);
-       uvreq->cb.send = cb;
-       uvreq->cbarg = cbarg;
-
-       uvreq->uvbuf.base = isc_mem_get(sock->mgr->mctx, region->length + 2);
-       uvreq->uvbuf.len = region->length + 2;
-       *(uint16_t *)uvreq->uvbuf.base = htons(region->length);
-       memmove(uvreq->uvbuf.base + 2, region->base, region->length);
+       if (sock->outer == NULL) {
+               /* The socket is closed */
+               return (ISC_R_NOTCONNECTED);
+       }
 
-       if (sock->tid == isc_nm_tid()) {
-               isc_region_t r;
+       t = isc_mem_get(sock->mgr->mctx, sizeof(*t));
+       *t = (tcpsend_t){
+               .cb = cb,
+               .cbarg = cbarg,
+               .handle = handle->sock->outer->tcphandle,
+       };
 
-               r.base = (unsigned char *)uvreq->uvbuf.base;
-               r.length = uvreq->uvbuf.len;
+       isc_mem_attach(sock->mgr->mctx, &t->mctx);
+       t->orighandle = handle;
+       isc_nmhandle_ref(t->orighandle);
 
-               return (isc__nm_tcp_send(sock->outer->tcphandle, &r,
-                                        tcpdnssend_cb, uvreq));
-       } else {
-               isc__netievent_tcpdnssend_t *ievent = NULL;
+       t->region = (isc_region_t){ .base = isc_mem_get(t->mctx,
+                                                       region->length + 2),
+                                   .length = region->length + 2 };
 
-               ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpdnssend);
-               ievent->req = uvreq;
-               ievent->sock = sock;
+       *(uint16_t *)t->region.base = htons(region->length);
+       memmove(t->region.base + 2, region->base, region->length);
 
-               isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
-                                      (isc__netievent_t *)ievent);
-
-               return (ISC_R_SUCCESS);
-       }
-
-       return (ISC_R_UNEXPECTED);
+       return (isc_nm_send(t->handle, &t->region, tcpdnssend_cb, t));
 }
 
 static void
 tcpdns_close_direct(isc_nmsocket_t *sock) {
        REQUIRE(sock->tid == isc_nm_tid());
        /* We don't need atomics here, it's all in single network thread */
-
        if (sock->timer_initialized) {
                /*
                 * We need to fire the timer callback to clean it up,
index 23da362f8574591b0e58a3bfbafdebd2d24f9662..49cef6aef69231d58e0068f6023e4ab3341e2194 100644 (file)
@@ -132,32 +132,6 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
        return (ISC_R_SUCCESS);
 }
 
-/*%<
- * Allocator for UDP recv operations. Limited to size 20 * (2^16 + 2),
- * which allows enough space for recvmmsg() to get multiple messages at
- * a time.
- *
- * Note this doesn't actually allocate anything, it just assigns the
- * worker's receive buffer to a socket, and marks it as "in use".
- */
-static void
-udp_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
-       isc_nmsocket_t *sock = uv_handle_get_data(handle);
-       isc__networker_t *worker = NULL;
-
-       REQUIRE(VALID_NMSOCK(sock));
-       REQUIRE(sock->type == isc_nm_udpsocket);
-       REQUIRE(isc__nm_in_netthread());
-       REQUIRE(size <= ISC_NETMGR_RECVBUF_SIZE);
-
-       worker = &sock->mgr->workers[sock->tid];
-       INSIST(!worker->recvbuf_inuse);
-
-       buf->base = worker->recvbuf;
-       buf->len = ISC_NETMGR_RECVBUF_SIZE;
-       worker->recvbuf_inuse = true;
-}
-
 /*
  * handle 'udplisten' async call - start listening on a socket.
  */
@@ -193,20 +167,6 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
 
        r = uv_udp_bind(&sock->uv_handle.udp,
                        &sock->parent->iface->addr.type.sa, uv_bind_flags);
-       if (r == UV_EADDRNOTAVAIL &&
-           isc__nm_socket_freebind(&sock->uv_handle.handle) == ISC_R_SUCCESS)
-       {
-               /*
-                * Retry binding with IP_FREEBIND (or equivalent option) if the
-                * address is not available. This helps with IPv6 tentative
-                * addresses which are reported by the route socket, although
-                * named is not yet able to properly bind to them.
-                */
-               r = uv_udp_bind(&sock->uv_handle.udp,
-                               &sock->parent->iface->addr.type.sa,
-                               uv_bind_flags);
-       }
-
        if (r < 0) {
                isc__nm_incstats(sock->mgr, sock->statsindex[STATID_BINDFAIL]);
        }
@@ -218,7 +178,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
        uv_send_buffer_size(&sock->uv_handle.handle,
                            &(int){ ISC_SEND_BUFFER_SIZE });
 #endif
-       uv_udp_recv_start(&sock->uv_handle.udp, udp_alloc_cb, udp_recv_cb);
+       uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb, udp_recv_cb);
 }
 
 static void
@@ -249,6 +209,19 @@ static void
 stoplistening(isc_nmsocket_t *sock) {
        REQUIRE(sock->type == isc_nm_udplistener);
 
+       /*
+        * Socket is already closing; there's nothing to do.
+        */
+       if (!isc__nmsocket_active(sock)) {
+               return;
+       }
+
+       /*
+        * Mark it inactive now so that all sends will be ignored
+        * and we won't try to stop listening again.
+        */
+       atomic_store(&sock->active, false);
+
        for (int i = 0; i < sock->nchildren; i++) {
                isc__netievent_udpstop_t *event = NULL;
 
@@ -282,18 +255,6 @@ isc__nm_udp_stoplistening(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(sock->type == isc_nm_udplistener);
 
-       /*
-        * Socket is already closing; there's nothing to do.
-        */
-       if (!isc__nmsocket_active(sock)) {
-               return;
-       }
-       /*
-        * Mark it inactive now so that all sends will be ignored
-        * and we won't try to stop listening again.
-        */
-       atomic_store(&sock->active, false);
-
        /*
         * If the manager is interlocked, re-enqueue this as an asynchronous
         * event. Otherwise, go ahead and stop listening right away.
@@ -369,23 +330,25 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
 #endif
 
        /*
-        * Three reasons to return now without processing:
-        * - If addr == NULL that's the end of stream - we can
-        *   free the buffer and bail.
-        * - If we're simulating a firewall blocking UDP packets
-        *   bigger than 'maxudp' bytes for testing purposes.
-        * - If the socket is no longer active.
+        * If addr == NULL that's the end of stream - we can
+        * free the buffer and bail.
         */
-       maxudp = atomic_load(&sock->mgr->maxudp);
-       if ((addr == NULL) || (maxudp != 0 && (uint32_t)nrecv > maxudp) ||
-           (!isc__nmsocket_active(sock)))
-       {
+       if (addr == NULL) {
                if (free_buf) {
                        isc__nm_free_uvbuf(sock, buf);
                }
                return;
        }
 
+       /*
+        * Simulate a firewall blocking UDP packets bigger than
+        * 'maxudp' bytes.
+        */
+       maxudp = atomic_load(&sock->mgr->maxudp);
+       if (maxudp != 0 && (uint32_t)nrecv > maxudp) {
+               return;
+       }
+
        result = isc_sockaddr_fromsockaddr(&sockaddr, addr);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
        nmhandle = isc__nmhandle_get(sock, &sockaddr, NULL);
@@ -422,7 +385,7 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
        uint32_t maxudp = atomic_load(&sock->mgr->maxudp);
 
        /*
-        * We're simulating a firewall blocking UDP packets bigger than
+        * Simulate a firewall blocking UDP packets bigger than
         * 'maxudp' bytes, for testing purposes.
         *
         * The client would ordinarily have unreferenced the handle
@@ -546,9 +509,6 @@ udp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
        REQUIRE(sock->tid == isc_nm_tid());
        REQUIRE(sock->type == isc_nm_udpsocket);
 
-       if (!isc__nmsocket_active(sock)) {
-               return (ISC_R_CANCELED);
-       }
        isc_nmhandle_ref(req->handle);
        rv = uv_udp_send(&req->uv_req.udp_send, &sock->uv_handle.udp,
                         &req->uvbuf, 1, &peer->type.sa, udp_send_cb);
index 3c429118fd66a8bf1be9bd18295c946668b35f13..b756755644f2684f3351a828737a8a80ff6b94b8 100644 (file)
@@ -1617,6 +1617,7 @@ ns__client_put_cb(void *client0) {
 void
 ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg) {
        ns_client_t *client;
+       bool newclient = false;
        ns_clientmgr_t *mgr;
        ns_interface_t *ifp;
        isc_result_t result;
@@ -1713,23 +1714,29 @@ ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg) {
        }
 #endif /* if NS_CLIENT_DROPPORT */
 
-       env = ns_interfacemgr_getaclenv(client->manager->interface->mgr);
-       if (client->sctx->blackholeacl != NULL &&
-           (dns_acl_match(&netaddr, NULL, client->sctx->blackholeacl, env,
-                          &match, NULL) == ISC_R_SUCCESS) &&
-           match > 0)
-       {
-               ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
-                             NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
-                             "dropped request: blackholed peer");
-               isc_task_unpause(client->task);
-               return;
-       }
-
        ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
                      ISC_LOG_DEBUG(3), "%s request",
                      TCP_CLIENT(client) ? "TCP" : "UDP");
 
+       /*
+        * Check the blackhole ACL for UDP only, since TCP is done in
+        * client_newconn.
+        */
+       env = ns_interfacemgr_getaclenv(client->manager->interface->mgr);
+       if (newclient) {
+               if (client->sctx->blackholeacl != NULL &&
+                   (dns_acl_match(&netaddr, NULL, client->sctx->blackholeacl,
+                                  env, &match, NULL) == ISC_R_SUCCESS) &&
+                   match > 0)
+               {
+                       ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
+                                     NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
+                                     "blackholed UDP datagram");
+                       isc_task_unpause(client->task);
+                       return;
+               }
+       }
+
        result = dns_message_peekheader(buffer, &id, &flags);
        if (result != ISC_R_SUCCESS) {
                /*
@@ -2190,36 +2197,17 @@ ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg) {
        isc_task_unpause(client->task);
 }
 
-isc_result_t
+void
 ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
-       ns_interface_t *ifp = (ns_interface_t *)arg;
-       dns_aclenv_t *env = ns_interfacemgr_getaclenv(ifp->mgr);
-       ns_server_t *sctx = ns_interfacemgr_getserver(ifp->mgr);
+       ns_server_t *sctx = (ns_server_t *)arg;
        unsigned int tcpquota;
-       isc_sockaddr_t peeraddr;
-       isc_netaddr_t netaddr;
-       int match;
 
+       UNUSED(handle);
        UNUSED(result);
 
-       if (handle != NULL) {
-               peeraddr = isc_nmhandle_peeraddr(handle);
-               isc_netaddr_fromsockaddr(&netaddr, &peeraddr);
-
-               if (sctx->blackholeacl != NULL &&
-                   (dns_acl_match(&netaddr, NULL, sctx->blackholeacl, env,
-                                  &match, NULL) == ISC_R_SUCCESS) &&
-                   match > 0)
-               {
-                       return (ISC_R_CONNREFUSED);
-               }
-       }
-
        tcpquota = isc_quota_getused(&sctx->tcpquota);
        ns_stats_update_if_greater(sctx->nsstats, ns_statscounter_tcphighwater,
                                   tcpquota);
-
-       return (ISC_R_SUCCESS);
 }
 
 static void
index 5cc51b8987a6bc86f9cc57fc5e4e182c91adbd84..591ccb8270458b42755d3ef6c86cdb7148cb0158 100644 (file)
@@ -476,7 +476,7 @@ ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg);
  * (Not intended for use outside this module and associated tests.)
  */
 
-isc_result_t
+void
 ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg);
 
 /*%<
index e210ee3bc0c63d2874e363c048a9ebefb9b75b8f..31f68fb39923567439e3c7c581be39b1aa06ef2f 100644 (file)
@@ -197,12 +197,6 @@ ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr);
 bool
 ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, const isc_sockaddr_t *addr);
 
-ns_server_t *
-ns_interfacemgr_getserver(ns_interfacemgr_t *mgr);
-/*%<
- * Returns the ns_server object associated with the interface manager.
- */
-
 ns_interface_t *
 ns__interfacemgr_getif(ns_interfacemgr_t *mgr);
 ns_interface_t *
index 61db9499ff8c77f494ca4001dd66ba4e06348c17..957cac90cedcf0e6ca41dd32d64f6f4096bed8ff 100644 (file)
@@ -467,7 +467,7 @@ ns_interface_listentcp(ns_interface_t *ifp) {
 
        result = isc_nm_listentcpdns(
                ifp->mgr->nm, (isc_nmiface_t *)&ifp->addr, ns__client_request,
-               ifp, ns__client_tcpconn, ifp, sizeof(ns_client_t),
+               ifp, ns__client_tcpconn, ifp->mgr->sctx, sizeof(ns_client_t),
                ifp->mgr->backlog, &ifp->mgr->sctx->tcpquota,
                &ifp->tcplistensocket);
        if (result != ISC_R_SUCCESS) {
@@ -481,12 +481,7 @@ ns_interface_listentcp(ns_interface_t *ifp) {
         * this is necessary because we are adding to the TCP quota just
         * by listening.
         */
-       result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp);
-       if (result != ISC_R_SUCCESS) {
-               isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
-                             "connecting TCP socket: %s",
-                             isc_result_totext(result));
-       }
+       ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp->mgr->sctx);
 
 #if 0
 #ifndef ISC_ALLOW_MAPPED
@@ -1272,13 +1267,6 @@ ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr,
        return (result);
 }
 
-ns_server_t *
-ns_interfacemgr_getserver(ns_interfacemgr_t *mgr) {
-       REQUIRE(NS_INTERFACEMGR_VALID(mgr));
-
-       return (mgr->sctx);
-}
-
 ns_interface_t *
 ns__interfacemgr_getif(ns_interfacemgr_t *mgr) {
        ns_interface_t *head;
index 1680e4982d68a81351cb5efd4efe372bfdc71da9..d2b9ad652f547555397081d6867211546e3d59db 100644 (file)
@@ -55,7 +55,6 @@ ns_interfacemgr_create
 ns_interfacemgr_detach
 ns_interfacemgr_dumprecursing
 ns_interfacemgr_getaclenv
-ns_interfacemgr_getserver
 ns_interfacemgr_islistening
 ns_interfacemgr_listeningon
 ns_interfacemgr_scan