topo: комментарии к функциям topo_node/topo_group
conn_mgr: src node_id вместо conn->peer_node_id, препенд ETCP_RT_ID_CONN_MGR к dgram, bind CONN_MGR после etcp_router_init call: guard CALL_ST_CONNECTING при accept
This commit is contained in:
1 parent
1fce405204
commit
e7fc69bb1d
7 files changed
+95
-19
No files matched your search
@@ -18,16 +18,19 @@
|
||||
#include "../lib/u_async.h"
|
||||
#include "../ntp_time.h"
|
||||
|
||||
/* Инкремент refcount узла: держит TOPO_NODE живым, пока на него ссылаются группы. */
|
||||
void topo_node_ref(struct TOPO_NODE* ni) {
|
||||
if (!ni) return;
|
||||
ni->group_ref_count++;
|
||||
}
|
||||
|
||||
/* Инкремент refcount узла в глобальном реестре по node_id (взял ссылку через реестр). */
|
||||
void topo_node_registry_ref(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
struct TOPO_NODE* ni = topo_node_registry_find(groups, node_id);
|
||||
if (ni) ni->group_ref_count++;
|
||||
}
|
||||
|
||||
/* Декремент refcount; при обнулении освобождает имя узла и сам TOPO_NODE. */
|
||||
void topo_node_unref(struct TOPO_NODE* ni) {
|
||||
if (!ni) return;
|
||||
if (--ni->group_ref_count == 0) {
|
||||
@@ -36,6 +39,7 @@ void topo_node_unref(struct TOPO_NODE* ni) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Освобождают односвязные списки структур узла (sock_meta/адреса/подсети v4,v6) из memory_pool. */
|
||||
static void free_v4_sock_list(struct memory_pool* pool, struct TOPO_SOCKMETA4* head) {
|
||||
while (head) { struct TOPO_SOCKMETA4* next = head->next; memory_pool_free(pool, head); head = next; }
|
||||
}
|
||||
@@ -54,10 +58,12 @@ static void free_v4_sub_list(struct memory_pool* pool, struct TOPO_SUBNET4* head
|
||||
static void free_v6_sub_list(struct memory_pool* pool, struct TOPO_SUBNET6* head) {
|
||||
while (head) { struct TOPO_SUBNET6* next = head->next; memory_pool_free(pool, head); head = next; }
|
||||
}
|
||||
/* Освобождает список reality-сокетов узла (выделялся u_calloc). */
|
||||
static void free_reality_sock_list(struct TOPO_REALITY_SOCK* head) {
|
||||
while (head) { struct TOPO_REALITY_SOCK* next = head->next; u_free(head); head = next; }
|
||||
}
|
||||
|
||||
/* Ищет reality-параметры сокета узла по socket_id (NULL, если сокет без reality). */
|
||||
const struct TOPO_REALITY_SOCK* topo_node_find_reality_sock(const struct TOPO_NODE* ni, uint8_t socket_id) {
|
||||
if (!ni) return NULL;
|
||||
for (const struct TOPO_REALITY_SOCK* r = ni->reality_socks; r; r = r->next)
|
||||
@@ -65,6 +71,7 @@ const struct TOPO_REALITY_SOCK* topo_node_find_reality_sock(const struct TOPO_NO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Копирует reality-параметры узла в link->reality и поднимает флаг reality_set. */
|
||||
void topo_node_apply_reality(struct ETCP_LINK* link, const struct TOPO_REALITY_SOCK* rs) {
|
||||
if (!link || !rs) return;
|
||||
memcpy(link->reality.server_static_pubkey, rs->server_pubkey, REALITY_AUTH_KEY_SIZE);
|
||||
@@ -147,6 +154,7 @@ static void topo_node_identity_free(struct TOPO_GROUPS* groups, struct TOPO_NODE
|
||||
ni->reality_socks = NULL;
|
||||
}
|
||||
|
||||
/* Полностью освобождает TOPO_NODE со всеми списками и именем (без учёта refcount). */
|
||||
void topo_node_free_raw(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
if (!ni) return;
|
||||
if (groups) {
|
||||
@@ -160,10 +168,12 @@ void topo_node_free_raw(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
u_free(ni);
|
||||
}
|
||||
|
||||
/* Публичная обёртка free_raw — уничтожение узла глобального реестра. */
|
||||
void topo_node_destroy(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
topo_node_free_raw(groups, ni);
|
||||
}
|
||||
|
||||
/* Освобождает per-group поля TOPO_GROUP_NODE: unref идентичности в реестре + подсети, сброс handle. */
|
||||
void topo_nodeq_free_group_fields(struct TOPO_GROUPS* groups, struct TOPO_GROUP_NODE* nq) {
|
||||
if (!groups || !nq) return;
|
||||
topo_node_registry_unref(groups, nq->node_id);
|
||||
@@ -178,6 +188,7 @@ void topo_nodeq_free_group_fields(struct TOPO_GROUPS* groups, struct TOPO_GROUP_
|
||||
|
||||
// ===== глобальный реестр TOPO_NODE =====
|
||||
|
||||
/* Ищет TOPO_NODE в глобальном реестре по node_id (NULL, если узла нет). */
|
||||
struct TOPO_NODE* topo_node_registry_find(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
if (!groups || !groups->node_registry) return NULL;
|
||||
struct ll_entry* e = queue_find_data_by_index(groups->node_registry, &node_id);
|
||||
@@ -194,6 +205,7 @@ static int topo_node_is_full_identity(const struct TOPO_NODE* ni) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Кладёт узел в реестр; если он уже есть — обновляет идентичность/адреса и возвращает существующий. */
|
||||
struct TOPO_NODE* topo_node_registry_store(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
if (!groups || !ni) return NULL;
|
||||
struct TOPO_NODE* existing = topo_node_registry_find(groups, ni->node_id);
|
||||
@@ -242,6 +254,7 @@ struct TOPO_NODE* topo_node_registry_store(struct TOPO_GROUPS* groups, struct TO
|
||||
return ni;
|
||||
}
|
||||
|
||||
/* Снимает ссылку группы на узел; при последней — чистит идентичность и удаляет запись из реестра. */
|
||||
void topo_node_registry_unref(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
if (!groups) return;
|
||||
struct TOPO_NODE* ni = topo_node_registry_find(groups, node_id);
|
||||
@@ -258,6 +271,7 @@ void topo_node_registry_unref(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
|
||||
// ===== serialization =====
|
||||
|
||||
/* Собирает канонический буфер для Ed25519-подписи узла (id, ver, pubkey, имя, тип, адреса). */
|
||||
int topo_node_build_sig_msg(struct TOPO_NODE* ni, uint8_t* buf, size_t buf_size) {
|
||||
if (!ni || !buf || buf_size < 64 + 9) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "build_sig_msg: invalid args"); return -1; }
|
||||
size_t off = 0;
|
||||
@@ -311,6 +325,7 @@ int topo_node_build_sig_msg(struct TOPO_NODE* ni, uint8_t* buf, size_t buf_size)
|
||||
return (int)off;
|
||||
}
|
||||
|
||||
/* Подписывает свой узел Ed25519: build_sig_msg + sc_ed25519_sign → ni->x25519_self_sig. */
|
||||
void topo_node_sign_self(struct UTUN_INSTANCE* instance, struct TOPO_NODE* ni) {
|
||||
if (!instance || !ni) return;
|
||||
uint8_t sig_msg[TOPO_SIG_MSG_MAX_SIZE];
|
||||
@@ -319,6 +334,7 @@ void topo_node_sign_self(struct UTUN_INSTANCE* instance, struct TOPO_NODE* ni) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Ed25519 self-sign FAILED for node=%016llx", (unsigned long long)ni->node_id);
|
||||
}
|
||||
|
||||
/* Вычисляет суммарный размер динамической части NODEINFO по счётчикам заголовка. */
|
||||
int topo_node_dyn_size(const struct TOPOMSG_NODE* msg) {
|
||||
return msg->node_name_len
|
||||
+ msg->local_v4_sockets * sizeof(struct TOPOMSG_SOCKMETA4)
|
||||
@@ -332,6 +348,7 @@ int topo_node_dyn_size(const struct TOPOMSG_NODE* msg) {
|
||||
+ msg->hop_count * 8;
|
||||
}
|
||||
|
||||
/* Сериализует узел в wire-формат NODEINFO (заголовок + имя + адреса + подсети + hop_list). */
|
||||
int topo_node_serialize(struct TOPO_NODE* ni, struct TOPO_GROUP_NODE* nq,
|
||||
uint64_t group_id, uint8_t flags,
|
||||
uint8_t* out, size_t out_max, uint16_t cumulative_rtt) {
|
||||
@@ -412,6 +429,7 @@ int topo_node_serialize(struct TOPO_NODE* ni, struct TOPO_GROUP_NODE* nq,
|
||||
|
||||
// ===== deserialization =====
|
||||
|
||||
/* Разбирает wire-формат NODEINFO в TOPO_NODE + подсети/hop_list/cumulative_rtt (память через пулы). */
|
||||
int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t len, struct TOPO_NODE** out_ni, struct TOPO_NODESUBNETS** out_subnets,
|
||||
uint64_t** out_hop_list, uint8_t* out_hop_count,
|
||||
uint16_t* out_cumulative_rtt) {
|
||||
@@ -531,6 +549,7 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ищет per-group узел TOPO_GROUP_NODE в группе по node_id (NULL, если нет). */
|
||||
struct TOPO_GROUP_NODE* topo_node_find_by_id(struct TOPO_GROUP* group, uint64_t node_id) {
|
||||
if (!group || !group->nodes) return NULL;
|
||||
uint64_t key = node_id;
|
||||
@@ -538,6 +557,7 @@ struct TOPO_GROUP_NODE* topo_node_find_by_id(struct TOPO_GROUP* group, uint64_t
|
||||
return e ? (struct TOPO_GROUP_NODE*)e : NULL;
|
||||
}
|
||||
|
||||
/* Решает, нужен ли ping узлу: да, если в любой группе last_ping старше PING_TTL_TB. */
|
||||
int topo_node_ping_request_cbk(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
if (!groups || !groups->group_list) return 0;
|
||||
uint64_t now = get_time_tb();
|
||||
@@ -560,6 +580,7 @@ int topo_node_ping_request_cbk(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Обновляет RTT/last_ping узла во всех группах, пишет RTT в БД и уведомляет подписчиков. */
|
||||
void topo_node_ping_update_rtt(struct TOPO_GROUPS* groups, uint64_t node_id, uint16_t rtt) {
|
||||
if (!groups || !groups->group_list) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "ping_update_rtt: no groups, node=%016llx rtt=%u", (unsigned long long)node_id, (unsigned)rtt);
|
||||
@@ -588,6 +609,7 @@ void topo_node_ping_update_rtt(struct TOPO_GROUPS* groups, uint64_t node_id, uin
|
||||
}
|
||||
}
|
||||
|
||||
/* Суммарный RTT цепочки до узла: минимальный (rtt_last + cumulative_rtt) среди живых путей. */
|
||||
uint16_t topo_get_chain_rtt(struct TOPO_GROUP_NODE* nq) {
|
||||
if (!nq || !nq->paths || !nq->paths->head) {
|
||||
return 0xFFFF;
|
||||
@@ -606,6 +628,7 @@ uint16_t topo_get_chain_rtt(struct TOPO_GROUP_NODE* nq) {
|
||||
|
||||
// ===== dump / format =====
|
||||
|
||||
/* Есть ли у узла непустая диагностика связности (статусы/таймстемпы проб). */
|
||||
static int is_node_connectivity_active(struct TOPO_CONNECTIVITY* c) {
|
||||
return c->probe_status != PROBE_STATUS_NONE
|
||||
|| c->interface_status != PROBE_RESULT_UNKNOWN
|
||||
@@ -616,6 +639,7 @@ static int is_node_connectivity_active(struct TOPO_CONNECTIVITY* c) {
|
||||
|| c->last_ping_time != 0;
|
||||
}
|
||||
|
||||
/* Читаемое имя статуса/результата пробы и типа conn_mgr для дампа. */
|
||||
static const char* probe_status_str(uint8_t s) {
|
||||
switch (s) { case 0: return "NONE"; case 1: return "IN_PROGRESS"; case 2: return "DONE"; default: return "?"; }
|
||||
}
|
||||
@@ -626,6 +650,7 @@ static const char* conn_mgr_type_str(uint8_t t) {
|
||||
switch (t) { case 1: return "DIRECT"; case 2: return "REVERSE"; case 3: return "INDIRECT"; default: return "NONE"; }
|
||||
}
|
||||
|
||||
/* Выводит в лог полный дамп узлов группы (адреса, пути, связность, conn_mgr). */
|
||||
void topo_node_dump_all(struct TOPO_GROUP* group) {
|
||||
if (!group || !group->nodes) return;
|
||||
|
||||
@@ -713,6 +738,7 @@ void topo_node_dump_all(struct TOPO_GROUP* group) {
|
||||
}
|
||||
}
|
||||
|
||||
/* То же, что dump_all, но в строковый буфер (для control-сервера). */
|
||||
int topo_node_format_all(struct TOPO_GROUP* group, char* buf, size_t buf_size) {
|
||||
if (!group || !group->nodes || !buf || buf_size == 0) return 0;
|
||||
int pos = 0;
|
||||
@@ -804,6 +830,7 @@ int topo_node_format_all(struct TOPO_GROUP* group, char* buf, size_t buf_size) {
|
||||
|
||||
// ===== update my nodeinfo =====
|
||||
|
||||
/* Пересоздаёт local_node группы при изменении имени/подсетей/ключей, инкрементируя версию. */
|
||||
int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GROUP* group) {
|
||||
if (!instance || !group) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args"); return -1; }
|
||||
size_t name_len = 0;
|
||||
@@ -897,6 +924,7 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
|
||||
return vc;
|
||||
}
|
||||
|
||||
/* Пересобирает списки адресов своего узла из ETCP-сокетов; при изменении — подпись, БД, рассылка. */
|
||||
int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
if (!instance || !instance->topo_groups) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args"); return -1; }
|
||||
struct TOPO_GROUP* default_group = topo_groups_get_default(instance->topo_groups);
|
||||
@@ -1065,6 +1093,7 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
return changed ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Callback изменения сокета (адрес/статус) — инициирует пересборку адресов своего узла. */
|
||||
void topo_node_on_socket_changed(struct ETCP_SOCKET* sock, int event, void* arg) {
|
||||
(void)arg;
|
||||
if (!sock || !sock->instance) return;
|
||||
|
||||
Reference in new issue
Block a user