From a70c1230071a8fd79ac8a9448e526d751cb74a9d Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Sun, 16 Mar 2025 14:49:25 +0000 Subject: [PATCH] fix(connectionhandler): Increase delay timings for TLS alert transmission in session ticket blocking to allow graceful socket termination --- changelog.md | 7 +++++++ ts/00_commitinfo_data.ts | 2 +- ts/classes.pp.connectionhandler.ts | 33 ++++++++++++++---------------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/changelog.md b/changelog.md index 1474d3b..2ccfef7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2025-03-16 - 4.1.10 - fix(connectionhandler) +Increase delay timings for TLS alert transmission in session ticket blocking to allow graceful socket termination + +- Updated finishConnection: replaced immediate socket.destroy with a graceful end call +- Increased delay after successful write from 50ms to 200ms to allow alert processing +- Raised safety timeout from 250ms to 400ms when waiting for 'drain' event + ## 2025-03-16 - 4.1.9 - fix(ConnectionHandler) Replace closeNotify alert with handshake failure alert in TLS ClientHello handling to properly signal missing SNI and enforce session ticket restrictions. diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 222b308..e9747fc 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartproxy', - version: '4.1.9', + version: '4.1.10', description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.' } diff --git a/ts/classes.pp.connectionhandler.ts b/ts/classes.pp.connectionhandler.ts index b740c64..b62a668 100644 --- a/ts/classes.pp.connectionhandler.ts +++ b/ts/classes.pp.connectionhandler.ts @@ -610,37 +610,34 @@ export class ConnectionHandler { socket.cork(); const writeSuccessful = socket.write(serverNameUnknownAlertData); socket.uncork(); - - // Function to handle the clean socket termination + + // Function to handle the clean socket termination - but more gradually const finishConnection = () => { - // First call end() to initiate a graceful close (sends FIN) + // Give Chrome more time to process the alert before closing + // We won't call destroy() at all - just end() and let the socket close naturally socket.end(); - - // Allow a short delay for the alert and FIN to be transmitted - // before we fully close the socket + + // Log the cleanup but wait for natural closure setTimeout(() => { - if (!socket.destroyed) { - socket.destroy(); - } this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni'); - }, 150); // Short delay, but longer than the standard TCP ACK timeout + }, 300); // Longer delay to let socket cleanup happen naturally }; - + if (writeSuccessful) { - // If the data was successfully written to the kernel buffer, - // we can finish the connection after a short delay to ensure transmission - setTimeout(finishConnection, 50); + // Wait longer before ending connection to ensure alert is processed by client + setTimeout(finishConnection, 200); // Increased from 50ms to 200ms } else { // If the kernel buffer was full, wait for the drain event socket.once('drain', () => { - setTimeout(finishConnection, 50); + // Wait longer after drain as well + setTimeout(finishConnection, 200); }); - - // Set a safety timeout in case drain never happens + + // Safety timeout is increased too setTimeout(() => { socket.removeAllListeners('drain'); finishConnection(); - }, 250); + }, 400); // Increased from 250ms to 400ms } } catch (err) { // If we can't send the alert, fall back to immediate termination