Browse Source

Document implemented interface STUN fallback and provenance semantics

master
evgeny 12 hours ago
parent
commit
c19f835334
  1. 14
      doc/nat_detection.txt
  2. 27
      doc/stun_nat.md

14
doc/nat_detection.txt

@ -1,14 +1,17 @@
Детектор свойств endpoint
========================
Владелец рабочего сокета единственный вычисляет и публикует его профиль.
Владелец рабочего сокета единственный выбирает и публикует его профиль.
Помощники возвращают наблюдения и выполняют прямые испытания. Профиль относится
к протоколу, семейству, фактическому локальному IP:port и поколению сокета.
PUBLIC/NAT/PRIVATE/LOCAL — политика конфигурации, а не результат измерения.
source=ETCP означает измерение рабочего endpoint; source=STUN — резервную оценку
по его IP/netif через другой порт. Измеренный ETCP имеет приоритет до истечения TTL.
Модель: src/routing_layer/address_profile.h.
mapping: UNKNOWN, UNCHANGED, EIM, DEPENDENT.
inbound: UNKNOWN, OPEN, CONTACT_REQUIRED.
source: NONE, ETCP, STUN.
evidence_id: случайный 64-битный ID завершённого раунда владельца.
checked_at: время измерения владельца, Unix microseconds.
generation: случайный 64-битный ID жизненного цикла локального endpoint.
@ -144,14 +147,14 @@ tests/stream_netns --nat-only: 16 настоящих uTun с 10 NAT, прове
профилей и точного собственного внешнего адреса. --nat-check включает эту фазу
до обычных JOIN/Merkle/BGP/streaming. Главный network namespace не меняется.
Резервное определение типа NAT через STUN: план 2026-10-12
-------------------------------------------------------
Резервное определение типа NAT через STUN: реализация IPv4 2026-10-12
------------------------------------------------------------------
Уточнение пользователя: STUN группирует рабочие сокеты по одинаковым IP/netif,
создаёт аналогичный UDP-сокет с другим портом и определяет тип NAT для группы.
Когда ETCP не может выполнить проверку из-за нехватки узлов, используется STUN.
Это заменяет прежнее предложение использовать STUN непосредственно на ETCP fd.
Далее описан план; работающая резервная интеграция ещё не реализована.
Резервная схема реализована для native IPv4 UDP. IPv6 остаётся отдельным этапом.
1. Реестр уникальных путей
@ -197,7 +200,8 @@ tests/stream_netns --nat-only: 16 настоящих uTun с 10 NAT, прове
NAT_DETECTION остаётся единственным владельцем эффективного socket profile,
nat_addr и публикации NODEINFO. STUN предоставляет кэш по ключу группы,
уведомляет о завершении/инвалидации; сам не меняет профили рабочих сокетов.
NAT_DETECTION проверяет его готовность/инвалидацию раз в секунду; сам STUN
не меняет профили рабочих сокетов.
Реестр групп не держит указателей на рабочие сокеты: потребитель проверяет
собственные socket generation и актуальную принадлежность группе перед применением.

27
doc/stun_nat.md

@ -1,11 +1,15 @@
# Независимая STUN-диагностика NAT
Модуль `src/transport_layer/stun_nat.c/h` измеряет NAT на сетевых интерфейсах существующих IPv4 UDP-сокетов.
Для каждого исходного сокета создаётся собственный неблокирующий UDP-сокет с тем же локальным IP,
Модуль `src/transport_layer/stun_nat.c/h` измеряет NAT на уникальных путях существующих IPv4 UDP-сокетов.
Ключ группы — семейство, фактический IP и netif; имена и рабочие порты не участвуют.
Для каждой группы создаётся один собственный неблокирующий UDP-сокет с тем же локальным IP,
привязкой к устройству и Linux SO_MARK / FreeBSD FIB. Тестовый порт выбирается случайно из 49152–65535.
Модуль сам регистрирует чтение в uasync, принимает STUN и закрывает свой сокет после измерения.
Исходный ETCP fd, его порт, обработчики, NAT-поля, NODEINFO и существующий `nat_detection` не изменяются.
Результат описывает тестовый порт; поведение NAT на порту ETCP может отличаться.
STUN не меняет исходный ETCP fd, его порт и обработчики. NAT_DETECTION использует его
оценку типа при NO_OBSERVER/NO_HELPER, помечает source=STUN и публикует подписанный профиль.
Действующий результат source=ETCP имеет приоритет, включая частичный. Мapped endpoint
тестового порта не переносится в nat_addr или NODEINFO рабочего сокета.
Поведение NAT на рабочем порту может отличаться; source показывает происхождение оценки.
## Конфигурация
@ -29,11 +33,16 @@ IPv6, SOCKS UDP и `only_local` пропускаются с явным стат
`stun_nat_get_result(instance, "имя исходного сокета", &result)` копирует локальный снимок:
Имя сначала разрешается в текущий рабочий сокет, затем в группу. API ядра
`stun_nat_get_socket_result(instance, socket, &result)` дополнительно проверяет
текущие IP/netif и параметры маршрутизации. Несколько рабочих портов получают общий снимок.
- `local` — тестовый IP:port; `servers[2]` и `mapped[2]` — реальные серверы и наблюдавшиеся внешние адреса;
- `translated`: -1 неизвестно, 0 трансляция не наблюдалась, 1 внешний адрес отличается;
- `mapping`: UNKNOWN, MATCH, DEPENDENT, EIM, ADM, APDM;
- `filtering`: UNKNOWN, EIF, ADF, APDF;
- причины неполного результата, статус, время измерения и обнаруженная поддержка RFC 5780.
- ключ группы, generation, evidence_id, measured_at_us, количество рабочих сокетов и признак refresh.
Обычный STUN даёт MATCH при одинаковых адресах и DEPENDENT при разных. MATCH не доказывает EIM,
а обычные Binding-ответы не позволяют определить filtering. Первоначальный сервер опрашивается повторно:
@ -68,8 +77,14 @@ transaction ID, границы/выравнивание атрибутов, XOR-
Ядро запускает модуль при `utun_core_start`; остановка уничтожает его до сетевых ресурсов и config.
Перезагрузка конфига отменяет старые DNS/таймеры и создаёт новый модуль.
Раз в три секунды выполняется локальная сверка исходных сокетов: новые/изменённые проверяются,
исчезнувшие удаляются. Неизменившиеся сокеты повторно не опрашиваются.
Раз в три секунды выполняется локальная сверка групп: новые/изменённые проверяются,
группа удаляется после исчезновения последнего рабочего сокета. Смена имени/представителя
или удаление дубликата не теряет кэш. Несовпадение mark/FIB/device внутри одного ключа
даёт UNKNOWN с причиной incompatible routing policy.
TTL результата 300 секунд, refresh 180 секунд; неполные/неудачные проверки повторяются через 30 секунд.
Во время штатного refresh доступен прежний результат до TTL; его возраст не обновляется.
Использованные тестовые порты не переиспользуются в течение жизни ядра, включая reload STUN.
История портов освобождается только при окончательном destroy ядра.
`stun_nat_recheck(instance)` явно повторяет измерение на новых портах, в том числе после смены маршрута без смены IP.
Публичные операции выполняются в uasync-потоке экземпляра.

Loading…
Cancel
Save