fix: memory pool alloc mismatch in tests, db_sync SEND_DATA buffer overflow

- test_etcp_router_reconnect, test_etcp_connect, test_stcp_traffic:
  replace u_calloc with memory_pool_alloc for TOPO_SOCKMETA4/TOPO_ADDR4
- db_sync.c: fix req[14] -> req[15] — SEND_DATA request header is 15 bytes
  (type:1 + from:4 + count:2 + vp:4 + want_from:4)
This commit is contained in:
evgeny committed 2026-07-31 21:44:44 +03:00
1 parent fe9be74e29
commit d310bccf08
52 files changed
+1796 -585

No files matched your search

+56 -44
View File
@@ -18,12 +18,17 @@
void topo_node_ref(struct TOPO_NODE* ni) {
if (!ni) return;
ni->ref_count++;
ni->group_ref_count++;
}
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++;
}
void topo_node_unref(struct TOPO_NODE* ni) {
if (!ni) return;
if (--ni->ref_count == 0) {
if (--ni->group_ref_count == 0) {
u_free(ni->node_name);
u_free(ni);
}
@@ -60,21 +65,25 @@ void topo_node_free_raw(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
u_free(ni);
}
void topo_node_free_lists(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq) {
if (!group || !nq) return;
if (nq->node) {
free_v4_sock_list(group->instance->topo_groups->v4_sock_meta_pool, nq->node->v4_sock_meta);
free_v4_addr_list(group->instance->topo_groups->v4_addr_pool, nq->node->v4_addrs);
free_v6_sock_list(group->instance->topo_groups->v6_sock_meta_pool, nq->node->v6_sock_meta);
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_registry_release(group->instance->topo_groups, nq->node);
nq->node = NULL;
void topo_node_destroy(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
topo_node_free_raw(groups, ni);
}
void topo_nodeq_free_group_fields(struct TOPO_GROUPS* groups, struct TOPO_GROUP_NODE* nq) {
if (!groups || !nq) return;
struct TOPO_NODE* ni = topo_node_registry_find(groups, nq->node_id);
if (ni) {
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);
ni->v4_sock_meta = NULL; ni->v4_addrs = NULL;
ni->v6_sock_meta = NULL; ni->v6_addrs = NULL;
topo_node_registry_unref(groups, nq->node_id);
}
if (nq->subnets) {
free_v4_sub_list(group->instance->topo_groups->v4_subnet_pool, nq->subnets->v4_subnets);
free_v6_sub_list(group->instance->topo_groups->v6_subnet_pool, nq->subnets->v6_subnets);
free_v4_sub_list(groups->v4_subnet_pool, nq->subnets->v4_subnets);
free_v6_sub_list(groups->v6_subnet_pool, nq->subnets->v6_subnets);
u_free(nq->subnets);
nq->subnets = NULL;
}
@@ -84,7 +93,7 @@ void topo_node_free_lists(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq) {
// ===== глобальный реестр TOPO_NODE =====
static struct TOPO_NODE* node_registry_find(struct TOPO_GROUPS* groups, uint64_t node_id) {
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);
if (!e) return NULL;
@@ -93,9 +102,9 @@ static struct TOPO_NODE* node_registry_find(struct TOPO_GROUPS* groups, uint64_t
return node;
}
struct TOPO_NODE* topo_node_registry_acquire(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
struct TOPO_NODE* topo_node_registry_store(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
if (!groups || !ni) return NULL;
struct TOPO_NODE* existing = node_registry_find(groups, ni->node_id);
struct TOPO_NODE* existing = topo_node_registry_find(groups, ni->node_id);
if (existing) {
topo_node_ref(existing);
topo_node_free_raw(groups, ni);
@@ -113,10 +122,11 @@ struct TOPO_NODE* topo_node_registry_acquire(struct TOPO_GROUPS* groups, struct
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;
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);
if (!ni) return;
uint32_t prev_ref = ni->group_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;
@@ -139,9 +149,8 @@ int topo_node_dyn_size(const struct TOPOMSG_NODE* msg) {
+ msg->hop_count * 8;
}
int topo_node_serialize(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq, uint8_t* out, size_t out_max, uint16_t cumulative_rtt) {
if (!group || !nq || !nq->node || !out) return -1;
struct TOPO_NODE* ni = nq->node;
int topo_node_serialize(struct TOPO_NODE* ni, struct TOPO_GROUP_NODE* nq, uint8_t* out, size_t out_max, uint16_t cumulative_rtt) {
if (!ni || !nq || !out) return -1;
struct TOPOMSG_NODE msg;
memset(&msg, 0, sizeof(msg));
@@ -224,7 +233,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 = 0;
ni->group_ref_count = 0;
ni->flags = msg->flags;
ni->group_id = msg->group_id;
ni->node_id = msg->node_id;
@@ -316,11 +325,11 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
return 0;
}
struct TOPO_NODEQ* topo_node_find_by_id(struct TOPO_GROUP* group, uint64_t node_id) {
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;
struct ll_entry* e = queue_find_data_by_index(group->nodes, &key);
return e ? (struct TOPO_NODEQ*)e : NULL;
return e ? (struct TOPO_GROUP_NODE*)e : NULL;
}
int topo_node_ping_request_cbk(struct TOPO_GROUPS* groups, uint64_t node_id) {
@@ -329,7 +338,7 @@ int topo_node_ping_request_cbk(struct TOPO_GROUPS* groups, uint64_t node_id) {
struct ll_entry* ge = groups->group_list->head;
while (ge) {
struct TOPO_GROUP* g = (struct TOPO_GROUP*)ge;
struct TOPO_NODEQ* nq = topo_node_find_by_id(g, node_id);
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(g, node_id);
if (nq) {
struct TOPO_CONNECTIVITY* c = &nq->connectivity;
if (c->last_ping_time == 0 || (now - c->last_ping_time) > PING_TTL_TB) {
@@ -354,7 +363,7 @@ void topo_node_ping_update_rtt(struct TOPO_GROUPS* groups, uint64_t node_id, uin
struct ll_entry* ge = groups->group_list->head;
while (ge) {
struct TOPO_GROUP* g = (struct TOPO_GROUP*)ge;
struct TOPO_NODEQ* nq = topo_node_find_by_id(g, node_id);
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(g, node_id);
if (nq) {
nq->connectivity.last_ping_time = now;
if (nq->connectivity.interface_min_rtt == 0 || rtt < nq->connectivity.interface_min_rtt)
@@ -402,8 +411,8 @@ void topo_node_dump_all(struct TOPO_GROUP* group) {
int idx = 0;
struct ll_entry* e = group->nodes->head;
while (e) {
struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
struct TOPO_NODE* ni = nq->node;
struct TOPO_GROUP_NODE* nq = (struct TOPO_GROUP_NODE*)e;
struct TOPO_NODE* ni = topo_node_registry_find(group->instance->topo_groups, nq->node_id);
if (!ni) { e = e->next; continue; }
int is_local = (group->local_node == nq);
const char* name_s = ni->node_name ? ni->node_name : "";
@@ -498,8 +507,8 @@ int topo_node_format_all(struct TOPO_GROUP* group, char* buf, size_t buf_size) {
int idx = 0;
struct ll_entry* e = group->nodes->head;
while (e && (size_t)pos < buf_size) {
struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
struct TOPO_NODE* ni = nq->node;
struct TOPO_GROUP_NODE* nq = (struct TOPO_GROUP_NODE*)e;
struct TOPO_NODE* ni = topo_node_registry_find(group->instance->topo_groups, nq->node_id);
if (!ni) { e = e->next; continue; }
int is_local = (group->local_node == nq);
const char* name_s = ni->node_name ? ni->node_name : "";
@@ -620,9 +629,10 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
}
int changed = 1; uint8_t old_ver = 0;
if (group->local_node && group->local_node->node) {
struct TOPO_NODE* oni = group->local_node->node;
old_ver = oni->ver;
if (group->local_node) {
struct TOPO_NODE* oni = topo_node_registry_find(instance->topo_groups, group->local_node->node_id);
if (oni) {
old_ver = oni->ver;
changed = (vc != (group->local_node->subnets ? topo_list_count((struct _topo_head*)group->local_node->subnets->v4_subnets) : 0))
|| (sock_count != topo_list_count((struct _topo_head*)oni->v4_sock_meta))
|| (addr_count != topo_list_count((struct _topo_head*)oni->v4_addrs))
@@ -643,23 +653,24 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
}
if (group->local_node && group->instance && group->instance->topo_groups)
if (memcmp(oni->ed25519_public_key, group->ed25519_public_key, SC_PUBKEY_SIZE) != 0) changed = 1;
}
}
if (changed) {
if (group->local_node) {
if (instance->rt) route_delete(instance->rt, group->local_node);
topo_node_free_lists(group, group->local_node);
topo_nodeq_free_group_fields(instance->topo_groups, group->local_node);
u_free(group->local_node);
group->local_node = NULL;
}
group->local_node = u_calloc(1, sizeof(struct TOPO_NODEQ));
group->local_node = u_calloc(1, sizeof(struct TOPO_GROUP_NODE));
if (!group->local_node) return -1;
struct TOPO_NODEQ* lq = group->local_node;
struct TOPO_GROUP_NODE* lq = group->local_node;
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 = 0;
ni->group_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;
@@ -670,8 +681,8 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Ed25519 self-sign FAILED for my node=%016llx", (unsigned long long)ni->node_id);
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 = topo_node_registry_acquire(instance->topo_groups, ni);
lq->hash_node_id = ni->node_id;
topo_node_registry_store(instance->topo_groups, ni);
lq->node_id = ni->node_id;
lq->hop_count = 0;
lq->dirty = 1;
lq->last_ver = ni->ver;
@@ -757,7 +768,8 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
if (group->group_type != TOPO_GROUP_TYPE_CHAT && instance->rt && !route_insert(instance->rt, lq))
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "failed to insert local routes");
} else {
group->local_node->last_ver = group->local_node->node->ver;
struct TOPO_NODE* lni = topo_node_registry_find(instance->topo_groups, group->local_node->node_id);
if (lni) group->local_node->last_ver = lni->ver;
}
return vc;
}