conn_mgr — Менеджер установки соединений
1. Назначение
Трёхфазный асинхронный менеджер подключения к удалённым нодам. Отвечает за установку ETCP-соединения с выбором оптимального способа:
- DIRECT — прямое INIT-рукопожатие со всеми известными IPv4-адресами цели (с проверкой NAT-совместимости)
- REVERSE — если у нас прямой IP, а цель за NAT: отправляем наши адреса через BGP, цель подключается к нам
- INDIRECT — обмениваемся через BGP списками кандидатов-посредников, выбираем общих по минимальной сумме RTT, трафик идёт через
etcp_router
Также выполняет фоновые задачи: периодический ping всех BGP-нод, поддержание списка лучших посредников, idle-таймаут для неактивных соединений, локальное сканирование сети.
Типы соединений (итоговый результат):
CONN_TYPE_DIRECT (1) — прямое соединение
CONN_TYPE_REVERSE (2) — цель подключилась к нам
CONN_TYPE_INDIRECT (3) — через посредника
2. Как пользоваться
Инициализация
struct CONN_MGR* mgr = conn_mgr_init(instance);
// Регистрирует обработчик в etcp_router для ETCP_RT_ID_CONN_MGR (0x11)
// Запускает фоновые таймеры: bg_ping, candidate_ping
Подключение
static void my_connect_cb(int result, uint64_t node_id, void* arg) {
if (result == CONN_MGR_OK) { /* подключено */ }
else if (result == CONN_MGR_ERR_TIMEOUT) { /* таймаут */ }
else if (result == CONN_MGR_ERR_UNREACHABLE) { /* недостижима */ }
}
conn_mgr_connect_node(mgr, target_node_id, idle_timeout_ms, my_connect_cb, arg);
Отправка данных
struct ll_entry* entry = queue_entry_new(0);
entry->dgram = data; entry->len = len;
conn_mgr_send(mgr, node_id, entry); // entry освобождается внутри
Кандидаты-посредники
Внешний код (обычно route_connectivity) вызывает conn_mgr_update_best_candidates() для заполнения списка лучших посредников (топ-3 по RTT). Список используется фазой INDIRECT.
Нюансы
- Повторный
connect_node для уже подключённой ноды вернёт CONN_MGR_ERR_ALREADY_CONNECTED
- Для ноды в состоянии CONNECTING новый вызов добавит ещё один callback в список ожидания
- Для INDIRECT-соединений
conn_mgr_send использует round-robin по выбранным посредникам
- Пока существует активный ETCP-линк к ноде, немедленно возвращает CONNECTED
3. API
Корневые структуры
| Структура |
Описание |
CONN_MGR |
Корневая структура менеджера. Хранит массив entries[], топ-3 best_candidates, таймеры (bg_ping_timer, candidate_ping_timer), списки reverse_pending/exchange_pending, next_request_id |
CONN_MGR_ENTRY |
Запись о подключении к одной ноде: state, conn_type, idle_timeout_ms, список коллбэков cb_list, массив intermediaries[], состояния local_scan_state/main_connect_state, текущая main.phase |
CONN_MGR_CANDIDATE |
Пара {node_id, rtt} — запись о кандидате-посреднике (packed) |
cm_cb_node |
Узел связного списка коллбэков для асинхронного результата подключения |
cm_reverse_pending |
Запись об ожидании REVERSE-подключения (связный список) |
cm_exchange_pending |
Запись об ожидании INDIRECT-обмена, включает кешированный ответ и таймер probe-повторов |
Жизненный цикл
| Функция |
Описание |
conn_mgr_init(instance) |
Выделяет CONN_MGR, регистрирует ETCP_RT_ID_CONN_MGR в маршрутизаторе, запускает bg_ping и candidate_ping таймеры |
conn_mgr_destroy(mgr) |
Отменяет таймеры, освобождает все entries, exchange_pending, reverse_pending |
Подключение / отключение
| Функция |
Описание |
conn_mgr_connect_node(mgr, id, timeout, cb, arg) |
Запускает 3-фазное подключение. Если уже подключена — сразу callback с OK. Если в процессе — добавляет callback в список |
conn_mgr_disconnect_node(mgr, id) |
Шлёт DISCONNECT пакет, сбрасывает conn_mgr_type в NODEINFO_Q, удаляет entry |
conn_mgr_send(mgr, id, entry) |
Отправляет данные подключённой ноде через etcp_router; для INDIRECT — round-robin по посредникам; обновляет last_traffic_tb |
conn_mgr_set_idle_timeout(mgr, id, ms) |
Устанавливает/снимает idle-таймер для ноды. При неактивности дольше ms — автоотключение |
conn_mgr_get_status(mgr, id, &state, &type) |
Возвращает текущее состояние и тип соединения |
Кандидаты-посредники
| Функция |
Описание |
conn_mgr_update_best_candidates(mgr, id, rtt) |
Вставляет/обновляет кандидата в отсортированном топ-3 по RTT. Худшие кандидаты вытесняются |
Протокольные подкоманды (ETCP_RT_ID_CONN_MGR = 0x11)
| Константа |
Описание |
CONN_MGR_SUBCMD_DIRECT_REQ (0x01) |
Фаза 2: "я за NAT, подключись ко мне" — наши адреса |
CONN_MGR_SUBCMD_DIRECT_RESP (0x02) |
Ответ на DIRECT_REQ (зарезервирован) |
CONN_MGR_SUBCMD_INTERM_EXCHANGE_REQ (0x03) |
Фаза 3 инициатор: наш топ-4 кандидатов |
CONN_MGR_SUBCMD_INTERM_EXCHANGE_RESP (0x04) |
Фаза 3 ответ: свои + чужие кандидаты с RTT с обеих сторон |
CONN_MGR_SUBCMD_INTERM_SELECTED (0x05) |
Фаза 3 финал: выбранные посредники |
CONN_MGR_SUBCMD_DISCONNECT (0x06) |
Уведомление о разрыве |
Пакеты протокола (все packed)
| Структура |
Поля |
CONN_MGR_DIRECT_REQ |
cmd, subcmd, request_id, addr_count + массив адресов {type, ip[4], port, sock_id} |
CONN_MGR_DIRECT_RESP |
cmd, subcmd, request_id, accepted |
CONN_MGR_INTERM_EXCHANGE_REQ |
cmd, subcmd, request_id, candidate_count, candidates[4] |
CONN_MGR_INTERM_EXCHANGE_RESP |
cmd, subcmd, request_id, my_count, your_count, my_candidates[4], your_candidates[4] |
CONN_MGR_INTERM_SELECTED |
cmd, subcmd, request_id, count, selected[3] |
CONN_MGR_DISCONNECT |
cmd, subcmd, node_id |
Коды возврата
| Код |
Значение |
CONN_MGR_OK (0) |
Успех |
CONN_MGR_ERR_NOT_FOUND (-1) |
Нода не найдена в BGP |
CONN_MGR_ERR_NO_ADDRESSES (-2) |
Нет адресов для подключения |
CONN_MGR_ERR_TIMEOUT (-3) |
Таймаут |
CONN_MGR_ERR_UNREACHABLE (-4) |
Недостижима (все фазы) |
CONN_MGR_ERR_ALREADY_CONNECTED (-6) |
Уже подключены |
CONN_MGR_ERR_INTERNAL (-7) |
Внутренняя ошибка |
Ключевые константы
| Константа |
Значение |
Смысл |
CONN_MGR_MAX_CANDIDATES |
3 |
Макс. число лучших посредников в списке |
CONN_MGR_MAX_INTERMEDIARIES |
3 |
Макс. число выбранных посредников для одного соединения |
CONN_MGR_CONNECT_DIRECT_TIMEOUT_MS |
5000 |
Таймаут фазы DIRECT |
CONN_MGR_CONNECT_REVERSE_TIMEOUT_MS |
15000 |
Таймаут фазы REVERSE |
CONN_MGR_INTERM_EXCHANGE_TIMEOUT_MS |
15000 |
Таймаут фазы INDIRECT |
CONN_MGR_CANDIDATE_STALE_TB |
300000 |
Порог устаревания кандидата (~30 сек) |
CONN_MGR_CANDIDATE_PING_TB |
20000 |
Интервал ping кандидатов (~2 сек) |
CONN_MGR_BG_PING_INTERVAL_TB |
1000 |
Интервал фонового ping нод (~100 мс) |
CONN_MGR_BG_PING_CYCLE_MIN_TB |
100000 |
Мин. длительность цикла обхода всех нод (~10 сек) |
CONN_MGR_IDLE_CHECK_INTERVAL_TB |
10000 |
Интервал проверки idle (~1 сек) |
CONN_MGR_LOCAL_SCAN_ATTEMPTS |
3 |
Попыток локального сканирования |