From 3c036ecc4ca3bda620defa4058e66c56e2688b88 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 4 Jun 2026 00:44:51 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20restore=20conn=5Ffree=20cleanup=20?= =?UTF-8?q?=E2=80=94=20tcp=5Fconn=5Fdestroy,=20timers,=20waiters=20were=20?= =?UTF-8?q?lost?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous edit accidentally removed tcp_conn_destroy, timer cancellations, and etcp_router_cancel_send_ready from conn_free. Without tcp_conn_destroy the socket was never removed from uasync, causing repeated EPOLLERR → repeated conn_free on freed memory → double-free crash. Added debug logs for freed guard entry and u_free. --- src/proxy/tcp_proxy_server.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/proxy/tcp_proxy_server.c b/src/proxy/tcp_proxy_server.c index 5f48d412..3fdc9e1a 100644 --- a/src/proxy/tcp_proxy_server.c +++ b/src/proxy/tcp_proxy_server.c @@ -196,7 +196,11 @@ static int conn_total(struct tcp_proxy_server_conn* rc) { void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc) { if (!rc) return; - if (rc->freed) return; + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:FREE enter rc=%p freed=%d sid=%08x", (void*)rc, rc->freed, rc->stream_id); + if (rc->freed) { + DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "SOCK:FREE double rc=%p — IGNORED", (void*)rc); + return; + } rc->freed = 1; int total = conn_total(rc); DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:FREE fd=%d sid=%08x total=%d cli_closed=%d fin=%d error=%d", @@ -205,6 +209,11 @@ void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc) { struct tcp_proxy_server_conn** prev = &rc->ctx->conns; while (*prev) { if (*prev == rc) { *prev = rc->next; rc->ctx->conn_count--; break; } prev = &(*prev)->next; } } + if (rc->tc) { tcp_conn_destroy(rc->tc); rc->tc = NULL; } + if (rc->close_timer) { uasync_cancel_timeout(rc->ua, rc->close_timer); rc->close_timer = NULL; } + if (rc->diag_timer) { uasync_cancel_timeout(rc->ua, rc->diag_timer); rc->diag_timer = NULL; } + if (rc->ctx && rc->ctx->inst) etcp_router_cancel_send_ready(rc->ctx->inst, rc->peer_node_id, ETCP_ID_TCP_PROXY, &rc->pause_waiter); + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:FREE u_free rc=%p", (void*)rc); u_free(rc); }