Browse Source

Plan unified STUN and ETCP endpoint measurements

master
evgeny 13 hours ago
parent
commit
37e897d0d2
  1. 76
      doc/nat_detection.txt
  2. 13
      doc/tasks.md

76
doc/nat_detection.txt

@ -143,3 +143,79 @@ test_sock_match: независимость политики от фактов,
tests/stream_netns --nat-only: 16 настоящих uTun с 10 NAT, проверка всех UDP/TCP
профилей и точного собственного внешнего адреса. --nat-check включает эту фазу
до обычных JOIN/Merkle/BGP/streaming. Главный network namespace не меняется.
Объединение со STUN: проект доработки после rebase 2026-10-12
-----------------------------------------------------------
Сейчас stun_nat — дополнительная локальная диагностика другого UDP-порта.
Она возвращает mapped адреса, MATCH/EIM/ADM/APDM и EIF/ADF/APDF, но не меняет
address_profile или NODEINFO. Это корректная граница текущего модуля: общий
интерфейс и одинаковый SO_MARK/FIB не означают одинаковое состояние двух портов.
В ходе rebase тест переведён на address_profile, probe_only исключён из сканирования.
Сборка и полный основной набор из 145 тестов прошли.
Варианты:
1. Оставить независимый порт: показывать STUN рядом с профилем ETCP, с точным
тестовым endpoint и временем. Полезно для диагностики расхождений, но ни
внешний порт, ни классификация не становятся фактами рабочего сокета.
2. Для участия STUN в рабочем профиле использовать фактический ETCP UDP fd.
Рекомендуемый вариант для объединённого детектора; требует доработок ниже.
Владение и алгоритм варианта 2:
- NAT_DETECTION остаётся единственным планировщиком раундов и владельцем
address_profile/nat_addr/публикации. STUN выполняет транзакции и отдаёт
наблюдения; самостоятельно не назначает профиль и не закрывает ETCP fd.
- Каждое наблюдение содержит actual local IP:port, socket ID, generation,
round, endpoint наблюдателя, observed endpoint, monotonic time и причину.
Имя сокета — только метка для человека. Диагностика другого порта хранится
отдельно и не проходит проверку принадлежности рабочему endpoint.
- В прямом UDP read_callback распознавать ответы STUN до ETCP decrypt:
формат/cookie, активная 96-битная транзакция, ожидаемый source, receiving
socket/generation/round. Единственный читатель fd остаётся у транспорта;
STUN не добавляет второго uasync-reader. Отправки проходят общий учёт контактов.
- Раунд выбирает доступные ETCP или настроенные STUN-наблюдатели. Разные
имена серверов не заменяют разные реальные IP. Для обычного STUN нужны
независимые IP; расширенные пробы требуют фактически доступных alternate IP/port.
- До mapping-проб выполнять чистые ingress/CHANGE-пробы, затем наблюдения
на разных назначениях, затем повтор исходного наблюдения. Обе проверки
используют общую историю всех UDP-отправок, а не отдельную STUN history.
Загрязнение теста или отсутствие независимого адреса даёт частичный результат.
- Обычный Binding дополняет наблюдения. MATCH сам по себе не назначает EIM;
стабильное расхождение назначений даёт DEPENDENT. RFC5780 EIM соответствует
EIM либо UNCHANGED при отсутствии трансляции, ADM/APDM — DEPENDENT.
- Положительный чистый ingress может подтвердить OPEN. ADF/APDF сохранять
в диагностике; CONTACT_REQUIRED публиковать после подтверждённого перехода
до/после контакта на неизменном endpoint. Таймаут CHANGE без доказательства
работы альтернативной отправки не отличает фильтрацию от поведения сервера.
- У STUN нет проверки ключа ETCP; FINGERPRINT — CRC, не аутентификация.
Расхождение с действующими аутентифицированными фактами требует повторного
раунда и лога обоих наблюдений, а не перезаписи по принципу «последний ответ».
Таймаут дополнительной проверки не сбрасывает ещё действующий профиль.
- Свежесть проверяется по локальному monotonic времени. checked_at/evidence_id
формирует владелец при применении результата, в единой транзакции публикации.
Смена endpoint/маршрута, generation, закрытие, reload и stop отменяют все пробы.
TCP и SOCKS5 не наследуют native UDP-факты; существующая listener-проверка остаётся.
Порядок реализации: (1) общий контракт наблюдения и жизненного цикла,
(2) STUN-транзакции через рабочий UDP и безопасный demux,
(3) единое расписание/история контактов и применение результатов,
(4) локальные тесты и RFC5780-серверы в существующем изолированном стенде.
Обязательные новые тесты: разные NAT-свойства тестового и рабочего портов;
ETCP DATA/INIT во время STUN; чужие/поздние ID и reused socket generation;
контакт к alternate IP через INIT/ACK/keepalive перед CHANGE; отсутствие RFC5780,
молчаливое игнорирование CHANGE, потери и недоступные альтернативы;
расхождения STUN/ETCP, TTL, reload, смена маршрута без смены IP, shutdown/leaks;
реальные EIM/EIF, EIM/ADF, EIM/APDF, ADM/APDM на netns NAT с RTT/jitter/loss.
В текущей независимой диагностике до объединения остаются ограничения:
source_snapshot обнуляет исходный порт и не сохраняет generation; сканирование
не замечает пересоздание рабочего сокета с тем же именем/IP/настройками;
неизменившийся источник не обновляется без явного recheck; свежий тест исключает
только непосредственно предыдущий порт, а не всю возможную историю NAT этого tuple.
Эти результаты нельзя автоматически использовать как актуальные рабочие факты.
Нормативные протоколы: https://www.rfc-editor.org/rfc/rfc8489 (Binding, transaction ID),
https://www.rfc-editor.org/rfc/rfc5780#section-4.3 (mapping), #section-4.4 (filtering),
#section-4.5 (порядок и зависимость от прежнего состояния). Приведённая схема
владения и согласования результатов — проект интеграции uTun, а не требование RFC.

13
doc/tasks.md

@ -4,6 +4,19 @@
## Текущие задачи
[ ] **STUN: объединённый детектор рабочего endpoint** — план и варианты в
`doc/nat_detection.txt`, раздел после rebase 12.10.2026. Текущий STUN измеряет
другой порт, его результат нельзя переносить в ETCP/NODEINFO. Нужны единый
владелец профиля, STUN через рабочий UDP fd, общая история контактов и отмена
по socket generation. Дополнительно проверить молчаливое игнорирование CHANGE,
повторное использование тестовых портов, давность и смену маршрута без смены IP.
[ ] **check.sh: изоляция сетевых integration-тестов** — после основного набора
автоматически запускает check-proxy/burst/load при доступном sudo. Скрипты
меняют rp_filter, таблицу 100 и iptables главного namespace; cleanup выставляет
rp_filter=1 вместо сохранённого значения. Перенести тесты в отдельный namespace
и проверять неизменность родительской сети, как в tests/stream_netns.
[ ] **Стриминг: реализация по stream.txt** — 10.10.2026:
ТЗ и этапы: doc/stream.txt, разделы 15–16. Основа данных реализована в src/stream:
подписанные FEC-блоки 1300 байт, общий буфер 32 МБ, относительные timestamp-метрики,

Loading…
Cancel
Save