From 2adfbd572e9b63ae1ae944a2f0e997165f6db555 Mon Sep 17 00:00:00 2001 From: mikhailm-coder Date: Thu, 2 Jul 2026 16:27:04 +0200 Subject: [PATCH] fix: evict stale pooled connection before each control-channel dial ILibWebClient pipelines the WS upgrade onto a kept-alive connection from its DataTable when one exists for the target address. If the gateway abortively closed that socket (or it died during a network blip), the queued upgrade fails instantly with no HTTP response (tls=down, elapsedMs=0) without ever touching the network, and every 4-6 min retry rides the same dead object indefinitely - the agent stays offline until process restart while other clients on the same host reconnect fine. Deleting the address entry before pipelining forces a fresh TCP+TLS connect per dial. Safe because the single-flight guard guarantees no in-flight control-channel request at this point and httpClientManager has no other users, so the call can only drop an idle stale socket. Co-Authored-By: Claude Fable 5 --- meshcore/agentcore.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index 3f82514a..6a471649 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -4807,6 +4807,9 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent) ILibWebClient_AddWebSocketRequestHeaders(req, 65535, MeshServer_OnSendOK); + // Evict any stale pooled connection to this address so every dial performs a fresh TCP+TLS connect instead of riding a dead kept-alive socket. + ILibWebClient_DeleteRequests(agent->httpClientManager, (struct sockaddr*)&meshServer); + void **tmp = ILibMemory_SmartAllocate(2 * sizeof(void*)); agent->controlChannelRequest = tmp; tmp[0] = agent;