From e76fc05f8d2f19a61ee0e85b18f1e7d7b17cc3c1 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 18 Dec 2025 21:37:09 +0000 Subject: [PATCH] weakset for sockets --- .../services/infrastructure/NetworkService.ts | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/server/src/services/infrastructure/NetworkService.ts b/server/src/services/infrastructure/NetworkService.ts index 1847786ea..a2b6de10f 100644 --- a/server/src/services/infrastructure/NetworkService.ts +++ b/server/src/services/infrastructure/NetworkService.ts @@ -16,6 +16,8 @@ import ApiError from "@/utils/ApiError.js"; import { config } from "@/config/index.js"; import CacheableLookup from "cacheable-lookup"; import { getChildLogger } from "@/logger/Logger.js"; +// Track sockets we've already attached a secureConnect listener to avoid leaks on keep-alive reuse +const tlsCaptureAttached: WeakSet = new WeakSet(); const SERVICE_NAME = "NetworkService"; const logger = getChildLogger(SERVICE_NAME); export interface INetworkService { @@ -159,16 +161,17 @@ class NetworkService implements INetworkService { } }; - // Attempt immediate capture; for reused TLS sockets this is sufficient. - capture(); + const isTLS = typeof (socket as any).getPeerCertificate === "function"; + if (!isTLS) return; - // Only add a one-time listener if TLS handshake hasn't completed. - const isTLS = - typeof (socket as any).getPeerCertificate === "function"; - const isEncrypted = isTLS && (socket as any).encrypted === true; - const connectPending = - isTLS && !isEncrypted && (socket as any).connecting === true; - if (connectPending && typeof socket.once === "function") { + // If socket already encrypted (keep-alive reuse), capture immediately + if ((socket as any).encrypted === true) { + capture(); + } + + // Add at most one secureConnect listener per socket + if (!tlsCaptureAttached.has(socket) && typeof socket.once === "function") { + tlsCaptureAttached.add(socket); socket.once("secureConnect", capture); } });