]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make sure the unit test listening and connecting ports are different
authorOndřej Surý <ondrej@isc.org>
Tue, 11 Oct 2022 10:03:17 +0000 (12:03 +0200)
committerOndřej Surý <ondrej@isc.org>
Wed, 12 Oct 2022 13:36:25 +0000 (15:36 +0200)
In rare circumstances, the UDP port for the listening socket and the UDP
port for the connecting socket might be the same.  Because we use the
"reuse" port socket option, this isn't caught when binding the socket,
and thus the connected client socket could send a datagram to itself,
completely bypassing the server.  This doesn't happen under normal
operation mode because `named` is listening on a privileged port (53),
and even if not, it doesn't usually talk to itself as the tests do.

Pick an arbitrary port for listening (9153-9156) that is outside the
ephemeral port range for the network manager related unit tests (except
the `doh_test).

tests/isc/netmgr_common.c
tests/isc/netmgr_common.h
tests/isc/tcp_test.c
tests/isc/tcpdns_test.c
tests/isc/tls_test.c
tests/isc/tlsdns_test.c
tests/isc/udp_test.c

index e92a59bad5458f2e26449608df42375a03878f9e..62c9ed74eb662ee1976e0ad173c52f3de0f74ecb 100644 (file)
@@ -95,69 +95,20 @@ bool allow_send_back = false;
 bool noanswer = false;
 bool stream_use_TLS = false;
 bool stream = false;
+in_port_t stream_port = 0;
 
 isc_nm_recv_cb_t connect_readcb = NULL;
 
-int
-setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) {
-       socklen_t addrlen = sizeof(*addr);
-       uv_os_sock_t fd = -1;
-       int r;
-
-       isc_sockaddr_fromin6(addr, &in6addr_loopback, 0);
-
-       fd = socket(AF_INET6, family, 0);
-       if (fd < 0) {
-               perror("setup_ephemeral_port: socket()");
-               return (-1);
-       }
-
-       r = bind(fd, (const struct sockaddr *)&addr->type.sa,
-                sizeof(addr->type.sin6));
-       if (r != 0) {
-               perror("setup_ephemeral_port: bind()");
-               isc__nm_closesocket(fd);
-               return (r);
-       }
-
-       r = getsockname(fd, (struct sockaddr *)&addr->type.sa, &addrlen);
-       if (r != 0) {
-               perror("setup_ephemeral_port: getsockname()");
-               isc__nm_closesocket(fd);
-               return (r);
-       }
-
-#if IPV6_RECVERR
-#define setsockopt_on(socket, level, name) \
-       setsockopt(socket, level, name, &(int){ 1 }, sizeof(int))
-
-       r = setsockopt_on(fd, IPPROTO_IPV6, IPV6_RECVERR);
-       if (r != 0) {
-               perror("setup_ephemeral_port");
-               isc__nm_closesocket(fd);
-               return (r);
-       }
-#endif
-
-       return (fd);
-}
-
 int
 setup_netmgr_test(void **state) {
        char *env_workers = getenv("ISC_TASK_WORKERS");
-       uv_os_sock_t tcp_listen_sock = -1;
        size_t nworkers;
 
        tcp_connect_addr = (isc_sockaddr_t){ .length = 0 };
        isc_sockaddr_fromin6(&tcp_connect_addr, &in6addr_loopback, 0);
 
        tcp_listen_addr = (isc_sockaddr_t){ .length = 0 };
-       tcp_listen_sock = setup_ephemeral_port(&tcp_listen_addr, SOCK_STREAM);
-       if (tcp_listen_sock < 0) {
-               return (-1);
-       }
-       isc__nm_closesocket(tcp_listen_sock);
-       tcp_listen_sock = -1;
+       isc_sockaddr_fromin6(&tcp_listen_addr, &in6addr_loopback, stream_port);
 
        if (env_workers != NULL) {
                workers = atoi(env_workers);
index 17eb27b0419d797a86eaa68a3159c154d80f7f90..31d63f3fc9e3a2cc8f4c41ca5fc8fd9eebbfe1b8 100644 (file)
 
 #include "netmgr/netmgr-int.h"
 
+/*
+ * Pick unused port outside the ephemeral port range, so we don't clash with
+ * connected sockets.
+ */
+#define UDP_TEST_PORT   9153
+#define TCP_TEST_PORT   9154
+#define TLS_TEST_PORT   9155
+#define TCPDNS_TEST_PORT 9156
+#define TLSDNS_TEST_PORT 9157
+
 typedef void (*stream_connect_function)(isc_nm_t *nm);
 typedef void (*connect_func)(isc_nm_t *);
 
@@ -119,6 +129,7 @@ extern bool allow_send_back;
 extern bool noanswer;
 extern bool stream_use_TLS;
 extern bool stream;
+extern in_port_t stream_port;
 
 extern isc_nm_recv_cb_t connect_readcb;
 
@@ -213,9 +224,6 @@ extern isc_nm_recv_cb_t connect_readcb;
 #define atomic_assert_int_ge(val, exp) assert_true(atomic_load(&val) >= exp)
 #define atomic_assert_int_gt(val, exp) assert_true(atomic_load(&val) > exp)
 
-int
-setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family);
-
 int
 setup_netmgr_test(void **state);
 int
index de25a6be8e39d44fc4f5d84fa04dac44d8ce719e..b76394fa6f0b0f143c3e5a8cda1e611c1d4a3b4d 100644 (file)
@@ -132,6 +132,7 @@ ISC_TEST_LIST_END
 
 static int
 tcp_setup(void **state __attribute__((__unused__))) {
+       stream_port = TCP_TEST_PORT;
        stream_use_TLS = false;
        stream = true;
 
index 691b2468465016d11d86a990bbd002062f2e25f9..4a66629e0c2c5c255e26e9028aefb2a79ea7b805 100644 (file)
@@ -142,4 +142,12 @@ ISC_TEST_ENTRY_CUSTOM(tcpdns_recv_send, stream_recv_send_setup,
                      stream_recv_send_teardown)
 
 ISC_TEST_LIST_END
-ISC_TEST_MAIN
+
+static int
+tcpdns_setup(void **state __attribute__((__unused__))) {
+       stream_port = TCPDNS_TEST_PORT;
+
+       return (0);
+}
+
+ISC_TEST_MAIN_CUSTOM(tcpdns_setup, NULL)
index 211dd6bae445c5dac29308e9fa781043aceef26e..e4d7f86ea4f383ed76e318792705ada40a50ea7a 100644 (file)
@@ -131,6 +131,7 @@ ISC_TEST_LIST_END
 
 static int
 tls_setup(void **state __attribute__((__unused__))) {
+       stream_port = TLS_TEST_PORT;
        stream_use_TLS = true;
        stream = true;
 
index f5033fb1165991d52733b65d2abe0e50ab0ba557..2dbc3d532e647327bf3d9fc6ebcb3cd4f1d77cff 100644 (file)
@@ -147,4 +147,12 @@ ISC_TEST_ENTRY_CUSTOM(tlsdns_recv_send, stream_recv_send_setup,
 /* FIXME: Re-add the noalpn tests */
 
 ISC_TEST_LIST_END
-ISC_TEST_MAIN
+
+static int
+tlsdns_setup(void **state __attribute__((__unused__))) {
+       stream_port = TCPDNS_TEST_PORT;
+
+       return (0);
+}
+
+ISC_TEST_MAIN_CUSTOM(tlsdns_setup, NULL)
index 1006caa4d16abfa04f2105636c5fd0878dd390cb..64066ec28f2199a2a7434c385df239fed8fad07a 100644 (file)
@@ -56,8 +56,6 @@ static isc_sockaddr_t udp_connect_addr;
 
 static int
 setup_test(void **state) {
-       uv_os_sock_t udp_listen_sock = -1;
-
        setup_loopmgr(state);
        setup_netmgr(state);
 
@@ -65,11 +63,8 @@ setup_test(void **state) {
        isc_sockaddr_fromin6(&udp_connect_addr, &in6addr_loopback, 0);
 
        udp_listen_addr = (isc_sockaddr_t){ .length = 0 };
-       udp_listen_sock = setup_ephemeral_port(&udp_listen_addr, SOCK_DGRAM);
-       if (udp_listen_sock < 0) {
-               return (-1);
-       }
-       isc__nm_closesocket(udp_listen_sock);
+       isc_sockaddr_fromin6(&udp_listen_addr, &in6addr_loopback,
+                            UDP_TEST_PORT);
 
        atomic_store(&sreads, 0);
        atomic_store(&ssends, 0);