Добавлен group_id в etcp_router и topo_group, удалён msg_transport

- etcp_router: SVC_ROUTE_HDR (+8B), ETCP_ROUTER_CONN/TRANSIT_QUEUE хеши расширены под group_id
- Все caller'ы (proxy, routing, conn_mgr, nat, chatgui, tests) обновлены
- topo_group: глобальный реестр TOPO_NODE по node_id, ref_count=0 при создании
- BGP-обмен активируется для всех групп (а не только дефолтной)
- Протокол: group_id добавлен в WITHDRAW/TABLE_REQ/TABLE_COMPLETE/ERR_GROUP_MISMATCH
- Per-connection коллбэки заменены на instance-level conn_status
- msg_transport полностью удалён из проекта
57/57 тестов
This commit is contained in:
Evgeny committed 2026-07-22 15:51:03 +03:00
1 parent 5265783164
commit 852ce401e7
37 files changed
+375 -1125

No files matched your search

+65 -13
View File
@@ -48,6 +48,18 @@ 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; }
}
void topo_node_free_raw(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
if (!ni) return;
if (groups) {
free_v4_sock_list(groups->v4_sock_meta_pool, ni->v4_sock_meta);
free_v4_addr_list(groups->v4_addr_pool, ni->v4_addrs);
free_v6_sock_list(groups->v6_sock_meta_pool, ni->v6_sock_meta);
free_v6_addr_list(groups->v6_addr_pool, ni->v6_addrs);
}
u_free(ni->node_name);
u_free(ni);
}
void topo_node_free_lists(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq) {
if (!group || !nq) return;
if (nq->node) {
@@ -57,7 +69,7 @@ void topo_node_free_lists(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq) {
free_v6_addr_list(group->instance->topo_groups->v6_addr_pool, nq->node->v6_addrs);
nq->node->v4_sock_meta = NULL; nq->node->v4_addrs = NULL;
nq->node->v6_sock_meta = NULL; nq->node->v6_addrs = NULL;
topo_node_unref(nq->node);
topo_node_registry_release(group->instance->topo_groups, nq->node);
nq->node = NULL;
}
if (nq->subnets) {
@@ -70,6 +82,46 @@ void topo_node_free_lists(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq) {
u_free(nq->hop_list); nq->hop_list = NULL; nq->hop_count = 0;
}
// ===== глобальный реестр TOPO_NODE =====
static struct TOPO_NODE* 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);
return e ? ((struct TOPO_NODE_REG_ENTRY*)e)->node : NULL;
}
struct TOPO_NODE* topo_node_registry_acquire(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
if (!groups || !ni) return NULL;
struct TOPO_NODE* existing = node_registry_find(groups, ni->node_id);
if (existing) {
topo_node_ref(existing);
topo_node_free_raw(groups, ni);
return existing;
}
struct ll_entry* qe = queue_entry_new(sizeof(struct TOPO_NODE_REG_ENTRY));
if (!qe) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "registry_acquire: queue_entry_new failed for node=%016llx", (unsigned long long)ni->node_id);
return NULL;
}
struct TOPO_NODE_REG_ENTRY* re = (struct TOPO_NODE_REG_ENTRY*)qe;
re->node = ni;
topo_node_ref(ni);
memcpy(re->ll.data, &ni->node_id, 8);
queue_data_put_with_index(groups->node_registry, &re->ll);
return ni;
}
void topo_node_registry_release(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
if (!groups || !ni) return;
uint64_t node_id = ni->node_id;
uint32_t prev_ref = ni->ref_count;
topo_node_unref(ni);
if (prev_ref == 1) {
struct ll_entry* e = groups->node_registry ? queue_find_data_by_index(groups->node_registry, &node_id) : NULL;
if (e) { queue_remove_data(groups->node_registry, e); queue_entry_free(e); }
}
}
// ===== serialization =====
int topo_node_dyn_size(const struct TOPOMSG_NODE* msg) {
@@ -167,7 +219,7 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!ni) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc TOPO_NODE failed"); return -1; }
ni->ref_count = 1;
ni->ref_count = 0;
ni->flags = msg->flags;
ni->group_id = msg->group_id;
ni->node_id = msg->node_id;
@@ -186,46 +238,46 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
for (int i = 0; i < msg->local_v4_sockets; i++) {
const struct TOPOMSG_SOCKMETA4* w = (const struct TOPOMSG_SOCKMETA4*)dp; dp += sizeof(*w);
struct TOPO_SOCKMETA4* e = memory_pool_alloc(group->instance->topo_groups->v4_sock_meta_pool);
if (!e) { topo_node_unref(ni); return -1; }
if (!e) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type;
e->next = ni->v4_sock_meta; ni->v4_sock_meta = e;
}
for (int i = 0; i < msg->local_v4_addrs; i++) {
const struct TOPOMSG_ADDR4* w = (const struct TOPOMSG_ADDR4*)dp; dp += sizeof(*w);
struct TOPO_ADDR4* e = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool);
if (!e) { topo_node_unref(ni); return -1; }
if (!e) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
memcpy(e->addr, w->addr, 4); e->port = w->port; e->type = w->type; e->socket_id = w->socket_id; e->protocol = w->protocol;
e->next = ni->v4_addrs; ni->v4_addrs = e;
}
for (int i = 0; i < msg->local_v6_sockets; i++) {
const struct TOPOMSG_SOCKMETA6* w = (const struct TOPOMSG_SOCKMETA6*)dp; dp += sizeof(*w);
struct TOPO_SOCKMETA6* e = memory_pool_alloc(group->instance->topo_groups->v6_sock_meta_pool);
if (!e) { topo_node_unref(ni); return -1; }
if (!e) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type;
e->next = ni->v6_sock_meta; ni->v6_sock_meta = e;
}
for (int i = 0; i < msg->local_v6_addrs; i++) {
const struct TOPOMSG_ADDR6* w = (const struct TOPOMSG_ADDR6*)dp; dp += sizeof(*w);
struct TOPO_ADDR6* e = memory_pool_alloc(group->instance->topo_groups->v6_addr_pool);
if (!e) { topo_node_unref(ni); return -1; }
if (!e) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
memcpy(e->addr, w->addr, 16); e->port = w->port; e->type = w->type; e->socket_id = w->socket_id; e->protocol = w->protocol;
e->next = ni->v6_addrs; ni->v6_addrs = e;
}
if (out_subnets && (msg->flags & TOPO_FLAG_SEND_SUBNETS) && (msg->local_v4_subnets || msg->local_v6_subnets)) {
struct TOPO_NODESUBNETS* r = u_calloc(1, sizeof(struct TOPO_NODESUBNETS));
if (!r) { topo_node_unref(ni); return -1; }
if (!r) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
for (int i = 0; i < msg->local_v4_subnets; i++) {
const struct TOPOMSG_SUBNET4* w = (const struct TOPOMSG_SUBNET4*)dp; dp += sizeof(*w);
struct TOPO_SUBNET4* e = memory_pool_alloc(group->instance->topo_groups->v4_subnet_pool);
if (!e) { u_free(r); topo_node_unref(ni); return -1; }
if (!e) { u_free(r); topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
memcpy(e->addr, w->addr, 4); e->prefix_length = w->prefix_length;
e->next = r->v4_subnets; r->v4_subnets = e;
}
for (int i = 0; i < msg->local_v6_subnets; i++) {
const struct TOPOMSG_SUBNET6* w = (const struct TOPOMSG_SUBNET6*)dp; dp += sizeof(*w);
struct TOPO_SUBNET6* e = memory_pool_alloc(group->instance->topo_groups->v6_subnet_pool);
if (!e) { u_free(r); topo_node_unref(ni); return -1; }
if (!e) { u_free(r); topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
memcpy(e->addr, w->addr, 16); e->prefix_length = w->prefix_length;
e->next = r->v6_subnets; r->v6_subnets = e;
}
@@ -241,14 +293,14 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
if (out_tranzit && msg->tranzit_nodes > 0) {
size_t tsz = msg->tranzit_nodes * sizeof(struct TOPOMSG_TRANZIT);
*out_tranzit = u_malloc(tsz);
if (!*out_tranzit) { topo_node_unref(ni); return -1; }
if (!*out_tranzit) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
memcpy(*out_tranzit, dp, tsz); dp += tsz;
*out_tranzit_count = msg->tranzit_nodes;
}
if (out_hop_list && msg->hop_count > 0) {
size_t hsz = msg->hop_count * 8;
*out_hop_list = u_malloc(hsz);
if (!*out_hop_list) { topo_node_unref(ni); return -1; }
if (!*out_hop_list) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
memcpy(*out_hop_list, dp, hsz); dp += hsz;
*out_hop_count = msg->hop_count;
}
@@ -600,7 +652,7 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!ni) { u_free(lq); group->local_node = NULL; return -1; }
ni->ref_count = 1;
ni->ref_count = 0;
ni->flags = (group->group_type == TOPO_GROUP_TYPE_CHAT) ? 0 : TOPO_FLAG_SEND_SUBNETS;
ni->group_id = group->group_id;
ni->node_id = instance->node_id;
@@ -609,7 +661,7 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
memcpy(ni->ed25519_public_key, group->ed25519_public_key, SC_PUBKEY_SIZE);
if (name_len) { ni->node_name = u_malloc(name_len + 1); if (ni->node_name) { memcpy(ni->node_name, instance->name, name_len); ni->node_name[name_len] = 0; } }
lq->node = ni;
lq->node = topo_node_registry_acquire(instance->topo_groups, ni);
lq->hash_node_id = ni->node_id;
lq->hop_count = 0;
lq->dirty = 1;