Remove obsolete CM disconnect and clarify service ownership

This commit is contained in:
evgeny committed 2026-10-24 16:22:15 +02:00
1 parent e6a812042f
commit 182fb97970
3 files changed
+22 -37

No files matched your search

+17 -9
View File
@@ -48,9 +48,10 @@ typedef void (*conn_mgr_cb_t)(struct CONN_MGR_HANDLE* h,
/* ═══════ lifecycle ═══════ */
/* Создать менеджер группы и его фоновые проверки; NULL при ошибке. */
/* Создать менеджер группы с обоими фоновыми таймерами; NULL с очисткой ресурсов при ошибке. */
struct CONN_MGR* conn_mgr_init(struct TOPO_GROUP* group);
/* Остановить проверки и освободить менеджер. Все клиентские handles закрыть ДО destroy. */
/* Остановить проверки и освободить менеджер вне его callbacks.
* Живые клиентские handles отсоединяются, callbacks отменяются; владельцы закрывают их сами. */
void conn_mgr_destroy(struct CONN_MGR* mgr);
/* Приём управляющего пакета от etcp_router; забирает entry. */
void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry);
@@ -60,9 +61,14 @@ void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry
/**
* Параллельные пробы: DIRECT сразу, REVERSE через 0/500мс, INDIRECT через 0/1000мс от общего старта.
* Посредник используется сразу после проверки; поздний прямой путь заменяет его без повторного UP.
* Возврат 0 — запрос принят, -1 — ошибка запуска. cb обязателен.
* Возврат 0 — запрос принят, -1 — ошибка запуска. cb обязателен, cb_arg заимствован.
* Отсутствующая группа создаётся как CHAT с десятичным channel_id=group_id.
* При отсутствии узла загружает запись из общей SQLite во временный групповой узел;
* отказ запуска очищает приобретённые ссылки. Последний CM-владелец убирает такой
* узел, если у него не появились BGP-пути.
* Ошибка до запуска может возвращаться без callback. В callback h может быть NULL.
* Успешно выданный handle закрывает вызывающий, в том числе после TIMEOUT.
* out_handle необязателен: иначе вызывающий получает handle из callback.
* При ошибке *out_handle=NULL. Успешный handle закрывает вызывающий, в том числе после TIMEOUT.
*/
int conn_mgr_open(struct UTUN_INSTANCE* inst,
uint64_t group_id,
@@ -73,7 +79,9 @@ int conn_mgr_open(struct UTUN_INSTANCE* inst,
/** Закрыть свой handle и отменить его callbacks, в том числе отложенный UP.
* Допустимо из callback (также закрытие другого handle). После close указатель больше не использовать.
* Очистка внутренней записи CM отсоединяет handles, но владельцы всё равно обязаны вызвать close.
* Последний handle освобождает ресурсы CM; чужие NCD-владельцы сохраняют транспорт. */
* Последний handle снимает запись CM; чужие NCD-владельцы сохраняют транспорт.
* Освобождение памяти закрытых объектов выполняют фоновые callbacks/destroy менеджера,
* без новых выделений памяти в close. После destroy отсоединённый handle допускает только close. */
void conn_mgr_close(struct CONN_MGR_HANDLE* h);
/* ═══════ доступ к соединению ═══════ */
@@ -81,13 +89,13 @@ void conn_mgr_close(struct CONN_MGR_HANDLE* h);
/** Заимствованный READY прямой ETCP_CONN; NULL для INDIRECT, ожидания или отсоединённого handle. */
struct ETCP_CONN* conn_mgr_get_conn(struct CONN_MGR_HANDLE* h);
/** Передать e->dgram через маршрутизатор CM. Освобождает entry при ненулевом h;
* буфер dgram отдельно не освобождает. При h==NULL entry остаётся у вызывающего. */
int conn_mgr_send(struct CONN_MGR_HANDLE* h, struct ll_entry* e);
/* Данные сервиса отправляются через etcp_route_send/etcp_router_conn_send с его svc_id.
* CM handle всё это время сохраняет потребность в доставке; политика сервиса задаёт шифрование. */
/* ═══════ мониторинг (вызывается извне) ═══════ */
/** Обновить RTT кандидата-посредника (≤3, сортировка по возрастанию). */
/** Обновить кандидата (≤3, сортировка по RTT, затем node_id); self/0 и RTT=0/FFFF игнорируются.
* При заполнении списка READY-кандидаты вытесняют недоступных независимо от прежнего RTT. */
void conn_mgr_update_best_candidates(struct CONN_MGR* mgr, uint64_t node_id, uint16_t rtt);
/** Запланировать перепроверку путей после изменения маршрутов или READY групповых сессий. */
+5 -21
View File
@@ -642,16 +642,6 @@ struct ETCP_CONN* conn_mgr_get_conn(struct CONN_MGR_HANDLE* h) {
return cm_direct_conn(h->entry->mgr, h->entry->node_id);
}
int conn_mgr_send(struct CONN_MGR_HANDLE* h, struct ll_entry* e) {
if (!h || !e) return -1;
struct CONN_MGR_ENTRY* entry = h->entry;
if (!entry || entry->state != CONN_MGR_STATE_CONNECTED) { queue_entry_free(e); return -1; }
entry->last_traffic_tb = get_time_tb();
struct ETCP_ROUTER_CONN* r = etcp_router_conn_get(entry->mgr->instance, entry->mgr->group->group_id, entry->node_id, ETCP_RT_ID_CONN_MGR);
if (!r) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "conn_mgr: no route to 0x%016llx, dropping %u bytes", (unsigned long long)entry->node_id, (unsigned)e->len); queue_entry_free(e); return -1; }
int ret = etcp_router_conn_send(r, e->dgram, e->len, 0); queue_entry_free(e); return ret;
}
/* Локальные пробы уже созданы DIRECT через NCD. Проверяем все LAN-адреса,
* не дублируя handshake и не создавая отдельные ping-контексты. */
void cm_start_local_scan(struct CONN_MGR_ENTRY* entry) {
@@ -702,6 +692,7 @@ void cm_start_phase_reverse(struct CONN_MGR_ENTRY* entry) {
uint64_t now = get_time_tb();
if (!entry->reverse_started) {
entry->reverse_started = 1; entry->reverse_request_id = ++entry->mgr->next_request_id;
if (!entry->reverse_request_id) entry->reverse_request_id = ++entry->mgr->next_request_id;
entry->reverse_deadline_tb = now + CONN_MGR_CONNECT_REVERSE_TIMEOUT_MS * 10;
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "conn_mgr: REVERSE start peer=%016llx elapsed=%llums",
(unsigned long long)entry->node_id, (unsigned long long)((now - entry->start_tb) / 10));
@@ -718,6 +709,10 @@ void cm_handle_direct_req(uint64_t src, struct CONN_MGR* mgr, const uint8_t* dat
return;
}
struct CM_DIRECT_REQ req; memcpy(&req, data, sizeof(req));
if (!req.request_id || !src || src == mgr->instance->node_id) {
DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "conn_mgr: invalid DIRECT_REQ peer=%016llx request=%u",
(unsigned long long)src, req.request_id); return;
}
struct TOPO_NODE* ni = topo_node_registry_find(mgr->instance->topo_groups, src);
if (!ni) { DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "conn_mgr: REVERSE unknown peer=%016llx", (unsigned long long)src); return; }
struct CONN_MGR_ENTRY* entry = cm_ensure_entry(mgr, src);
@@ -738,12 +733,6 @@ void cm_handle_direct_req(uint64_t src, struct CONN_MGR* mgr, const uint8_t* dat
/* ═══════ disconnect / recv ═══════ */
void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id) {
struct CONN_MGR_ENTRY* entry = cm_find_entry(mgr, node_id); if (!entry) return;
cm_clear_nodeinfo(mgr, node_id); cm_entry_cleanup(entry);
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "conn_mgr: remote disconnect from 0x%016llx", (unsigned long long)node_id);
}
void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (!entry || !entry->dgram || entry->len < ROUTER_SVC_PAYLOAD_OFF + 2) {
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); }
@@ -770,7 +759,6 @@ void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry
if (mgr) { struct CONN_MGR_ENTRY* e = cm_find_entry(mgr, src); if (e && e->state == CONN_MGR_STATE_CONNECTED) e->last_traffic_tb = get_time_tb(); }
switch (sub) {
case CM_SUBCMD_DIRECT_REQ: cm_handle_direct_req(src, mgr, d, len); break;
case CM_SUBCMD_DIRECT_RESP: break;
case CM_SUBCMD_INTERM_EXCHANGE_REQ:
if (len == CM_EXCHANGE_REQ_SIZE) cm_handle_interm_exchange_req(src, mgr, (struct CM_EXCHANGE_REQ*)d);
else DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "conn_mgr: malformed EXCHANGE_REQ peer=%016llx len=%zu", (unsigned long long)src, len);
@@ -778,10 +766,6 @@ void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry
case CM_SUBCMD_INTERM_EXCHANGE_RESP: if (mgr) cm_handle_interm_exchange_resp(mgr, src, d, len); break;
case CM_SUBCMD_INTERM_SELECTED: if (mgr) cm_handle_interm_selected(mgr, src, d, len); break;
case CM_SUBCMD_INTERM_ACK: if (mgr) cm_handle_interm_ack(mgr, src, d, len); break;
case CM_SUBCMD_DISCONNECT:
if (len == CM_DISCONNECT_SIZE && ((struct CM_DISCONNECT*)d)->node_id == src) cm_handle_disconnect(mgr, src);
else DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "conn_mgr: malformed DISCONNECT peer=%016llx len=%zu", (unsigned long long)src, len);
break;
default: DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "conn_mgr: unknown command=%u peer=%016llx", sub, (unsigned long long)src); break;
}
queue_dgram_free(entry); queue_entry_free(entry);
-7
View File
@@ -61,11 +61,9 @@ enum CM_TRY_STATE {
enum {
CM_SUBCMD_DIRECT_REQ = 0x01,
CM_SUBCMD_DIRECT_RESP = 0x02,
CM_SUBCMD_INTERM_EXCHANGE_REQ = 0x03,
CM_SUBCMD_INTERM_EXCHANGE_RESP= 0x04,
CM_SUBCMD_INTERM_SELECTED = 0x05,
CM_SUBCMD_DISCONNECT = 0x06,
CM_SUBCMD_INTERM_ACK = 0x07,
};
@@ -73,19 +71,15 @@ struct CONN_MGR_CANDIDATE { uint64_t node_id; uint16_t rtt; } __attribute__((pac
#pragma pack(push, 1)
struct CM_DIRECT_REQ { uint8_t cmd, subcmd; uint32_t request_id; };
struct CM_DIRECT_RESP { uint8_t cmd, subcmd; uint32_t request_id; uint8_t accepted; };
struct CM_EXCHANGE_REQ { uint8_t cmd, subcmd; uint32_t request_id; uint8_t candidate_count; struct CONN_MGR_CANDIDATE candidates[CONN_MGR_MAX_CANDIDATES]; };
struct CM_EXCHANGE_RESP { uint8_t cmd, subcmd; uint32_t request_id; uint8_t my_count, your_count; struct CONN_MGR_CANDIDATE my_candidates[CONN_MGR_MAX_CANDIDATES], your_candidates[CONN_MGR_MAX_CANDIDATES]; };
struct CM_INTERM_SEL { uint8_t cmd, subcmd; uint32_t request_id; uint8_t count; struct CONN_MGR_CANDIDATE selected[3]; };
struct CM_DISCONNECT { uint8_t cmd, subcmd; uint64_t node_id; };
#pragma pack(pop)
#define CM_DIRECT_REQ_H_SIZE (sizeof(struct CM_DIRECT_REQ))
#define CM_DIRECT_RESP_HDR_SIZE (sizeof(struct CM_DIRECT_RESP))
#define CM_EXCHANGE_REQ_SIZE (sizeof(struct CM_EXCHANGE_REQ))
#define CM_EXCHANGE_RESP_SIZE (sizeof(struct CM_EXCHANGE_RESP))
#define CM_INTERM_SEL_SIZE (sizeof(struct CM_INTERM_SEL))
#define CM_DISCONNECT_SIZE (sizeof(struct CM_DISCONNECT))
/* ═══════ внутренние структуры ═══════ */
@@ -154,7 +148,6 @@ void cm_start_phase_reverse(struct CONN_MGR_ENTRY* entry);
void cm_start_phase_indirect(struct CONN_MGR_ENTRY* entry);
void cm_start_local_scan(struct CONN_MGR_ENTRY* entry);
void cm_handle_direct_req(uint64_t src, struct CONN_MGR* mgr, const uint8_t* data, size_t len);
void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id);
void cm_finalize_indirect(struct CONN_MGR_ENTRY* entry);
void cm_refresh_path(struct CONN_MGR_ENTRY* entry);
void cm_arm_timer(struct CONN_MGR_ENTRY* entry);