From 38447da5e86ace2cade129eae6dc0cb02040df57 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 17 Oct 2026 16:02:01 +0200 Subject: [PATCH] nat: retry partial ingress measurements and keep known-IP anchor replies available --- src/routing_layer/nat_detection.c | 3 +++ tests/test_stun_nat.c | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/routing_layer/nat_detection.c b/src/routing_layer/nat_detection.c index 4384a782..b0e16846 100644 --- a/src/routing_layer/nat_detection.c +++ b/src/routing_layer/nat_detection.c @@ -626,6 +626,7 @@ static void owner_apply(struct nat_socket *state, uint8_t mapping, uint8_t inbou (unsigned long long)state->observer, (unsigned long long)state->helper, state->filter_clean, nat_check_reason_name(partial_reason)); owner_finish(state, NAT_REASON_NONE); state->reason = partial_reason; + if (!profile.inbound && mapping != ADDRESS_MAP_DEPENDENT) state->due = get_time_tb() + NAT_RETRY_TB; } static int owner_run(struct nat_socket *state, uint8_t step) { @@ -1365,6 +1366,8 @@ int nat_detection_ping_allowed(struct NAT_DETECTION *detector, struct ETCP_SOCKE socket->name, (unsigned long long)peer, sockaddr_storage_to_str(source).str); return 0; } + history_load(state); + if (contacted(state, source)) return 1; /* Уже известный IP не может испортить испытание незнакомого входа. */ if (!tag || length != ROUTE_OBSERVE_TAG_SIZE || memcmp(tag, "NAT4UDP!", 8)) return 1; uint64_t group_id = read64(tag + 25), round = read64(tag + 17), owner = peer; if (state->phase && state->group_id == group_id && state->round == round && (state->helper == peer || state->observer == peer)) return 1; diff --git a/tests/test_stun_nat.c b/tests/test_stun_nat.c index 96764ab4..812ef74f 100644 --- a/tests/test_stun_nat.c +++ b/tests/test_stun_nat.c @@ -391,7 +391,10 @@ static void test_fallback(void) { assert(socket->address_profile.source == ADDRESS_SOURCE_NONE && !socket->address_profile.mapping && !socket->address_profile.inbound); assert(!memcmp(&socket->address_profile, &duplicate->address_profile, sizeof(socket->address_profile))); assert(!socket->nat_addr.ss_family && !duplicate->nat_addr.ss_family); - struct nat_check_status status; assert(!nat_detection_get_status(owner->nat_det, socket, &status)); + struct nat_check_status status; + end = get_time_tb() + 30000; + do { test_clock_poll(nf.ua, 1000); assert(!nat_detection_get_status(owner->nat_det, socket, &status)); } + while (get_time_tb() < end && status.reason != NAT_REASON_NO_OBSERVER); assert(status.reason == NAT_REASON_NO_OBSERVER); struct TOPO_NODE* snapshot = topo_node_registry_find(owner->topo_groups, owner->node_id); assert(snapshot && !topo_node_verify(snapshot));