1
0
Fork 0
bind9/tests/isc/netmgr_common.h
Daniel Baumann f66ff7eae6
Adding upstream version 1:9.20.9.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-21 13:32:37 +02:00

614 lines
15 KiB
C

/*
* 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 <isc/atomic.h>
#include <isc/netmgr.h>
#include <isc/refcount.h>
#include <isc/thread.h>
#include <isc/util.h>
#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
#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 *);
extern isc_nm_t *listen_nm;
extern isc_nm_t *connect_nm;
extern isc_sockaddr_t tcp_listen_addr;
extern isc_sockaddr_t tcp_connect_addr;
extern isc_tlsctx_t *tcp_listen_tlsctx;
extern isc_tlsctx_t *tcp_connect_tlsctx;
extern isc_tlsctx_client_session_cache_t *tcp_tlsctx_client_sess_cache;
extern isc_sockaddr_t udp_listen_addr;
extern isc_sockaddr_t udp_connect_addr;
extern uint64_t send_magic;
extern uint64_t stop_magic;
extern isc_region_t send_msg;
extern isc_region_t stop_msg;
extern atomic_bool do_send;
extern atomic_int_fast64_t nsends;
extern int_fast64_t esends; /* expected sends */
extern atomic_int_fast64_t ssends;
extern atomic_int_fast64_t sreads;
extern atomic_int_fast64_t saccepts;
extern atomic_int_fast64_t cconnects;
extern atomic_int_fast64_t csends;
extern atomic_int_fast64_t creads;
extern atomic_int_fast64_t ctimeouts;
extern int expected_ssends;
extern int expected_sreads;
extern int expected_csends;
extern int expected_cconnects;
extern int expected_creads;
extern int expected_ctimeouts;
extern bool ssends_shutdown;
extern bool sreads_shutdown;
extern bool csends_shutdown;
extern bool cconnects_shutdown;
extern bool creads_shutdown;
extern bool ctimeouts_shutdown;
#define have_expected_ssends(v) ((v) >= expected_ssends && expected_ssends >= 0)
#define have_expected_sreads(v) ((v) >= expected_sreads && expected_sreads >= 0)
#define have_expected_saccepts(v) \
((v) >= expected_saccepts && expected_saccepts >= 0)
#define have_expected_csends(v) ((v) >= expected_csends && expected_csends >= 0)
#define have_expected_cconnects(v) \
((v) >= expected_cconnects && expected_cconnects >= 0)
#define have_expected_creads(v) ((v) >= expected_creads && expected_creads >= 0)
#define have_expected_ctimeouts(v) \
((v) >= expected_ctimeouts && expected_ctimeouts >= 0)
#define do_ssends_shutdown(lm) \
if (ssends_shutdown) { \
isc_loopmgr_shutdown(lm); \
}
#define do_sreads_shutdown(lm) \
if (sreads_shutdown) { \
isc_loopmgr_shutdown(lm); \
}
#define do_saccepts_shutdown(lm) \
if (saccepts_shutdown) { \
isc_loopmgr_shutdown(lm); \
}
#define do_csends_shutdown(lm) \
if (csends_shutdown) { \
isc_loopmgr_shutdown(lm); \
}
#define do_cconnects_shutdown(lm) \
if (cconnects_shutdown) { \
isc_loopmgr_shutdown(lm); \
}
#define do_creads_shutdown(lm) \
if (creads_shutdown) { \
isc_loopmgr_shutdown(lm); \
}
#define do_ctimeouts_shutdown(lm) \
if (ctimeouts_shutdown) { \
isc_loopmgr_shutdown(lm); \
}
extern isc_refcount_t active_cconnects;
extern isc_refcount_t active_csends;
extern isc_refcount_t active_creads;
extern isc_refcount_t active_ssends;
extern isc_refcount_t active_sreads;
extern isc_nmsocket_t *listen_sock;
extern isc_quota_t listener_quota;
extern atomic_bool check_listener_quota;
extern bool allow_send_back;
extern bool noanswer;
extern bool stream_use_TLS;
extern bool stream_use_PROXY;
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
/* Timeout for soft-timeout tests (0.05 seconds) */
#define T_SOFT 50
/* Timeouts in miliseconds */
#define T_INIT 120 * 1000
#define T_IDLE 120 * 1000
#define T_KEEPALIVE 120 * 1000
#define T_ADVERTISED 120 * 1000
#define T_CONNECT 30 * 1000
/* Wait for 1 second (1000 milliseconds) */
#define WAIT_REPEATS 1000
#define T_WAIT 1 /* 1 millisecond */
#define WAIT_FOR(v, op, val) \
{ \
X(v); \
int_fast64_t __r = WAIT_REPEATS; \
int_fast64_t __o = 0; \
do { \
int_fast64_t __l = atomic_load(&v); \
if (__l op val) { \
break; \
}; \
if (__o == __l) { \
__r--; \
} else { \
__r = WAIT_REPEATS; \
} \
__o = __l; \
uv_sleep(T_WAIT); \
} while (__r > 0); \
X(v); \
P(__r); \
assert_true(atomic_load(&v) op val); \
}
#define WAIT_FOR_EQ(v, val) WAIT_FOR(v, ==, val)
#define WAIT_FOR_NE(v, val) WAIT_FOR(v, !=, val)
#define WAIT_FOR_LE(v, val) WAIT_FOR(v, <=, val)
#define WAIT_FOR_LT(v, val) WAIT_FOR(v, <, val)
#define WAIT_FOR_GE(v, val) WAIT_FOR(v, >=, val)
#define WAIT_FOR_GT(v, val) WAIT_FOR(v, >, val)
#define DONE() atomic_store(&do_send, false);
#define CHECK_RANGE_FULL(v) \
{ \
int __v = atomic_load(&v); \
assert_true(__v > 1); \
}
#define CHECK_RANGE_HALF(v) \
{ \
int __v = atomic_load(&v); \
assert_true(__v > 1); \
}
/* Enable this to print values while running tests */
#undef PRINT_DEBUG
#ifdef PRINT_DEBUG
#define X(v) \
fprintf(stderr, "%s:%s:%d:%s = %" PRId64 "\n", __func__, __FILE__, \
__LINE__, #v, atomic_load(&v))
#define P(v) fprintf(stderr, #v " = %" PRId64 "\n", v)
#define F() \
fprintf(stderr, "%u:%s(%p, %s, %p)\n", isc_tid(), __func__, handle, \
isc_result_totext(eresult), cbarg)
#define isc_loopmgr_shutdown(loopmgr) \
{ \
fprintf(stderr, "%u:%s:%s:%d:isc_loopmgr_shutdown(%p)\n", \
isc_tid(), __func__, __FILE__, __LINE__, loopmgr); \
isc_loopmgr_shutdown(loopmgr); \
}
#else
#define X(v)
#define P(v)
#define F()
#endif
#define atomic_assert_int_eq(val, exp) assert_int_equal(atomic_load(&val), exp)
#define atomic_assert_int_ne(val, exp) \
assert_int_not_equal(atomic_load(&val), exp)
#define atomic_assert_int_le(val, exp) assert_true(atomic_load(&val) <= exp)
#define atomic_assert_int_lt(val, exp) assert_true(atomic_load(&val) > exp)
#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_netmgr_test(void **state);
int
teardown_netmgr_test(void **state ISC_ATTR_UNUSED);
void
noop_recv_cb(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
void *cbarg);
isc_result_t
noop_accept_cb(isc_nmhandle_t *handle ISC_ATTR_UNUSED, isc_result_t result,
void *cbarg ISC_ATTR_UNUSED);
void
connect_send_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg);
void
connect_send(isc_nmhandle_t *handle);
void
connect_read_cb(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *cbarg);
void
connect_connect_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg);
void
connect_success_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg);
void
listen_send_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg);
void
listen_read_cb(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *cbarg);
isc_result_t
listen_accept_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg);
isc_result_t
stream_accept_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg);
void
timeout_retry_cb(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *cbarg);
isc_quota_t *
tcp_listener_init_quota(size_t nthreads);
stream_connect_function
get_stream_connect_function(void);
isc_result_t
stream_listen(isc_nm_accept_cb_t accept_cb, void *accept_cbarg, int backlog,
isc_quota_t *quota, isc_nmsocket_t **sockp);
void
stream_connect(isc_nm_cb_t cb, void *cbarg, unsigned int timeout);
void
set_proxyheader_info(isc_nm_proxyheader_info_t *pi);
isc_nm_proxyheader_info_t *
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
stream_noop(void **state ISC_ATTR_UNUSED);
int
stream_noop_teardown(void **state ISC_ATTR_UNUSED);
int
proxystream_noop_setup(void **state);
int
proxystream_noop_teardown(void **state);
int
proxystreamtls_noop_setup(void **state);
int
proxystreamtls_noop_teardown(void **state);
int
stream_noresponse_setup(void **state ISC_ATTR_UNUSED);
void
stream_noresponse(void **state ISC_ATTR_UNUSED);
int
stream_noresponse_teardown(void **state ISC_ATTR_UNUSED);
int
proxystream_noresponse_setup(void **state);
int
proxystream_noresponse_teardown(void **state);
int
proxystreamtls_noresponse_setup(void **state);
int
proxystreamtls_noresponse_teardown(void **state);
int
stream_timeout_recovery_setup(void **state ISC_ATTR_UNUSED);
void
stream_timeout_recovery(void **state ISC_ATTR_UNUSED);
int
stream_timeout_recovery_teardown(void **state ISC_ATTR_UNUSED);
int
proxystream_timeout_recovery_setup(void **state);
int
proxystream_timeout_recovery_teardown(void **state);
int
proxystreamtls_timeout_recovery_setup(void **state);
int
proxystreamtls_timeout_recovery_teardown(void **state);
int
stream_recv_one_setup(void **state ISC_ATTR_UNUSED);
void
stream_recv_one(void **state ISC_ATTR_UNUSED);
int
stream_recv_one_teardown(void **state ISC_ATTR_UNUSED);
int
proxystream_recv_one_setup(void **state);
int
proxystream_recv_one_teardown(void **state);
int
proxystreamtls_recv_one_setup(void **state);
int
proxystreamtls_recv_one_teardown(void **state);
int
stream_recv_two_setup(void **state ISC_ATTR_UNUSED);
void
stream_recv_two(void **state ISC_ATTR_UNUSED);
int
stream_recv_two_teardown(void **state ISC_ATTR_UNUSED);
int
proxystream_recv_two_setup(void **state);
int
proxystream_recv_two_teardown(void **state);
int
proxystreamtls_recv_two_setup(void **state);
int
proxystreamtls_recv_two_teardown(void **state);
int
stream_recv_send_setup(void **state ISC_ATTR_UNUSED);
void
stream_recv_send(void **state ISC_ATTR_UNUSED);
int
stream_recv_send_teardown(void **state ISC_ATTR_UNUSED);
void
stream_recv_send_connect(void *arg);
int
proxystream_recv_send_setup(void **state);
int
proxystream_recv_send_teardown(void **state);
int
proxystreamtls_recv_send_setup(void **state);
int
proxystreamtls_recv_send_teardown(void **state);
int
stream_shutdownconnect_setup(void **state ISC_ATTR_UNUSED);
void
stream_shutdownconnect(void **state ISC_ATTR_UNUSED);
int
stream_shutdownconnect_teardown(void **state ISC_ATTR_UNUSED);
int
proxystream_shutdownconnect_setup(void **state);
int
proxystream_shutdownconnect_teardown(void **state);
int
proxystreamtls_shutdownconnect_setup(void **state);
int
proxystreamtls_shutdownconnect_teardown(void **state);
int
stream_shutdownread_setup(void **state ISC_ATTR_UNUSED);
void
stream_shutdownread(void **state ISC_ATTR_UNUSED);
int
stream_shutdownread_teardown(void **state ISC_ATTR_UNUSED);
int
proxystream_shutdownread_setup(void **state);
int
proxystream_shutdownread_teardown(void **state);
int
proxystreamtls_shutdownread_setup(void **state);
int
proxystreamtls_shutdownread_teardown(void **state);
void
stop_listening(void *arg ISC_ATTR_UNUSED);
/* UDP */
/* Timeout for soft-timeout tests (0.05 seconds) */
#define UDP_T_SOFT 50
/* Timeouts in miliseconds */
#define UDP_T_INIT 120 * 1000
#define UDP_T_IDLE 120 * 1000
#define UDP_T_KEEPALIVE 120 * 1000
#define UDP_T_ADVERTISED 120 * 1000
#define UDP_T_CONNECT 30 * 1000
int
setup_udp_test(void **state);
int
teardown_udp_test(void **state);
int
udp_noop_setup(void **state);
int
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);
int
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);
int
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);
int
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);
int
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);
int
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);
int
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);
int
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);
int
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);
int
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);