fix: утечки памяти в router-сервисах и при shutdown

- conn_mgr_router_recv_handler / md_etcp_recv не освобождали entry (рантайм-утечка на каждое сообщение)
- reality_relay: registry + shutdown hook (отложенный free не отрабатывал при остановке)
- etcp_router: uasync_drain_immediate после destroy (router_close_finalize)
- мелкие callback-списки: activity_cbks, node_cbks, props_cbks/apply_cbks
This commit is contained in:
evgeny committed 2026-09-21 21:55:11 +03:00
1 parent 2f3001458f
commit 8a9d8d0097
7 files changed
+68 -12

No files matched your search

+7 -2
View File
@@ -814,13 +814,17 @@ void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id) {
}
void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (!entry || !entry->dgram || entry->len < ROUTER_SVC_PAYLOAD_OFF + 2) return;
if (!entry || !entry->dgram || entry->len < ROUTER_SVC_PAYLOAD_OFF + 2) {
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); }
return;
}
if (!conn || !conn->instance) {
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "conn_mgr_router_recv: conn=%p", (void*)conn);
queue_dgram_free(entry); queue_entry_free(entry);
return;
}
uint8_t* d = entry->dgram + ROUTER_SVC_PAYLOAD_OFF; size_t len = entry->len - ROUTER_SVC_PAYLOAD_OFF;
if (d[0] != ETCP_RT_ID_CONN_MGR) return;
if (d[0] != ETCP_RT_ID_CONN_MGR) { queue_dgram_free(entry); queue_entry_free(entry); return; }
uint8_t sub = d[1];
/* conn_mgr — per-group: резолвим группу из заголовка доставки, а не instance->conn_mgr */
uint64_t group_id; memcpy(&group_id, entry->dgram + ROUTER_SVC_GROUP_OFF, 8);
@@ -836,6 +840,7 @@ void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry
case CM_SUBCMD_INTERM_SELECTED: if (mgr) cm_handle_interm_selected(mgr, src, d, len); break;
case CM_SUBCMD_DISCONNECT: if (len >= CM_DISCONNECT_SIZE && mgr) cm_handle_disconnect(mgr, ((struct CM_DISCONNECT*)d)->node_id); break;
}
queue_dgram_free(entry); queue_entry_free(entry);
}
int conn_mgr_open(struct UTUN_INSTANCE* inst,
+6 -6
View File
@@ -408,6 +408,11 @@ static void topo_group_destroy(struct TOPO_GROUP* group) {
topo_nodeq_free_group_fields(group->instance->topo_groups, group->local_node);
u_free(group->local_node);
}
/* освободить подписчиков BGP-событий (member_sync и др.) */
while (group->node_cbks) {
struct topo_node_cbk_entry* c = group->node_cbks;
group->node_cbks = c->next; u_free(c);
}
DEBUG_INFO(DEBUG_CATEGORY_SYS, "[GRP_DESTROY] 5 done");
}
@@ -420,13 +425,8 @@ void topo_groups_remove_group(struct TOPO_GROUPS* g, uint64_t group_id) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "remove_group: id=%016llx type=%d ch=%s",
(unsigned long long)group_id, group->group_type, group->channel_id);
/* освободить подписчиков BGP-событий (member_sync и др.), т.к. группа умирает */
struct topo_node_cbk_entry* c = group->node_cbks;
while (c) { struct topo_node_cbk_entry* n = c->next; u_free(c); c = n; }
group->node_cbks = NULL;
queue_remove_data(g->group_list, &group->ll);
topo_group_destroy(group);
topo_group_destroy(group); /* node_cbks освобождаются внутри */
queue_entry_free(&group->ll);
}