Exercise NAT startup rollback and UDP timeout allocation failure
This commit is contained in:
1 parent
a6444725da
commit
857a4cee2f
2 files changed
+63
No files matched your search
@@ -524,6 +524,7 @@ test_nat_detection_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
|
||||
test_nat_detection_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
|
||||
|
||||
if OS_LINUX
|
||||
test_nat_detection_LDFLAGS = -Wl,--wrap=etcp_add_conn_status_cbk -Wl,--wrap=etcp_add_socket_cbk -Wl,--wrap=uasync_set_timeout
|
||||
check_PROGRAMS += test_nat_detection_faults
|
||||
test_nat_detection_faults_SOURCES = test_nat_detection_faults.c $(test_clock_sources)
|
||||
test_nat_detection_faults_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
|
||||
|
||||
@@ -2,6 +2,65 @@
|
||||
* Настоящие ETCP/NCD/PING/STCP, без групповой автосвязности и без подмены времени. */
|
||||
#include "nat_fixture.h"
|
||||
#include "ntp_time.h"
|
||||
#include "transport_layer/etcp_api.h"
|
||||
#include "routing_layer/etcp_router.h"
|
||||
|
||||
#ifdef __linux__
|
||||
static int fail_subscription, fail_nat_timer, fail_ping_timer;
|
||||
|
||||
void __real_etcp_add_conn_status_cbk(struct UTUN_INSTANCE*, etcp_conn_status_fn, void*);
|
||||
void __wrap_etcp_add_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg) {
|
||||
if (fail_subscription != 1) __real_etcp_add_conn_status_cbk(inst, fn, arg);
|
||||
}
|
||||
|
||||
void __real_etcp_add_socket_cbk(struct UTUN_INSTANCE*, etcp_socket_cbk_fn, void*, int);
|
||||
void __wrap_etcp_add_socket_cbk(struct UTUN_INSTANCE* inst, etcp_socket_cbk_fn fn, void* arg, int events) {
|
||||
if (fail_subscription != 2) __real_etcp_add_socket_cbk(inst, fn, arg, events);
|
||||
}
|
||||
|
||||
void* __real_uasync_set_timeout(struct UASYNC*, int, void*, timeout_callback_t, const char*);
|
||||
void* __wrap_uasync_set_timeout(struct UASYNC* ua, int delay, void* arg, timeout_callback_t fn, const char* name) {
|
||||
if ((fail_nat_timer && !strcmp(name, "nat_detection")) || (fail_ping_timer && !strcmp(name, "ping_timeout"))) return NULL;
|
||||
return __real_uasync_set_timeout(ua, delay, arg, fn, name);
|
||||
}
|
||||
|
||||
static void unexpected_ping(int success, uint16_t rtt, void* arg, uint64_t nonce, const uint8_t* data, size_t size) {
|
||||
(void)success; (void)rtt; (void)nonce; (void)data; (void)size; (*(int*)arg)++;
|
||||
}
|
||||
|
||||
/* Частичный запуск снимает только свои подписки; не принятая проба не оставляет вечного pending. */
|
||||
static void test_start_failures(void) {
|
||||
struct nat_fixture fixture; nat_fixture_init(&fixture);
|
||||
struct UTUN_INSTANCE* inst = nat_fixture_node(&fixture, "127.0.0.2", NULL, NULL);
|
||||
nat_detection_destroy(inst->nat_det); inst->nat_det = NULL;
|
||||
uasync_poll(fixture.ua, 0);
|
||||
struct etcp_status_cbk_entry* connections = inst->conn_status_cbks;
|
||||
struct etcp_socket_cbk_entry* sockets = inst->socket_cbks;
|
||||
size_t allocations = u_get_allocated_count();
|
||||
for (int failure = 1; failure <= 3; failure++) {
|
||||
fail_subscription = failure; fail_nat_timer = failure == 3;
|
||||
assert(!nat_detection_create(inst));
|
||||
fail_subscription = 0; fail_nat_timer = 0;
|
||||
assert(inst->conn_status_cbks == connections && inst->socket_cbks == sockets);
|
||||
assert(!inst->router_bindings.callbacks[ETCP_RT_ID_NAT_DETECTION]);
|
||||
assert(u_get_allocated_count() == allocations);
|
||||
}
|
||||
inst->nat_det = nat_detection_create(inst); assert(inst->nat_det);
|
||||
nat_detection_set_automatic(inst->nat_det, 0);
|
||||
struct ETCP_SOCKET* socket = test_etcp_bound_socket(inst, "udp");
|
||||
struct sockaddr_storage target = socket->local_addr;
|
||||
((struct sockaddr_in*)&target)->sin_port = htons(9);
|
||||
struct PING_CONTEXT* pending = inst->pending_pings;
|
||||
int callbacks = 0; fail_ping_timer = 1;
|
||||
assert(etcp_send_ping_to_socket(inst, socket, inst->my_keys.public_key, &target, 1000,
|
||||
unexpected_ping, &callbacks, NULL, 0, 0) < 0);
|
||||
fail_ping_timer = 0;
|
||||
assert(inst->pending_pings == pending);
|
||||
uasync_poll(fixture.ua, 0); assert(!callbacks);
|
||||
nat_fixture_cleanup(&fixture);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS NAT partial startup rollback: two subscriptions, timer; failed UDP probe leaves no pending");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void wait_profile(struct nat_fixture *fixture, struct ETCP_SOCKET *socket, uint8_t mapping, uint8_t inbound) {
|
||||
uint64_t end = get_time_tb() + 180000;
|
||||
@@ -255,6 +314,9 @@ static void test_all_groups_tcp(void) {
|
||||
int main(void) {
|
||||
debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN); debug_set_category_level(DEBUG_CATEGORY_NAT, DEBUG_LEVEL_DEBUG);
|
||||
if (getenv("UTUN_TEST_DEBUG")) debug_set_category_level(DEBUG_CATEGORY_BGP, DEBUG_LEVEL_DEBUG);
|
||||
#ifdef __linux__
|
||||
test_start_failures();
|
||||
#endif
|
||||
struct nat_fixture fixture; nat_fixture_init(&fixture);
|
||||
struct SC_MYKEYS first, second;
|
||||
assert(sc_generate_keypair(&first) == SC_OK && sc_generate_keypair(&second) == SC_OK);
|
||||
|
||||
Reference in new issue
Block a user