You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
7.9 KiB
128 lines
7.9 KiB
/* |
|
* node_conn_direct — общий прямой транспорт к узлу по node_id. |
|
* |
|
* Модуль управляет ETCP-соединениями через непрозрачные handle'ы (NODE_CONN_DIRECT). |
|
* Каждый владелец открывает свой handle; несколько handle разделяют ETCP_CONN. |
|
* close снимает только своё владение. Последний handle закрывает неготовый транспорт |
|
* сразу; для UP начинает CLOSE/KEEP_ALIVE (до 5 s), пир может сохранить соединение. |
|
* |
|
* Кто использует: |
|
* - conn_mgr (Connection Manager) — создаёт handle'ы для DIR/REV/IND-соединений |
|
* - topo_group — владеет транспортом групповой сессии с начала CONNECTING |
|
* - протокол join — временный транспорт до добавления участника |
|
* - любой модуль, кому нужно надёжное ETCP-соединение с конкретным node_id |
|
* |
|
* Переходы UP/DOWN/TIMEOUT/CLOSED доставляются синхронно. Закрытие любого handle |
|
* из callback безопасно. Начальное UP при open готового conn откладывается через uasync_call_soon. |
|
* Все операции — в потоке uasync. NCD не проверяет членство и готовность группы. |
|
*/ |
|
#ifndef NODE_CONN_DIRECT_H |
|
#define NODE_CONN_DIRECT_H |
|
|
|
#include <stdint.h> |
|
|
|
struct UTUN_INSTANCE; |
|
struct ETCP_CONN; |
|
struct TOPO_NODE; |
|
struct ETCP_SOCKET; |
|
|
|
/* ─── Return codes ─── */ |
|
#define NCD_NEW 0 /* создано новое соединение */ |
|
#define NCD_REUSED 1 /* переиспользовано существующее */ |
|
#define NCD_ERR -1 /* ошибка */ |
|
|
|
/* ─── Opaque handle ─── */ |
|
struct NODE_CONN_DIRECT; |
|
|
|
/* ─── Callback events (единый callback на handle) ─── */ |
|
enum ncd_event { |
|
NCD_EVENT_UP = 0, /* соединение поднялось (линки работают) */ |
|
NCD_EVENT_DOWN = 1, /* соединение упало */ |
|
NCD_EVENT_CLOSED = 3, /* транспорт окончательно удалён; get_conn=NULL, владелец закрывает handle */ |
|
NCD_EVENT_TIMEOUT = 2, /* срок первой попытки истёк; удерживаемый handle может получить поздний UP */ |
|
}; |
|
|
|
typedef void (*ncd_callback)(struct NODE_CONN_DIRECT* h, enum ncd_event event, void* arg); |
|
|
|
/* |
|
* Открыть handle к узлу по node_id. |
|
* Node info ищется через node_registry, fallback — SQLite. |
|
* cb вызывается при изменении статуса / таймауте. |
|
* Если conn уже готов — cb(NCD_EVENT_UP) через uasync_call_soon (не синхронно). |
|
* До первой отправки дождаться UP. Результат: NCD_NEW/NCD_REUSED или NCD_ERR. |
|
* При успехе вызывающий обязан закрыть *out_handle, в том числе после CLOSED. |
|
*/ |
|
int node_conn_direct_open(struct UTUN_INSTANCE* inst, uint64_t node_id, |
|
ncd_callback cb, void* cb_arg, |
|
struct NODE_CONN_DIRECT** out_handle, |
|
struct ETCP_SOCKET* specific_sock); /* NULL — авто-подбор всех совместимых сокетов для линков */ |
|
|
|
/* |
|
* То же, но с уже загруженным TOPO_NODE (ni не владеем — можно передать временный на стеке). |
|
* ni должен содержать public_key, v4_addrs/v6_addrs для создания линков. |
|
*/ |
|
int node_conn_direct_open_node(struct UTUN_INSTANCE* inst, uint64_t node_id, |
|
ncd_callback cb, void* cb_arg, |
|
struct NODE_CONN_DIRECT** out_handle, |
|
struct TOPO_NODE* ni, /* публичный ключ + адреса пира (не владеем) */ |
|
struct ETCP_SOCKET* specific_sock); /* NULL — авто-подбор */ |
|
|
|
/* Освободить handle и отменить его callbacks; другие владельцы сохраняют транспорт. */ |
|
void node_conn_direct_close(struct NODE_CONN_DIRECT* h); |
|
|
|
/* Применить принятую запись из общего реестра к уже существующему соединению. |
|
* Не создаёт соединение и не приобретает handle. Число новых линков или -1 при ошибке. */ |
|
int node_conn_direct_update_node(struct UTUN_INSTANCE* inst, uint64_t node_id); |
|
|
|
/* Как close, но последний handle закрывает транспорт сразу, без fin_wait. |
|
* При наличии других handle общий транспорт и их callbacks сохраняются. */ |
|
void node_conn_direct_force_close(struct NODE_CONN_DIRECT* h); |
|
|
|
/* Сменить или сбросить (cb=NULL) callback на уже открытом handle. |
|
* Не влияет на refcounting и состояние conn. */ |
|
void node_conn_direct_set_callback(struct NODE_CONN_DIRECT* h, ncd_callback cb, void* cb_arg); |
|
|
|
/* Передать владение handle новому владельцу (смена callback + arg). |
|
* После вызова handle принадлежит new_cb_arg, прежний владелец |
|
* должен забыть указатель. Соединение не трогается. */ |
|
void node_conn_direct_transfer(struct NODE_CONN_DIRECT* h, ncd_callback new_cb, void* new_cb_arg); |
|
|
|
/* Идентификатор узла; 0 для NULL. */ |
|
uint64_t node_conn_direct_node_id(const struct NODE_CONN_DIRECT* h); |
|
|
|
/* Заимствованный транспорт, в том числе до UP; NULL после CLOSED. Не закрывать напрямую. */ |
|
struct ETCP_CONN* node_conn_direct_get_conn(struct NODE_CONN_DIRECT* h); |
|
|
|
/* ─── Протокол CLOSE / KEEP_ALIVE (ETCP_RT_ID_NCD_CONTROL = 0x12) ─── */ |
|
|
|
#define NCD_SUBCMD_CLOSE 0x01 |
|
#define NCD_SUBCMD_KEEP_ALIVE 0x02 |
|
|
|
#pragma pack(push, 1) |
|
struct ncd_control_msg { |
|
uint8_t cmd; /* ETCP_RT_ID_NCD_CONTROL */ |
|
uint8_t subcmd; /* NCD_SUBCMD_CLOSE / KEEP_ALIVE */ |
|
uint64_t node_id; /* node_id отправителя */ |
|
}; |
|
#pragma pack(pop) |
|
|
|
#define NCD_CONTROL_MSG_SIZE sizeof(struct ncd_control_msg) |
|
|
|
/* ─── Управление линками на конкретном сокете ─── */ |
|
/* |
|
* ncd_add_socket_links — итерирует все активные NCD-соединения (ncd_registry), |
|
* для каждого загружает TOPO_NODE с адресами пира и создаёт линки (etcp_link_new) |
|
* на переданном сокете (только совместимые family: v4/v6). Аналог ncd_create_links |
|
* но вызывается извне (auto_socket) при добавлении нового интерфейса. |
|
* Возвращает количество созданных линков (0 если нечего добавить или ошибка). |
|
*/ |
|
int ncd_add_socket_links(struct UTUN_INSTANCE* inst, struct ETCP_SOCKET* sock); |
|
|
|
/* |
|
* ncd_remove_socket_links — итерирует все активные NCD-соединения, |
|
* для каждого закрывает линки (etcp_link_close) привязанные к переданному сокету. |
|
* Вызывается при удалении сокета (интерфейс пропал). Возвращает количество закрытых линков. |
|
*/ |
|
int ncd_remove_socket_links(struct UTUN_INSTANCE* inst, struct ETCP_SOCKET* sock); |
|
|
|
#endif
|
|
|