From a65478edccc71448e5e105f890a536ae8fa948ab Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sat, 18 Jul 2026 11:24:51 +0300 Subject: [PATCH] chatgui: fix duplicate connection on invite when node already connected - chat_core_has_conn: search all connections (pending+ready) by peer_node_id - chat_core_connect_from_invite: skip chat_core_connect_auto if already connected - ca_timeout_cb: close timed-out connection to free socket link slot + cancel remaining timers + ca_cleanup on all-failed --- tools/chatgui/transport/chat_core.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/chatgui/transport/chat_core.c b/tools/chatgui/transport/chat_core.c index 1d2ecd8f..237e7b52 100644 --- a/tools/chatgui/transport/chat_core.c +++ b/tools/chatgui/transport/chat_core.c @@ -582,6 +582,18 @@ int chat_core_load_nodeinfo(uint64_t node_id, uint8_t* buf, size_t buf_size, /* ─── подключение к пиру из invite-ссылки ─── */ +/* проверить, есть ли уже ETCP-подключение к узлу (готовое или pending) */ +static int chat_core_has_conn(uint64_t node_id) { + if (!g_cc.inst || !g_cc.inst->connections) return 0; + struct ll_entry* entry = g_cc.inst->connections->head; + while (entry) { + struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data; + if (ce->conn->peer_node_id == node_id) return 1; + entry = entry->next; + } + return 0; +} + static void connect_result_cb(int result, uint64_t node_id, void* arg) { uint64_t channel_id = arg ? *(uint64_t*)arg : 0; uint8_t data[20]; @@ -636,6 +648,13 @@ void chat_core_connect_from_invite(struct chat_invite* inv) { } } + if (chat_core_has_conn(node_id)) { + DEBUG_INFO(DEBUG_CATEGORY_CONNECTIVITY, "%s: invite node 0x%016llx already connected, reusing", + CC_ID, (unsigned long long)node_id); + connect_result_cb(CC_OK, node_id, &inv->channel_id); + return; + } + DEBUG_INFO(DEBUG_CATEGORY_CONNECTIVITY, "%s: invite saved node=0x%016llx addrs=%d, starting direct connect", CC_ID, (unsigned long long)node_id, inv->addr_count); @@ -700,9 +719,17 @@ static void ca_timeout_cb(void* arg) { st->pending_count--; DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTIVITY, "%s: auto_connect TIMEOUT idx=%d pending=%d/%d peer=0x%016llx", CC_ID, ctx->addr_index, st->pending_count, st->addr_count, (unsigned long long)st->node_id); + if (st->conns[ctx->addr_index]) { + etcp_connection_close(st->conns[ctx->addr_index]); + st->conns[ctx->addr_index] = NULL; + } if (st->pending_count <= 0 && !st->delivered) { st->delivered = 1; + for (int i = 0; i < st->addr_count; i++) { + if (st->timers[i]) { uasync_cancel_timeout(st->inst->ua, st->timers[i]); st->timers[i] = NULL; } + } st->result_cb(CC_ERR_TIMEOUT, st->node_id, st->result_arg); + ca_cleanup(st); } }