Browse Source

Record validated STUN fallback, sanitizer checks and IPv6 follow-up

master
evgeny 24 hours ago
parent
commit
b852058501
  1. 9
      doc/tasks.md
  2. 19
      tests/stream_netns/TESTED.md
  3. 6
      tests/test_stun_nat.c

9
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. Скрипты

19
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 не изменился во всех перечисленных запусках.
Результаты прежних стриминговых прогонов ниже подтверждали сетевые правила шлюзов

6
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);

Loading…
Cancel
Save