etcp: replace connections linked-list with indexed ll_queue, add state/ref_count lifecycle

- Remove ETCP_CONN.next linked-list, UTUN_INSTANCE.connections list/count
- Unified connections in single ll_queue indexed by peer_node_id (0=pending)
- struct conn_queue_entry { peer_node_id, conn* } for uniform queue data
- Connection lifecycle via etcp.c: create→pending, conn_ready→indexed, close→detach+deferred free
- Close split: phase1 detach from external world, phase2 deferred via uasync_call_soon
- etcp_conn_set_peer_node_id: reindex on ID change (WARN)
- etcp_conn_ref_take/free: blocking close until refcount returns to 0
- Remove chat_connections — use unified connections queue directly
- Update all iteration/search patterns across 40 files (src + tests + chatgui)
This commit is contained in:
Evgeny committed 2026-07-15 19:56:47 +03:00
1 parent 6902f5fd95
commit a7ecee01f5
40 files changed
+650 -449

No files matched your search

+27 -22
View File
@@ -106,6 +106,9 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to create networks queue");
return -1;
}
// Initialize connection queue
instance->connections = queue_new(ua, 256, 0, 8, "connections");
if (!instance->connections) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create connections queue"); return -1; }
struct CFG_NETWORK *net = config->networks;
while (net) {
struct ll_entry *entry = queue_entry_new(sizeof(struct NETWORK_ENTRY));
@@ -397,17 +400,17 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
instance->etcp_sockets = NULL;
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[INSTANCE_DESTROY] ETCP sockets cleanup complete");
// Safe cleanup of ETCP connections with NULL pointer checks
struct ETCP_CONN* conn = instance->connections;
while (conn) {
struct ETCP_CONN* next = conn->next;
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[INSTANCE_DESTROY] Closing connection %p", conn);
if (conn) { // Дополнительная проверка на случай поврежденного списка
etcp_connection_close(conn); // Закрыть соединение (с проверкой NULL внутри)
// Cleanup ETCP connections (phase 1 detach + deferred phase 2 via call_soon)
{
struct ll_entry* entry = instance->connections->head;
while (entry) {
struct ll_entry* next = entry->next;
struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data;
if (ce && ce->conn) etcp_connection_close(ce->conn);
entry = next;
}
conn = next;
}
instance->connections = NULL;
queue_free(instance->connections); instance->connections = NULL;
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[INSTANCE_DESTROY] ETCP connections cleanup complete");
struct PING_CONTEXT* p = instance->pending_pings;
@@ -578,7 +581,7 @@ int utun_instance_init(struct UTUN_INSTANCE *instance) {
return -1;
}
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "Connections initialized successfully, count=%d", instance->connections_count);
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "Connections initialized successfully, count=%d", queue_entry_count(instance->connections));
// Initialize control server if configured
if (instance->config->global.control_sock.ss_family != 0) {
@@ -654,16 +657,15 @@ void utun_instance_diagnose_leaks(struct UTUN_INSTANCE *instance, const char *ph
}
// Подсчёт ETCP соединений
struct ETCP_CONN *conn = instance->connections;
while (conn) {
report.etcp_connections_count++;
// Подсчёт линков в соединениях
struct ETCP_LINK *link = conn->links;
while (link) {
report.etcp_links_count++;
link = link->next;
{
struct ll_entry* entry = instance->connections->head;
while (entry) {
struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data;
report.etcp_connections_count++;
struct ETCP_LINK *link = ce->conn->links;
while (link) { report.etcp_links_count++; link = link->next; }
entry = entry->next;
}
conn = conn->next;
}
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[LEAK DIAGNOSIS] Phase: %s", phase);
@@ -788,9 +790,12 @@ struct UTUN_INSTANCE *utun_instance_reload(struct UTUN_INSTANCE *instance, struc
// Clients [client:] and links (link=)
for (struct CFG_CLIENT *nc = new_config->clients; nc; nc = nc->next) {
struct ETCP_CONN *conn = NULL;
for (struct ETCP_CONN *c = instance->connections; c; c = c->next) {
if (strcmp(nc->name, c->name) == 0) {
conn = c; break;
{
struct ll_entry* entry = instance->connections->head;
while (entry) {
struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data;
if (strcmp(nc->name, ce->conn->name) == 0) { conn = ce->conn; break; }
entry = entry->next;
}
}
if (!conn) {