Files
utun2/doc/ble_join.txt
T

101 lines
9.7 KiB
Plaintext
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.
JOIN нового участника через BLE INVITE
====================================
Назначение
----------
Для двух ещё незнакомых узлов доставка utun:// не даёт транспорта обычному JOIN:
ETCP на BLE требует известный ключ участника. Начальный обмен переносится на
существующую INVITE-характеристику, без временного ETCP_CONN и временного членства.
Обычная передача ссылки и её ACK остаются самостоятельной операцией; получение
ссылки не запускает JOIN. Пользователь запускает тот же chat_sync_join_link.
Разделение ответственности
-------------------------
chat_sync остаётся единственным владельцем состояний JOIN, проверки приглашения,
подписей, записи SQLite, ожидания Merkle, результата UI и отмены. INFO_REQ/RESP,
REQUEST, READY и ERROR используют общие обработчики с обычным ETCP-путём.
BLE-драйвер реализует только ограниченный аутентифицированный транспорт этих
сообщений. Ядро не включает BLE/Qt/JNI и не зависит от адресов платформенного API.
Borrowed provider хранится у instance; unregister отменяет связанные JOIN и waiters
до освобождения драйвера. Все вызовы и события сериализованы в uasync.
Маршрут обмена
-------------
Маршрут содержит подтверждённый X25519-ключ пира и непрозрачный handle сессии.
Для ETCP ключ берётся из аутентифицированного соединения, для BLE — после CCM
и проверки свежего challenge. Ответ направляется по маршруту запроса; отложенный
READY хранит этот маршрут вместе с channel/peer/attempt. По одному node_id ответный
транспорт не выбирается. Клиент принимает ответы только совпадающей попытки и пути.
Если ETCP уже UP, сохраняется обычный путь. Иначе доступный BLE peer используется
для JOIN; при отсутствии BLE применяется прежний NCD/IP. Одновременно одну попытку
по двум транспортам не запускаем. Узел подключения должен совпадать с pubkey ссылки;
получение ссылки от другого nearby-узла само по себе не делает его connection-узлом.
Аутентификация до членства
-------------------------
Каждый пакет bootstrap содержит версию/тип и публичный X25519-ключ отправителя;
AES-128-CCM выполняет штатный secure_channel. Зашифрованное тело содержит отдельный
идентификатор протокола, sender/receiver node_id, случайные nonce обоих участников,
счётчик направления и разрешённое сообщение JOIN. Секреты приглашения не логируются.
Клиент закрепляет ключ connection-узла из принятой ссылки. Сервер проверяет
node_id=derive(X25519); успешный CCM доказывает владение соответствующим private key.
Это аутентификация личности, а не признание ключа членом группы.
HELLO несёт случайный nonce инициатора. Ответ возвращает его и свежий nonce сервера.
INFO_REQ подтверждает оба nonce; каждое следующее сообщение связано с той же парой
и строго возрастающим счётчиком. Старый HELLO не заменяет уже выбранную сессию;
старые пакеты другой сессии/направления, повторы, чужие ключи и посторонние типы
не передаются chat_sync. Одного сохранённого ciphertext недостаточно для нового JOIN.
HELLO повторяется до ответа с периодом не меньше500ms. Замена ещё не доказанного
challenge сохраняет исходный deadline; после завершения новая попытка получает новые nonce.
Зашифрованный CANCEL освобождает другую сторону при ошибке/отмене.
Разрешены только INFO_REQ, INFO_RESP, REQUEST, READY, ERROR. Произвольные сервисы,
CHANNEL_INVITE, серверный add_key, маршрутизация и история через bootstrap не доступны.
Получение INFO_REQ по-прежнему требует зарегистрированный действующий join_key.
Настройка показа входящих ссылок не заменяет проверку права вступления.
Ограничения и владение
---------------------
Одна криптографическая сессия на физический BLE-link, не более BLE_LINKS_MAX.
Очередь bootstrap ограничена четырьмя целыми сообщениями на link. Её backpressure
не создаёт неограниченной очереди; отказ завершает попытку с диагностикой.
DATA сохраняет предел1500; INVITE получает отдельный предел2304, достаточный для
максимального JOIN_INFO_RESP и криптографического envelope. Фрагментация остаётся
единственной, в ble_transport; собственный фрагментатор bootstrap не добавляется.
Сообщения ядра ограничены2048байт, остальные длины проверяются до копирования.
Ожидание открытия/фазы BLE ограничено20s, вся bootstrap-сессия —60s. Повторы и
keepalive не продлевают срок. Закрытие GATT отменяет JOIN и связанные waiters.
Переход к ETCP
-------------
Пока идёт bootstrap, появление записи connection-узла у joiner после INFO_RESP
не включает DATA раньше окончания JOIN. Сервер разрешает повышение после commit
мембера и отправки READY; клиент — после проверки READY. Принятые сообщения INVITE
должны быть отправлены до освобождения удержания. Повышение использует прежний
GATT, но выполняет обычный аутентифицированный handshake ETCP и повторную проверку
known-key. BGP/READY группы следуют существующему контракту. При отмене/таймауте
уже сохранённые и подписанные записи не откатываются.
Проверки
--------
Два настоящих ядра с fake GATT, без IP-пути: незнакомые ключи, доставленная ссылка,
обычный JOIN, сохранённый мембер, повышение и передача ETCP. Обе роли инициатора
GATT, MTU23/517, максимальный профиль, неверный/истёкший ключ, неподходящий pubkey,
повтор/подмена/неверный тип, разрыв и stop на каждой фазе. Отдельно — прежние JOIN
по IP, отложенный READY через Merkle и независимость доставки ссылки от JOIN.
После сборки — физический Linux/SM-A525F с логами обеих сторон: доставка, JOIN,
commit, известный ключ, ETCP UP и групповое согласование.
Результаты 30–31.10.2026
-----------------------
test_ble_etcp: MTU23/517, оба направления GATT, профиль1024 байта, неверный ключ,
повтор после отказа, отмена при занятом GATT, подписанное членство, ETCP и групповое READY — PASS.
test_ble_join: CCM tamper, подмена ключа, reflection/replay, старый handle, новый challenge,
сохранение deadline, whitelist, предел очереди, CANCEL и освобождение ресурсов — PASS.
Linux→SM-A525F23:43:55/01:43:56: INFO_REQ/RESP, REQUEST, READY result=0 через INVITE,
после него BLE ETCP и Merkle; сообщения в обе стороны подтверждены интерфейсом/БД.
Полный прогон ядра229/232: прежние test_call_admission/test_conn_mgr_phases/test_call_headless
падают так же, как до изменения. BlueZ private-bus, transport, desktop BLE и WinRT проверки — PASS.