Specify NCD ownership callbacks matching and fixed little-endian control wire
This commit is contained in:
1 parent
b83a28becc
commit
a353797edb
2 files changed
+42
-16
No files matched your search
@@ -675,7 +675,8 @@ static void ncd_recv_control_handler(struct ETCP_CONN* conn, struct ll_entry* e)
|
||||
struct ncd_control_msg message;
|
||||
memcpy(&message, e->dgram, sizeof(message));
|
||||
const struct ncd_control_msg* msg = &message;
|
||||
uint64_t sender_id = msg->node_id;
|
||||
uint64_t sender_id = 0;
|
||||
for (unsigned i = 0; i < 8; i++) sender_id |= (uint64_t)e->dgram[2 + i] << (8 * i);
|
||||
struct ncd_entry* entry = ncd_registry_find(conn->instance, sender_id);
|
||||
if (!sender_id || sender_id != conn->peer_node_id || (entry && entry->conn != conn)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_NCD, "[ncd] control from wrong transport node=%016llx", (unsigned long long)sender_id);
|
||||
@@ -698,6 +699,7 @@ static void ncd_recv_control_handler(struct ETCP_CONN* conn, struct ll_entry* e)
|
||||
if (!qe) DEBUG_ERROR(DEBUG_CATEGORY_NCD, "[ncd] KEEP_ALIVE allocation failed");
|
||||
else {
|
||||
memcpy(qe->dgram, &resp, sizeof(resp)); qe->len = sizeof(resp);
|
||||
for (unsigned i = 0; i < 8; i++) qe->dgram[2 + i] = (uint8_t)(conn->instance->node_id >> (8 * i));
|
||||
if (etcp_send(conn, qe) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_NCD, "[ncd] KEEP_ALIVE send failed node=%016llx", (unsigned long long)sender_id);
|
||||
queue_dgram_free(qe); queue_entry_free(qe);
|
||||
@@ -933,6 +935,7 @@ static void ncd_handle_close(struct NODE_CONN_DIRECT* h, int force) {
|
||||
if (!e) DEBUG_ERROR(DEBUG_CATEGORY_NCD, "[ncd] CLOSE allocation failed");
|
||||
else {
|
||||
memcpy(e->dgram, &msg, sizeof(msg)); e->len = sizeof(msg);
|
||||
for (unsigned i = 0; i < 8; i++) e->dgram[2 + i] = (uint8_t)(entry->inst->node_id >> (8 * i));
|
||||
if (etcp_send(conn,e) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_NCD, "[ncd] CLOSE send failed"); queue_dgram_free(e); queue_entry_free(e);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Несколько handles делят один ETCP_CONN; close снимает только своё владение.
|
||||
* NCD создаёт и обновляет UDP/STCP-линки, но не проверяет членство и готовность topo-группы.
|
||||
* Для групповой сессии используйте topo_group_peer_open, для звонка/файла и выбора пути — conn_mgr_open.
|
||||
* Все операции — в потоке uasync.
|
||||
* Все операции — в потоке uasync. Диагностика — категория etcp, подробности на debug.
|
||||
*/
|
||||
|
||||
/* Владение транспортом:
|
||||
@@ -12,21 +12,28 @@
|
||||
* Временный handle закрывают либо передают новому владельцу через transfer.
|
||||
* Потребность сервиса в доставке на всё время звонка/файла выражает CONN_MGR_HANDLE (conn_mgr.h).
|
||||
* Последний handle работающего транспорта начинает CLOSE/KEEP_ALIVE (5 с либо срок пробуждения пира);
|
||||
* DOWN-транспорт удаляется по таймауту ETCP.
|
||||
* Закрытие последнего handle до первого UP или после TIMEOUT удаляет транспорт сразу;
|
||||
* ранее работавший DOWN-транспорт остаётся до deadline ETCP.
|
||||
* Переходы UP/DOWN/TIMEOUT/CLOSED доставляются синхронно. Закрытие любого handle
|
||||
* из callback безопасно. Начальное UP при open готового conn откладывается через uasync_call_soon.
|
||||
* Вложенный переход отменяет оставшуюся рассылку прежнего события. После close указатель handle недействителен.
|
||||
* CLOSED отменяет таймеры и отсоединяет conn; handle всё равно закрывает владелец, в том числе после destroy ядра.
|
||||
*/
|
||||
#ifndef NODE_CONN_DIRECT_H
|
||||
#define NODE_CONN_DIRECT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct UTUN_INSTANCE;
|
||||
struct ETCP_CONN;
|
||||
struct TOPO_NODE;
|
||||
struct ETCP_SOCKET;
|
||||
|
||||
// Привязать CLOSE/KEEP_ALIVE при запуске ядра, в том числе без исходящих handles.
|
||||
// Привязать CLOSE/KEEP_ALIVE при запуске ядра, в том числе без исходящих handles; 0 — успех, -1 — ошибка.
|
||||
int node_conn_direct_init(struct UTUN_INSTANCE* inst);
|
||||
|
||||
// Число локальных владельцев конкретного транспорта; внешние ETCP refs сюда не входят.
|
||||
@@ -42,7 +49,8 @@ struct NODE_CONN_DIRECT;
|
||||
|
||||
/* Рабочий ETCP, совместимая исходящая пара либо возможность reverse на наш опубликованный адрес.
|
||||
* Без линков/handles/таймеров/проб. Исходящие пары — тот же обход, что open; reverse — sock_match/публикуемые адреса.
|
||||
* Учитывает IPv6 и исходящий TCP fallback; возможность попытки не доказывает достижимость. */
|
||||
* Учитывает IPv6 и исходящий TCP fallback; 1 — кандидат есть, 0 — нет/ошибка. SQLite не загружает.
|
||||
* Возможность попытки не доказывает достижимость и не подтверждает готовность группы. */
|
||||
int node_conn_direct_compatible(struct UTUN_INSTANCE* inst, uint64_t node_id);
|
||||
|
||||
// ─── Callback events (единый callback на handle) ───
|
||||
@@ -58,10 +66,14 @@ typedef void (*ncd_callback)(struct NODE_CONN_DIRECT* h, enum ncd_event event, v
|
||||
/*
|
||||
* Открыть handle к узлу по node_id.
|
||||
* Node info ищется через node_registry, fallback — SQLite.
|
||||
* cb вызывается при изменении статуса / таймауте.
|
||||
* cb/arg — callback и его контекст (cb=NULL допустим). Новый handle получает события только после возврата open.
|
||||
* Если conn уже готов — cb(NCD_EVENT_UP) через uasync_call_soon (не синхронно).
|
||||
* До первой отправки дождаться UP. Результат: NCD_NEW/NCD_REUSED или NCD_ERR.
|
||||
* При успехе вызывающий обязан закрыть *out_handle, в том числе после CLOSED.
|
||||
* out_handle обязателен; при ошибке *out_handle=NULL, старые handles и FIN_WAIT сохраняются.
|
||||
* Принятый snapshot и уже добавленные линки могут сохраниться при частичной ошибке обновления.
|
||||
* specific_sock=NULL выбирает все разрешённые пары; иначе нужен обычный сокет этого instance.
|
||||
* Явный сокет задаёт локальную политику, но сохраняются проверки family, протокола, target и REALITY.
|
||||
*/
|
||||
int node_conn_direct_open(struct UTUN_INSTANCE* inst, uint64_t node_id,
|
||||
ncd_callback cb, void* cb_arg,
|
||||
@@ -70,7 +82,10 @@ int node_conn_direct_open(struct UTUN_INSTANCE* inst, uint64_t node_id,
|
||||
|
||||
/*
|
||||
* То же, но с уже загруженным TOPO_NODE (ni не владеем — можно передать временный на стеке).
|
||||
* ni должен содержать public_key, v4_addrs/v6_addrs для создания линков.
|
||||
* ni заимствован до возврата; node_id должен совпадать с ни́м и производным public_key.
|
||||
* timestamp>0 требует верной подписи: более свежая запись принимается целиком, старая уступает известной,
|
||||
* одинаковый timestamp с другой подписью отклоняется. timestamp=0 — bootstrap, он не заменяет подписанную запись.
|
||||
* Адреса могут отсутствовать: handle ожидает также входящего подключения. Обход адресов использует отдельную копию.
|
||||
*/
|
||||
int node_conn_direct_open_node(struct UTUN_INSTANCE* inst, uint64_t node_id,
|
||||
ncd_callback cb, void* cb_arg,
|
||||
@@ -82,7 +97,8 @@ int node_conn_direct_open_node(struct UTUN_INSTANCE* inst, uint64_t node_id,
|
||||
void node_conn_direct_close(struct NODE_CONN_DIRECT* h);
|
||||
|
||||
/* Применить принятую запись из общего реестра к уже существующему соединению.
|
||||
* Не создаёт соединение и не приобретает handle. Число новых линков или -1 при ошибке. */
|
||||
* Не создаёт соединение и не приобретает handle. Число новых линков, 0 при отсутствии записи/транспорта, -1 при ошибке.
|
||||
* Добавляет недостающие пары и обновляет TCP/REALITY; работающие линки по исчезнувшим адресам сохраняются. */
|
||||
int node_conn_direct_update_node(struct UTUN_INSTANCE* inst, uint64_t node_id);
|
||||
|
||||
/* Как close, но последний handle закрывает транспорт сразу, без fin_wait.
|
||||
@@ -90,7 +106,8 @@ int node_conn_direct_update_node(struct UTUN_INSTANCE* inst, uint64_t node_id);
|
||||
void node_conn_direct_force_close(struct NODE_CONN_DIRECT* h);
|
||||
|
||||
/* Сменить или сбросить (cb=NULL) callback на уже открытом handle.
|
||||
* Не влияет на refcounting и состояние conn. */
|
||||
* Не влияет на refcounting и состояние conn, не повторяет уже доставленное событие.
|
||||
* Ещё не доставленный начальный UP использует новый callback/arg. */
|
||||
void node_conn_direct_set_callback(struct NODE_CONN_DIRECT* h, ncd_callback cb, void* cb_arg);
|
||||
|
||||
/* Передать владение handle новому владельцу (смена callback + arg).
|
||||
@@ -104,7 +121,7 @@ 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_ID_NCD_CONTROL = 0x12) ───
|
||||
// Прямой ETCP control: ровно 10 байт, cmd=0x12, subcmd, node_id little-endian; sender сверяется с peer транспорта.
|
||||
|
||||
#define NCD_SUBCMD_CLOSE 0x01
|
||||
#define NCD_SUBCMD_KEEP_ALIVE 0x02
|
||||
@@ -113,7 +130,7 @@ struct ETCP_CONN* node_conn_direct_get_conn(struct NODE_CONN_DIRECT* h);
|
||||
struct ncd_control_msg {
|
||||
uint8_t cmd; /* ETCP_ID_NCD_CONTROL */
|
||||
uint8_t subcmd; /* NCD_SUBCMD_CLOSE / KEEP_ALIVE */
|
||||
uint64_t node_id; /* node_id отправителя */
|
||||
uint64_t node_id; /* wire: 8 байт little-endian; не native uint64_t на big-endian платформе */
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -122,18 +139,24 @@ 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 если нечего добавить или ошибка).
|
||||
* кроме FIN_WAIT; загружает TOPO_NODE и добавляет все разрешённые пары на новом сокете.
|
||||
* Использует правила open(NULL): family/UDP/TCP, локальная политика, NAT-профиль, REALITY, IPv6 scope.
|
||||
* sock — обычный зарегистрированный сокет inst, заимствован до возврата; callbacks не должны удалять его.
|
||||
* Возвращает число новых линков, 0 если нечего добавить, -1 при ошибке (частичные добавления сохраняются).
|
||||
*/
|
||||
int ncd_add_socket_links(struct UTUN_INSTANCE* inst, struct ETCP_SOCKET* sock);
|
||||
|
||||
/*
|
||||
* ncd_remove_socket_links — итерирует все активные NCD-соединения,
|
||||
* для каждого закрывает линки (etcp_link_close) привязанные к переданному сокету.
|
||||
* Вызывается при удалении сокета (интерфейс пропал). Возвращает количество закрытых линков.
|
||||
* Вызывается перед удалением сокета; sock заимствован до возврата. Сам сокет не удаляет.
|
||||
* Возвращает число линков, закрытых этим вызовом, или -1 при отказе памяти. NULL inst/sock — 0.
|
||||
* Вложенные callbacks могут закрывать другие handles/линки. Транспорт вне NCD удаляет сам etcp_socket_remove.
|
||||
*/
|
||||
int ncd_remove_socket_links(struct UTUN_INSTANCE* inst, struct ETCP_SOCKET* sock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user