From b85205850170972194580071b50cff916f7e3a98 Mon Sep 17 00:00:00 2001 From: evgeny Date: Mon, 12 Oct 2026 01:31:29 +0200 Subject: [PATCH] Record validated STUN fallback, sanitizer checks and IPv6 follow-up --- doc/tasks.md | 9 ++++++++- tests/stream_netns/TESTED.md | 19 +++++++++++++++++++ tests/test_stun_nat.c | 6 ++++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/doc/tasks.md b/doc/tasks.md index 03a3dad9..8fa9e4e5 100644 --- a/doc/tasks.md +++ b/doc/tasks.md @@ -4,12 +4,19 @@ ## Текущие задачи -[ ] **STUN: резервное определение типа NAT по IP/netif** — уточнённый план +[+] **STUN IPv4: резервное определение типа NAT по IP/netif** — уточнённый план 12.10.2026 в `doc/nat_detection.txt`. Одна группа и отдельный тестовый UDP-порт на уникальный IP/netif, общий кэш с generation/TTL. При NO_OBSERVER/NO_HELPER применять пригодную оценку STUN с явным source; измеренный ETCP приоритетен. mapped адрес тестового сокета не переносить на рабочий. Проверить дубликаты, переход STUN -> ETCP, различия по портам и жизненный цикл; namespace-стенд. + Реализовано 12.10.2026: группировка, кэш/TTL, история портов через reload, + source в подписанном NODEINFO/SQLite/мониторе и приоритет частичного ETCP. + 145/145 тестов; три ASAN-теста без утечек; реальные cone/restricted/dependent + NAT и переключение STUN -> ETCP прошли в изолированном стенде. + +[ ] **STUN IPv6** — отдельный этап: IPv6 endpoint/config/DNS и XOR-MAPPED, + scope/netif, тесты IPv6/NAT66. IPv4-оценки не переносить на IPv6 или TCP. [ ] **check.sh: изоляция сетевых integration-тестов** — после основного набора автоматически запускает check-proxy/burst/load при доступном sudo. Скрипты diff --git a/tests/stream_netns/TESTED.md b/tests/stream_netns/TESTED.md index eb5330a7..8059d422 100644 --- a/tests/stream_netns/TESTED.md +++ b/tests/stream_netns/TESTED.md @@ -1,5 +1,24 @@ # Проверки 2026-10-11 +Дополнение 2026-10-12: резервный STUN по IP/netif. +`python3 tests/stream_netns/run.py --stun-only --output /tmp/stun-interface-netns-01` — PASS. +Настоящие RFC5780-серверы, отдельный тестовый порт и две рабочие подписанные записи одного IP/netif: +n03 STUN EIM/OPEN -> ETCP EIM/OPEN; +n14 STUN EIM/CONTACT_REQUIRED -> ETCP EIM/CONTACT_REQUIRED; +n05 STUN DEPENDENT/CONTACT_REQUIRED -> ETCP DEPENDENT/UNKNOWN. +Без пиров и с одним наблюдателем выбирается STUN; независимый помощник позволяет выбрать ETCP. +Mapped порт пробы не рекламируется для рабочего сокета. Главный namespace не изменён; +`/tmp/stun-interface-netns-01/host-check.json`, `stun-result.json`, `result.json`. + +Финальные проверки после исправления порядка остановки и сохранения истории портов при reload: +`make -C tests check -j4` — 145 passed, 0 failed, 0 skipped (`/tmp/stun-fallback-final-check.log`). +В отдельной ASAN-сборке `test_stun_nat`, `test_nat_detection`, `test_route_ping` +прошли с `detect_leaks=1:halt_on_error=1`: ошибок памяти/утечек нет +(`/tmp/stun-fallback-asan-test_stun_nat.log`, `/tmp/stun-fallback-asan-test_nat_detection.log`, +`/tmp/stun-fallback-asan-test_route_ping.log`). Проверены группировка, TTL/refresh, +удаление представителя, reload, подпись/SQLite source, приоритет частичного ETCP и cleanup. +Пять проверок изоляции прошли. IPv6 STUN остаётся отдельным этапом. + Стенд: 16 процессов uTun, 10 NAT-клиентов, 3 страны. Основной network namespace не изменился во всех перечисленных запусках. Результаты прежних стриминговых прогонов ниже подтверждали сетевые правила шлюзов diff --git a/tests/test_stun_nat.c b/tests/test_stun_nat.c index 186d4709..f997e9cb 100644 --- a/tests/test_stun_nat.c +++ b/tests/test_stun_nat.c @@ -315,7 +315,8 @@ static void test_groups(void) { duplicate.netif_index = 1; test_clock_run_for(f.ua, 30001); uint64_t end = get_time_tb() + 3000000; do { assert(!stun_nat_get_socket_result(&f.inst, &duplicate, &second)); - if (second.status != STUN_NAT_PENDING) break; test_clock_poll(f.ua, 10000); + if (second.status != STUN_NAT_PENDING) break; + test_clock_poll(f.ua, 10000); } while (get_time_tb() < end); assert(second.key.netif_index == 1 && second.evidence_id != first.evidence_id); duplicate.netif_index = 0; @@ -329,7 +330,8 @@ static void test_groups(void) { socket_close_wrapper(duplicate.fd); duplicate = extra_socket(&f, "another-ip", "127.0.0.5"); test_clock_run_for(f.ua, 30001); end = get_time_tb() + 3000000; do { assert(!stun_nat_get_socket_result(&f.inst, &duplicate, &second)); - if (second.status != STUN_NAT_PENDING) break; test_clock_poll(f.ua, 10000); + if (second.status != STUN_NAT_PENDING) break; + test_clock_poll(f.ua, 10000); } while (get_time_tb() < end); assert(!stun_nat_get_socket_result(&f.inst, &f.source, &first)); assert(second.key.address[3] == 5 && first.key.address[3] == 1 && second.evidence_id != first.evidence_id);