diff --git a/tests/isc/Makefile.am b/tests/isc/Makefile.am index 5bdf2fb3dc..5cdd915aeb 100644 --- a/tests/isc/Makefile.am +++ b/tests/isc/Makefile.am @@ -36,6 +36,7 @@ check_PROGRAMS = \ parse_test \ proxyheader_test \ proxystream_test \ + proxyudp_test \ quota_test \ radix_test \ random_test \ @@ -125,6 +126,20 @@ proxystream_test_SOURCES = \ netmgr_common.c \ stream_shutdown.c +proxyudp_test_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(OPENSSL_CFLAGS) + +proxyudp_test_LDADD = \ + $(LDADD) \ + $(OPENSSL_LIBS) + +proxyudp_test_SOURCES = \ + proxyudp_test.c \ + netmgr_common.h \ + netmgr_common.c \ + uv_wrap.h + random_test_LDADD = \ $(LDADD) \ -lm diff --git a/tests/isc/netmgr_common.c b/tests/isc/netmgr_common.c index fadbb6a036..e5d685f4fe 100644 --- a/tests/isc/netmgr_common.c +++ b/tests/isc/netmgr_common.c @@ -107,10 +107,11 @@ bool noanswer = false; bool stream_use_TLS = false; bool stream_use_PROXY = false; bool stream_PROXY_over_TLS = false; -bool udp_use_PROXY = false; bool stream = false; in_port_t stream_port = 0; +bool udp_use_PROXY = false; + isc_nm_recv_cb_t connect_readcb = NULL; isc_nm_proxyheader_info_t proxy_info_data; @@ -443,6 +444,11 @@ listen_read_cb(isc_nmhandle_t *handle, isc_result_t eresult, switch (eresult) { case ISC_R_SUCCESS: + if (udp_use_PROXY || stream_use_PROXY) { + assert_true(isc_nm_is_proxy_handle(handle)); + proxy_verify_endpoints(handle); + } + memmove(&magic, region->base, sizeof(magic)); assert_true(magic == send_magic); @@ -520,6 +526,7 @@ stream_accept_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) { if (stream_use_PROXY) { assert_true(isc_nm_is_proxy_handle(handle)); + proxy_verify_endpoints(handle); } isc_refcount_increment0(&active_sreads); @@ -908,6 +915,25 @@ stream_timeout_recovery_setup(void **state ISC_ATTR_UNUSED) { return (r); } +void +proxy_verify_endpoints(isc_nmhandle_t *handle) { + isc_sockaddr_t local, peer; + peer = isc_nmhandle_peeraddr(handle); + local = isc_nmhandle_localaddr(handle); + + if (isc_nm_is_proxy_unspec(handle)) { + isc_sockaddr_t real_local, real_peer; + real_peer = isc_nmhandle_real_peeraddr(handle); + real_local = isc_nmhandle_real_localaddr(handle); + + assert_true(isc_sockaddr_equal(&peer, &real_peer)); + assert_true(isc_sockaddr_equal(&local, &real_local)); + } else if (proxy_info == NULL) { + assert_true(isc_sockaddr_equal(&peer, &proxy_src)); + assert_true(isc_sockaddr_equal(&local, &proxy_dst)); + } +} + int proxystream_timeout_recovery_setup(void **state) { stream_use_PROXY = true; @@ -1199,7 +1225,8 @@ setup_udp_test(void **state) { udp_listen_addr = (isc_sockaddr_t){ .length = 0 }; isc_sockaddr_fromin6(&udp_listen_addr, &in6addr_loopback, - UDP_TEST_PORT); + udp_use_PROXY ? PROXYUDP_TEST_PORT + : UDP_TEST_PORT); atomic_store(&sreads, 0); atomic_store(&ssends, 0); @@ -1253,8 +1280,14 @@ teardown_udp_test(void **state) { static void udp_connect(isc_nm_cb_t cb, void *cbarg, unsigned int timeout) { - isc_nm_udpconnect(netmgr, &udp_connect_addr, &udp_listen_addr, cb, - cbarg, timeout); + if (udp_use_PROXY) { + isc_nm_proxyudpconnect(netmgr, &udp_connect_addr, + &udp_listen_addr, cb, cbarg, timeout, + NULL); + } else { + isc_nm_udpconnect(netmgr, &udp_connect_addr, &udp_listen_addr, + cb, cbarg, timeout); + } } static void @@ -1268,8 +1301,17 @@ udp_listen_read_cb(isc_nmhandle_t *handle, isc_result_t eresult, static void udp_start_listening(uint32_t nworkers, isc_nm_recv_cb_t cb) { - isc_result_t result = isc_nm_listenudp( - netmgr, nworkers, &udp_listen_addr, cb, NULL, &listen_sock); + isc_result_t result; + + if (udp_use_PROXY) { + result = isc_nm_listenproxyudp(netmgr, nworkers, + &udp_listen_addr, cb, NULL, + &listen_sock); + } else { + result = isc_nm_listenudp(netmgr, nworkers, &udp_listen_addr, + cb, NULL, &listen_sock); + } + assert_int_equal(result, ISC_R_SUCCESS); isc_loop_teardown(mainloop, stop_listening, listen_sock); @@ -1377,6 +1419,10 @@ udp__connect_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) { switch (eresult) { case ISC_R_SUCCESS: + if (udp_use_PROXY) { + assert_true(isc_nm_is_proxy_handle(handle)); + } + if (have_expected_cconnects(atomic_fetch_add(&cconnects, 1) + 1)) { @@ -1443,6 +1489,19 @@ udp_noop(void **arg ISC_ATTR_UNUSED) { udp_connect(connect_success_cb, NULL, UDP_T_CONNECT); } +int +proxyudp_noop_setup(void **state) { + udp_use_PROXY = true; + return (udp_noop_setup(state)); +} + +int +proxyudp_noop_teardown(void **state) { + int ret = udp_noop_teardown(state); + udp_use_PROXY = false; + return (ret); +} + static void udp_noresponse_recv_cb(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, void *cbarg) { @@ -1529,6 +1588,19 @@ udp_noresponse(void **arg ISC_ATTR_UNUSED) { udp_connect(udp_noresponse_connect_cb, listen_sock, UDP_T_SOFT); } +int +proxyudp_noresponse_setup(void **state) { + udp_use_PROXY = true; + return (udp_noresponse_setup(state)); +} + +int +proxyudp_noresponse_teardown(void **state) { + int ret = udp_noresponse_teardown(state); + udp_use_PROXY = false; + return (ret); +} + static void udp_timeout_recovery_ssend_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) { @@ -1667,6 +1739,19 @@ udp_timeout_recovery(void **arg ISC_ATTR_UNUSED) { udp_connect(udp_timeout_recovery_connect_cb, listen_sock, UDP_T_SOFT); } +int +proxyudp_timeout_recovery_setup(void **state) { + udp_use_PROXY = true; + return (udp_timeout_recovery_setup(state)); +} + +int +proxyudp_timeout_recovery_teardown(void **state) { + int ret = udp_timeout_recovery_teardown(state); + udp_use_PROXY = false; + return (ret); +} + static void udp_shutdown_connect_async_cb(void *arg ISC_ATTR_UNUSED); @@ -1722,6 +1807,19 @@ udp_shutdown_connect(void **arg ISC_ATTR_UNUSED) { isc_async_current(loopmgr, udp_shutdown_connect_async_cb, netmgr); } +int +proxyudp_shutdown_connect_setup(void **state) { + udp_use_PROXY = true; + return (udp_shutdown_connect_setup(state)); +} + +int +proxyudp_shutdown_connect_teardown(void **state) { + int ret = udp_shutdown_connect_teardown(state); + udp_use_PROXY = false; + return (ret); +} + static void udp_shutdown_read_recv_cb(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, void *cbarg) { @@ -1824,6 +1922,19 @@ udp_shutdown_read(void **arg ISC_ATTR_UNUSED) { udp_connect(udp_shutdown_read_connect_cb, NULL, UDP_T_SOFT); } +int +proxyudp_shutdown_read_setup(void **state) { + udp_use_PROXY = true; + return (udp_shutdown_read_setup(state)); +} + +int +proxyudp_shutdown_read_teardown(void **state) { + int ret = udp_shutdown_read_teardown(state); + udp_use_PROXY = false; + return (ret); +} + static void udp_cancel_read_recv_cb(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, void *cbarg) { @@ -1941,6 +2052,19 @@ udp_cancel_read(void **arg ISC_ATTR_UNUSED) { udp_connect(udp_cancel_read_connect_cb, NULL, UDP_T_SOFT); } +int +proxyudp_cancel_read_setup(void **state) { + udp_use_PROXY = true; + return (udp_cancel_read_setup(state)); +} + +int +proxyudp_cancel_read_teardown(void **state) { + int ret = udp_cancel_read_teardown(state); + udp_use_PROXY = false; + return (ret); +} + int udp_recv_one_setup(void **state) { setup_udp_test(state); @@ -1985,6 +2109,19 @@ udp_recv_one(void **arg ISC_ATTR_UNUSED) { udp_enqueue_connect(NULL); } +int +proxyudp_recv_one_setup(void **state) { + udp_use_PROXY = true; + return (udp_recv_one_setup(state)); +} + +int +proxyudp_recv_one_teardown(void **state) { + int ret = udp_recv_one_teardown(state); + udp_use_PROXY = false; + return (ret); +} + int udp_recv_two_setup(void **state) { setup_udp_test(state); @@ -2029,6 +2166,19 @@ udp_recv_two(void **arg ISC_ATTR_UNUSED) { udp_enqueue_connect(NULL); } +int +proxyudp_recv_two_setup(void **state) { + udp_use_PROXY = true; + return (udp_recv_two_setup(state)); +} + +int +proxyudp_recv_two_teardown(void **state) { + int ret = udp_recv_two_teardown(state); + udp_use_PROXY = false; + return (ret); +} + int udp_recv_send_setup(void **state) { setup_udp_test(state); @@ -2065,6 +2215,19 @@ udp_recv_send(void **arg ISC_ATTR_UNUSED) { } } +int +proxyudp_recv_send_setup(void **state) { + udp_use_PROXY = true; + return (udp_recv_send_setup(state)); +} + +int +proxyudp_recv_send_teardown(void **state) { + int ret = udp_recv_send_teardown(state); + udp_use_PROXY = false; + return (ret); +} + static void udp_double_read_send_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) { @@ -2235,3 +2398,16 @@ udp_double_read(void **arg ISC_ATTR_UNUSED) { udp_enqueue_connect(NULL); } + +int +proxyudp_double_read_setup(void **state) { + udp_use_PROXY = true; + return (udp_double_read_setup(state)); +} + +int +proxyudp_double_read_teardown(void **state) { + int ret = udp_double_read_teardown(state); + udp_use_PROXY = false; + return (ret); +} diff --git a/tests/isc/netmgr_common.h b/tests/isc/netmgr_common.h index 3df02c883b..230e2499d4 100644 --- a/tests/isc/netmgr_common.h +++ b/tests/isc/netmgr_common.h @@ -29,6 +29,7 @@ #define TCPDNS_TEST_PORT 9156 #define TLSDNS_TEST_PORT 9157 #define PROXYSTREAM_TEST_PORT 9158 +#define PROXYUDP_TEST_PORT 9159 typedef void (*stream_connect_function)(isc_nm_t *nm); typedef void (*connect_func)(isc_nm_t *); @@ -138,6 +139,8 @@ extern bool stream_PROXY_over_TLS; extern bool stream; extern in_port_t stream_port; +extern bool udp_use_PROXY; + extern isc_nm_recv_cb_t connect_readcb; #define NSENDS 100 @@ -295,6 +298,9 @@ get_proxyheader_info(void); isc_nm_proxy_type_t get_proxy_type(void); +void +proxy_verify_endpoints(isc_nmhandle_t *handle); + int stream_noop_setup(void **state ISC_ATTR_UNUSED); void @@ -463,6 +469,12 @@ udp_noop_teardown(void **state); void udp_noop(void **arg ISC_ATTR_UNUSED); +int +proxyudp_noop_setup(void **state); + +int +proxyudp_noop_teardown(void **state); + int udp_noresponse_setup(void **state); @@ -472,6 +484,12 @@ udp_noresponse_teardown(void **state); void udp_noresponse(void **arg ISC_ATTR_UNUSED); +int +proxyudp_noresponse_setup(void **state); + +int +proxyudp_noresponse_teardown(void **state); + int udp_timeout_recovery_setup(void **state); @@ -481,6 +499,12 @@ udp_timeout_recovery_teardown(void **state); void udp_timeout_recovery(void **arg ISC_ATTR_UNUSED); +int +proxyudp_timeout_recovery_setup(void **state); + +int +proxyudp_timeout_recovery_teardown(void **state); + int udp_shutdown_connect_setup(void **state); @@ -490,6 +514,12 @@ udp_shutdown_connect_teardown(void **state); void udp_shutdown_connect(void **arg ISC_ATTR_UNUSED); +int +proxyudp_shutdown_connect_setup(void **state); + +int +proxyudp_shutdown_connect_teardown(void **state); + int udp_shutdown_read_setup(void **state); @@ -499,6 +529,12 @@ udp_shutdown_read_teardown(void **state); void udp_shutdown_read(void **arg ISC_ATTR_UNUSED); +int +proxyudp_shutdown_read_setup(void **state); + +int +proxyudp_shutdown_read_teardown(void **state); + int udp_cancel_read_setup(void **state); @@ -508,6 +544,12 @@ udp_cancel_read_teardown(void **state); void udp_cancel_read(void **arg ISC_ATTR_UNUSED); +int +proxyudp_cancel_read_setup(void **state); + +int +proxyudp_cancel_read_teardown(void **state); + int udp_recv_one_setup(void **state); @@ -517,6 +559,12 @@ udp_recv_one_teardown(void **state); void udp_recv_one(void **arg ISC_ATTR_UNUSED); +int +proxyudp_recv_one_setup(void **state); + +int +proxyudp_recv_one_teardown(void **state); + int udp_recv_two_setup(void **state); @@ -526,6 +574,12 @@ udp_recv_two_teardown(void **state); void udp_recv_two(void **arg ISC_ATTR_UNUSED); +int +proxyudp_recv_two_setup(void **state); + +int +proxyudp_recv_two_teardown(void **state); + int udp_recv_send_setup(void **state); @@ -535,6 +589,12 @@ udp_recv_send_teardown(void **state); void udp_recv_send(void **arg ISC_ATTR_UNUSED); +int +proxyudp_recv_send_setup(void **state); + +int +proxyudp_recv_send_teardown(void **state); + int udp_double_read_setup(void **state); @@ -543,3 +603,9 @@ udp_double_read_teardown(void **state); void udp_double_read(void **arg ISC_ATTR_UNUSED); + +int +proxyudp_double_read_setup(void **state); + +int +proxyudp_double_read_teardown(void **state); diff --git a/tests/isc/proxyudp_test.c b/tests/isc/proxyudp_test.c new file mode 100644 index 0000000000..cf544fed1e --- /dev/null +++ b/tests/isc/proxyudp_test.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#include +#include /* IWYU pragma: keep */ +#include +#include +#include +#include +#include + +/* + * As a workaround, include an OpenSSL header file before including cmocka.h, + * because OpenSSL 3.1.0 uses __attribute__(malloc), conflicting with a + * redefined malloc in cmocka.h. + */ +#include + +#define UNIT_TESTING +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uv_wrap.h" +#define KEEP_BEFORE + +#include "netmgr/socket.c" +#include "netmgr/udp.c" +#include "netmgr_common.h" +#include "uv.c" + +#include + +ISC_LOOP_TEST_IMPL(proxyudp_noop) { udp_noop(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_noresponse) { udp_noresponse(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_timeout_recovery) { udp_timeout_recovery(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_shutdown_connect) { udp_shutdown_connect(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_shutdown_read) { udp_shutdown_read(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_cancel_read) { udp_cancel_read(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_recv_one) { udp_recv_one(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_recv_two) { udp_recv_two(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_recv_send) { udp_recv_send(arg); } + +ISC_LOOP_TEST_IMPL(proxyudp_double_read) { udp_double_read(arg); } + +ISC_TEST_LIST_START + +ISC_TEST_ENTRY_CUSTOM(proxyudp_noop, proxyudp_noop_setup, + proxyudp_noop_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_noresponse, proxyudp_noresponse_setup, + proxyudp_noresponse_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_timeout_recovery, + proxyudp_timeout_recovery_setup, + proxyudp_timeout_recovery_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_shutdown_read, proxyudp_shutdown_read_setup, + proxyudp_shutdown_read_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_cancel_read, proxyudp_cancel_read_setup, + proxyudp_cancel_read_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_shutdown_connect, + proxyudp_shutdown_connect_setup, + proxyudp_shutdown_connect_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_double_read, proxyudp_double_read_setup, + proxyudp_double_read_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_recv_one, proxyudp_recv_one_setup, + proxyudp_recv_one_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_recv_two, proxyudp_recv_two_setup, + proxyudp_recv_two_teardown) +ISC_TEST_ENTRY_CUSTOM(proxyudp_recv_send, proxyudp_recv_send_setup, + proxyudp_recv_send_teardown) + +ISC_TEST_LIST_END + +ISC_TEST_MAIN