Browse Source

Document compact NAT profiles and stable measurement lifetime

master
evgeny 6 days ago
parent
commit
53c32e5669
  1. 24
      doc/nat_detection.txt
  2. 18
      doc/node_snapshot.md
  3. 2
      src/routing_layer/topo_node_sqlite.h

24
doc/nat_detection.txt

@ -6,15 +6,13 @@
к протоколу, семейству, фактическому локальному IP:port и поколению сокета.
PUBLIC/NAT/PRIVATE/LOCAL — политика конфигурации, а не результат измерения.
source=ETCP означает измерение рабочего endpoint; source=STUN — резервную оценку
по его IP/netif через другой порт. Измеренный ETCP имеет приоритет до истечения TTL.
по его IP/netif через другой порт. Успешный ETCP имеет приоритет до явного сброса endpoint.
Модель: 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.
round/generation: локальные ID раунда и жизненного цикла endpoint; в NODEINFO не входят.
UNCHANGED означает совпадение наблюдаемых и локального адресов на испытанных
направлениях. Оно не доказывает свободный вход. EIM означает одинаковый внешний
@ -75,11 +73,12 @@ facet не превращается в ложный STRICT. Потери, оши
остаются подсказками для попыток, подтверждение связи даёт handshake с нужным ключом.
Один активный раунд на S. Таймаут пробы — max(1 секунда, 4*RTT), не более 3 секунд;
три попытки, бюджет раунда 30 секунд. Повтор после ошибки через 30 секунд или
после появления подходящего транспорта; штатный refresh через 180 секунд.
Срок фактов — 300 секунд. Таймеры владельца используют monotonic timebase;
checked_at не обновляется повторным NODEINFO и не зависит от ответа сервера NTP.
При несогласованных часах получатель использует осторожные попытки, не отказ.
три попытки, бюджет раунда 30 секунд. До первого результата повтор после ошибки
через 30 секунд или после появления подходящего транспорта; штатный refresh через 30 минут.
Успешный профиль не протухает по таймеру. Ошибка перепроверки сохраняет прежний результат
и редкий период; неизвестный inbound при том же mapping/endpoint сохраняет прежний ETCP inbound.
Свойства разных источников не объединяются в один ETCP-профиль. Смена адреса отменяет
старый раунд, сбрасывает профиль и назначает скорую проверку. Таймеры используют monotonic timebase.
TCP и прокси
-------------
@ -114,11 +113,12 @@ owner_key и helper_key имеют разные поля и никогда не
---------------
Профиль публикуется только владельцем в общей подписанной записи NODEINFO.
Списки и их границы входят в подпись; mapping/inbound/evidence/checked_at
Списки и их границы входят в подпись; mapping/inbound/source
сохраняются и загружаются вместе. node_addresses — производная проекция:
nat_mapping, nat_inbound, nat_evidence, nat_checked, address_kind.
nat_mapping, nat_inbound, nat_source, address_kind.
При изменении формата старый кэш адресов пересоздаётся; старый NAT_TYPE не
интерпретируется как новая модель. Подписанные snapshots и записи чата не удаляются.
интерпретируется как новая модель. При сокращении SOCKMETA старые snapshots инвалидируются
с сохранением timestamp; адреса и REALITY остаются bootstrap-сведениями. Записи чата не изменяются.
Общий NAT-адрес рекламируется только после EIM. DEPENDENT не рекламирует
универсальный внешний endpoint. NTP.reachable не управляет рекламой адресов.

18
doc/node_snapshot.md

@ -13,14 +13,14 @@
8-битный `ver` сохраняется как диагностический счётчик; свежесть определяется
только timestamp.
Профиль endpoint в SOCKMETA содержит независимые `mapping` и `inbound`, источник `source`,
`evidence_id` и `checked_at`. Последние относятся к измерению владельца,
а не к версии всего NODEINFO: повтор записи или изменение имени не продлевает
измерение. Новые поля профиля на проводе кодируются явными BE-байтами;
Профиль endpoint в SOCKMETA содержит независимые `mapping` и `inbound`, источник `source`.
ID и время измерения не передаются: последний успешный профиль действует до
явного изменения endpoint или подтверждённого нового результата. Повторная
проверка с тем же результатом не меняет NODEINFO. Все поля SOCKMETA — отдельные байты;
границы списков metadata/адресов/REALITY также входят в каноническую подпись.
Алгоритм и условия неопределённости описаны в `doc/nat_detection.txt`.
`source=ETCP` обозначает измерение рабочего endpoint, `source=STUN` — резервную оценку
по IP/netif с другого порта. Source входит в подпись; SOCKMETA занимает 21 байт.
по IP/netif с другого порта. Source входит в подпись; SOCKMETA занимает 5 байт.
STUN mapped endpoint не публикуется как внешний адрес рабочего сокета.
Таблица `node_snapshots` хранит полную сериализованную запись без группового
@ -29,10 +29,14 @@ STUN mapped endpoint не публикуется как внешний адре
snapshot загрузка использует его. Локальная публикация сохраняется до рассылки;
ошибка сохранения не разрешает публикацию новой версии.
В проекции адресов сохраняются `nat_mapping`, `nat_inbound`, `nat_evidence`,
`nat_checked`, `nat_source`, `address_kind`. Уникальность определяется endpoint и видом адреса,
В проекции адресов сохраняются `nat_mapping`, `nat_inbound`, `nat_source`, `address_kind`.
Уникальность определяется endpoint и видом адреса,
а не отображаемым классом NAT. Старый производный формат пересоздаётся;
bootstrap-загрузка без подписанного snapshot не подтверждает NAT-профиль.
При удалении старых `nat_evidence`/`nat_checked` адреса и REALITY сохраняются для bootstrap,
старые профили сбрасываются, сериализованные snapshots инвалидируются.
Максимальные timestamp snapshots сохраняются, чтобы новая локальная публикация
не откатывала версию даже при коррекции часов. Чат и ключи миграция не изменяет.
Timestamp 0 обозначает bootstrap-сведения без подписи (конфиг, приглашение,
начальные адреса). Они могут помочь установить первое соединение, но не

2
src/routing_layer/topo_node_sqlite.h

@ -25,7 +25,7 @@ uint64_t topo_node_sqlite_snapshot_timestamp(sqlite3* db, uint64_t node_id);
struct TOPO_NODE* topo_node_sqlite_snapshot_load(sqlite3* db, struct TOPO_GROUPS* groups, uint64_t node_id);
/* Персистентная запись адресов узла в node_addresses (источник истины — BGP/topo_group).
* DELETE + INSERT из ni->v4_addrs/v6_addrs; mapping/inbound/evidence из подписанного SOCKMETA. */
* DELETE + INSERT из ni->v4_addrs/v6_addrs; mapping/inbound/source из подписанного SOCKMETA. */
int topo_node_sqlite_addrs_put(sqlite3* db, uint64_t node_id, struct TOPO_NODE* ni);
/* Есть ли у узла запись мембера хотя бы в одной peers_<ch> (реальный мембер с ключами). */

Loading…
Cancel
Save