Files
utun2/doc/node_snapshot.md
T

89 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Подписанная запись узла
`TOPO_NODE.timestamp` — версия всей подписанной записи, а не отдельного адреса.
Узел-владелец назначает Unix microseconds, строго больше предыдущей сохранённой
версии. Имя, тип, активность, адреса, метаданные сокетов, REALITY и подпись
заменяются вместе. Timestamp входит в подпись. Групповые пути и подсети
остаются в `TOPO_GROUP_NODE` и не являются частью общей записи узла.
Получатель проверяет подпись до изменения реестра или маршрутов. Более свежая
запись заменяет старую целиком, включая пустые списки адресов. Старые записи
игнорируются; разные подписанные записи с одинаковым timestamp — конфликт.
Повторное BGP-объявление может обновить путь, но не содержимое общей записи.
8-битный `ver` сохраняется как диагностический счётчик; свежесть определяется
только timestamp.
Профиль endpoint в SOCKMETA содержит независимые `mapping` и `inbound`, источник `source`.
ID и время измерения не передаются: последний успешный профиль действует до
явного изменения endpoint или подтверждённого нового результата. Повторная
проверка с тем же результатом не меняет NODEINFO. Все поля SOCKMETA — отдельные байты;
границы списков metadata/адресов/REALITY также входят в каноническую подпись.
Алгоритм и условия неопределённости описаны в `doc/nat_detection.txt`.
`source=ETCP` обозначает результат детектора рабочего endpoint. Одно UDP-наблюдение может дать
адрес `TOPO_ADDR_NAT` при `mapping=UNKNOWN`, `inbound=UNKNOWN`: это NAT-кандидат
для пробного подключения, а не адрес интерфейса или подтверждённый открытый вход.
Общий внешний адрес подтверждает EIM; strict не публикует универсальный NAT-адрес.
Source входит в подпись; SOCKMETA занимает 5 байт. `source=STUN` означает предварительный
EIM? для того же локального IP/netif с неизвестным входом; измерение ETCP приоритетно.
Владелец снимает STUN-оценку после TTL. Внешний адрес тестового порта не публикуется:
NAT-кандидат по-прежнему требует наблюдения рабочего сокета.
Для TCP достаточно одного публичного пира: внешний IP с неизвестным входящим
портом публикуется как `TOPO_ADDR_NAT` с `port=0`, `mapping=UNKNOWN`, `inbound=UNKNOWN`.
NCD пропускает нулевые порты. Непубличный локальный TCP IP сразу означает NAT;
совпавший с наблюдением публичный IP даёт UNCHANGED без подтверждения открытого входа.
Таблица `node_snapshots` хранит полную сериализованную запись без группового
окружения. `node_addresses` остаётся проекцией для поиска и отображения, а не
источником для восстановления подписанной записи. При наличии сохранённого
snapshot загрузка использует его. Локальная публикация сохраняется до рассылки;
ошибка сохранения не разрешает публикацию новой версии.
В проекции адресов сохраняются `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-сведения без подписи (конфиг, приглашение,
начальные адреса). Они могут помочь установить первое соединение, но не
заменяют принятую подписанную запись. По BGP принимаются подписанные записи
с ненулевым timestamp. Формат NODEINFO изменён без обратной совместимости.
После принятия BGP-записи `node_conn_direct_update_node` применяет адреса к
существующему NCD-соединению. Отсутствующее соединение этот вызов не создаёт.
Линки дополняются как при UP, так и до установления соединения; повторная
доставка не создаёт дубликаты UDP/TCP. Работающие линки не закрываются только
из-за смены списка адресов. NCD удерживает ссылку на общую запись, пока
обслуживает соединение, и использует её при восстановлении.
`node_conn_direct_open_node` сверяет переданную запись с реестром/БД. Более
свежая подписанная запись принимается целиком, старая уступает уже известной.
Bootstrap-адреса не перекрывают подписанную запись даже при DOWN.
Конфигурационные подключения UTUN используют один адаптер
`init_client_connections` для старта и reload. Все адреса, TCP и REALITY
передаются NCD; адаптер не создаёт ETCP-линки. Новый набор handles открывается
до освобождения старого; при ошибке старые handles сохраняются. Конфигурация
удерживает один handle на клиента, независимо от количества его адресов.
Включение конфигурационного пира в UTUN-группу выполняет callback NCD UP.
Транспортный UP и наличие callback старого `etcp_connect` больше не включают
соединение в UTUN-группу автоматически. Входящий JOIN остаётся явным запросом
участия. При пересоздании UTUN-группы учитываются её конфигурационные handles.
Удаление клиента отправляет `LEAVE_GROUP` и освобождает удержание UTUN-группы
с обеих сторон. Другие владельцы NCD сохраняют транспорт. Поздние NODEINFO и
WITHDRAW от отсоединённого UTUN-пира игнорируются, чтобы не вернуть его маршруты.
LEAVE ждёт backpressure через queue waiter и временно удерживает собственный
NCD handle. Закрытие транспорта отменяет ожидание; новое участие в группе
делает ожидающий LEAVE устаревшим, и он не отправляется.
Причина удаления пира передаётся явно: только потеря транспорта запускает
recovery каскадных маршрутов. Локальный/удалённый LEAVE и удаление битой
member-записи не должны восстанавливать намеренно закрытое участие.
REALITY использует полное SNI до 255 символов; размер поля в записи узла
согласован с транспортом. Если локального TCP listen-сокета нет, NCD может
создать исходящий TCP-линк с выбором локального адреса операционной системой.