Remove obsolete CM disconnect and clarify service ownership
This commit is contained in:
1 parent
e6a812042f
commit
182fb97970
3 files changed
+22
-37
No files matched your search
@@ -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 групповых сессий. */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user