|
|
|
|
@ -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-потоке экземпляра. |
|
|
|
|
|
|
|
|
|
|