From 194c8398c152d58781adb24800d3bf6331b461b3 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 14 May 2026 03:35:26 +0300 Subject: [PATCH] fix ETCP: dgram leak on inflight pool exhaustion, cancel dangling timers on link close/new --- src/etcp.c | 3 ++- src/etcp_connections.c | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/etcp.c b/src/etcp.c index 75559a5c..c68d08cc 100644 --- a/src/etcp.c +++ b/src/etcp.c @@ -678,7 +678,8 @@ static void input_queue_cb(struct ll_queue* q, void* arg) { struct INFLIGHT_PACKET* p = (struct INFLIGHT_PACKET*)queue_entry_new_from_pool(etcp->inflight_pool); if (!p) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] cannot allocate INFLIGHT_PACKET (pool=%p etcp=%p)", etcp->log_name, etcp->inflight_pool, etcp); - queue_entry_free((struct ll_entry*)in_pkt); // Free the ETCP_FRAGMENT + queue_dgram_free(&in_pkt->ll); + queue_entry_free((struct ll_entry*)in_pkt); queue_resume_callback(q); return; } diff --git a/src/etcp_connections.c b/src/etcp_connections.c index 72ce512f..7ae1e0cb 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -847,9 +847,8 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn // insert_link(conn, link); if (insert_link(conn, link) < 0) { - // откатываем то, что успели - // (пока список ещё не добавлен — просто free) DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Can not insert link to socket"); + uasync_cancel_timeout(link->etcp->instance->ua, link->stats_timer); u_free(link); return NULL; } @@ -876,11 +875,20 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn void etcp_link_close(struct ETCP_LINK* link) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); if (!link) return; + + if (link->burst_resp_timer) { + uasync_cancel_timeout(link->etcp->instance->ua, link->burst_resp_timer); + link->burst_resp_timer = NULL; + } + if (!link->conn) { - // только удаляем из списка и free struct ETCP_LINK **pp = &link->etcp->links; while (*pp && *pp != link) pp = &(*pp)->next; if (*pp) *pp = link->next; + if (link->stats_timer) uasync_cancel_timeout(link->etcp->instance->ua, link->stats_timer); + if (link->init_timer) uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer); + if (link->shaper_timer) uasync_cancel_timeout(link->etcp->instance->ua, link->shaper_timer); + if (link->keepalive_timer) uasync_cancel_timeout(link->etcp->instance->ua, link->keepalive_timer); u_free(link); return; }