From 5e7eb6290f9c5f55ea2b4641606bddea6a794a05 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sun, 25 Oct 2026 23:52:41 +0100 Subject: [PATCH] Test STUN recheck with an existing and a newly discovered path --- tests/Makefile.am | 2 +- tests/test_stun_nat.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 017de72b..3b45bed1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -586,7 +586,7 @@ endif test_stun_nat_SOURCES = test_stun_nat.c $(test_clock_sources) test_stun_nat_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib test_stun_nat_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS) -test_stun_nat_LDFLAGS = $(test_clock_ldflags) +test_stun_nat_LDFLAGS = $(test_clock_ldflags) -Wl,--wrap=socket_create_udp test_nat_engine_SOURCES = test_nat_engine.c test_nat_engine_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib diff --git a/tests/test_stun_nat.c b/tests/test_stun_nat.c index 69c83364..4ce2456a 100644 --- a/tests/test_stun_nat.c +++ b/tests/test_stun_nat.c @@ -12,6 +12,10 @@ #define COOKIE 0x2112a442u +static unsigned udp_creations; +extern socket_t __real_socket_create_udp(int family); +socket_t __wrap_socket_create_udp(int family) { udp_creations++; return __real_socket_create_udp(family); } + struct fixture; struct endpoint { struct fixture* fixture; @@ -360,6 +364,28 @@ static void test_cache(void) { DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS STUN cache: automatic refresh, preserved age, failed refresh and expiry"); } +/* Recheck одновременно видит старый и новый путь: каждому нужен только один свежий тестовый fd. */ +static void test_recheck_new_path(void) { + struct fixture f = {.mapping = STUN_MAP_EIM, .multiple_clients = 1}; fixture_init(&f); fixture_start(&f, 0, 0, 0); + struct stun_nat_result prior = wait_result(&f), current; + struct ETCP_SOCKET added = extra_socket(&f, "added", "127.0.0.5"); + f.source.next = &added; + unsigned before = udp_creations; + stun_nat_recheck(&f.inst); + assert(udp_creations == before + 2); + current = wait_result(&f); + assert(current.generation != prior.generation && current.evidence_id != prior.evidence_id); + uint64_t deadline = get_time_tb() + 3000000; + do { + assert(!stun_nat_get_socket_result(&f.inst, &added, ¤t)); + if (current.status != STUN_NAT_PENDING) break; + test_clock_poll(f.ua, 10000); + } while (get_time_tb() < deadline); + assert(current.mapping == STUN_MAP_MATCH); + f.source.next = NULL; socket_close_wrapper(added.fd); fixture_destroy(&f); + DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS STUN recheck creates one fresh probe per existing/new path"); +} + static void wait_source(struct nat_fixture* nf, struct ETCP_SOCKET* socket, uint8_t source) { uint64_t end = get_time_tb() + 3000000; while (get_time_tb() < end) { @@ -486,6 +512,7 @@ int main(void) { test_config(); test_groups(); test_cache(); + test_recheck_new_path(); struct fixture ordinary = { .mapping = STUN_MAP_EIM }; run_case("ordinary equal", &ordinary, STUN_MAP_MATCH, STUN_FILTER_UNKNOWN); struct fixture dependent = { .mapping = STUN_MAP_ADM };