fix(PortProxy): Improve TLS keep-alive management and fix whitespace formatting

This commit is contained in:
Philipp Kunz 2025-03-10 14:13:56 +00:00
parent 4465cac807
commit 146fac73cf
3 changed files with 248 additions and 147 deletions

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
## 2025-03-10 - 3.30.1 - fix(PortProxy)
Improve TLS keep-alive management and fix whitespace formatting
- Implemented better handling for TLS keep-alive connections after sleep or long inactivity.
- Reformatted whitespace for better readability and consistency.
## 2025-03-08 - 3.30.0 - feat(PortProxy) ## 2025-03-08 - 3.30.0 - feat(PortProxy)
Add advanced TLS keep-alive handling and system sleep detection Add advanced TLS keep-alive handling and system sleep detection

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartproxy', name: '@push.rocks/smartproxy',
version: '3.30.0', version: '3.30.1',
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, and dynamic routing with authentication options.' description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, and dynamic routing with authentication options.'
} }

View File

@ -379,8 +379,8 @@ export class PortProxy {
// Feature flags // Feature flags
disableInactivityCheck: settingsArg.disableInactivityCheck || false, disableInactivityCheck: settingsArg.disableInactivityCheck || false,
enableKeepAliveProbes: settingsArg.enableKeepAliveProbes !== undefined enableKeepAliveProbes:
? settingsArg.enableKeepAliveProbes : true, // Enable by default settingsArg.enableKeepAliveProbes !== undefined ? settingsArg.enableKeepAliveProbes : true, // Enable by default
enableDetailedLogging: settingsArg.enableDetailedLogging || false, enableDetailedLogging: settingsArg.enableDetailedLogging || false,
enableTlsDebugLogging: settingsArg.enableTlsDebugLogging || false, enableTlsDebugLogging: settingsArg.enableTlsDebugLogging || false,
enableRandomizedTimeouts: settingsArg.enableRandomizedTimeouts || false, // Disable randomization by default enableRandomizedTimeouts: settingsArg.enableRandomizedTimeouts || false, // Disable randomization by default
@ -417,15 +417,23 @@ export class PortProxy {
serverName?: string serverName?: string
): void { ): void {
// Determine which NetworkProxy to use // Determine which NetworkProxy to use
const proxyIndex = domainConfig.networkProxyIndex !== undefined const proxyIndex =
? domainConfig.networkProxyIndex domainConfig.networkProxyIndex !== undefined ? domainConfig.networkProxyIndex : 0;
: 0;
// Validate the NetworkProxy index // Validate the NetworkProxy index
if (proxyIndex < 0 || proxyIndex >= this.networkProxies.length) { if (proxyIndex < 0 || proxyIndex >= this.networkProxies.length) {
console.log(`[${connectionId}] Invalid NetworkProxy index: ${proxyIndex}. Using fallback direct connection.`); console.log(
`[${connectionId}] Invalid NetworkProxy index: ${proxyIndex}. Using fallback direct connection.`
);
// Fall back to direct connection // Fall back to direct connection
return this.setupDirectConnection(connectionId, socket, record, domainConfig, serverName, initialData); return this.setupDirectConnection(
connectionId,
socket,
record,
domainConfig,
serverName,
initialData
);
} }
const networkProxy = this.networkProxies[proxyIndex]; const networkProxy = this.networkProxies[proxyIndex];
@ -441,7 +449,7 @@ export class PortProxy {
// Create a connection to the NetworkProxy // Create a connection to the NetworkProxy
const proxySocket = plugins.net.connect({ const proxySocket = plugins.net.connect({
host: proxyHost, host: proxyHost,
port: proxyPort port: proxyPort,
}); });
// Store the outgoing socket in the record // Store the outgoing socket in the record
@ -479,7 +487,9 @@ export class PortProxy {
socket.on('close', () => { socket.on('close', () => {
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] Client connection closed after forwarding to NetworkProxy`); console.log(
`[${connectionId}] Client connection closed after forwarding to NetworkProxy`
);
} }
this.cleanupConnection(record, 'client_closed'); this.cleanupConnection(record, 'client_closed');
}); });
@ -489,9 +499,12 @@ export class PortProxy {
this.updateActivity(record); this.updateActivity(record);
// Check for potential TLS renegotiation or reconnection packets // Check for potential TLS renegotiation or reconnection packets
if (chunk.length > 0 && chunk[0] === 22) { // ContentType.handshake if (chunk.length > 0 && chunk[0] === 22) {
// ContentType.handshake
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] Detected potential TLS handshake data while connected to NetworkProxy`); console.log(
`[${connectionId}] Detected potential TLS handshake data while connected to NetworkProxy`
);
} }
// Let the NetworkProxy handle the TLS renegotiation // Let the NetworkProxy handle the TLS renegotiation
@ -603,7 +616,9 @@ export class PortProxy {
} catch (err) { } catch (err) {
// Ignore errors - these are optional enhancements // Ignore errors - these are optional enhancements
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] Enhanced TCP keep-alive not supported for outgoing socket: ${err}`); console.log(
`[${connectionId}] Enhanced TCP keep-alive not supported for outgoing socket: ${err}`
);
} }
} }
} }
@ -660,7 +675,9 @@ export class PortProxy {
// For keep-alive connections, just log a warning instead of closing // For keep-alive connections, just log a warning instead of closing
if (record.hasKeepAlive) { if (record.hasKeepAlive) {
console.log( console.log(
`[${connectionId}] Timeout event on incoming keep-alive connection from ${record.remoteIP} after ${plugins.prettyMs( `[${connectionId}] Timeout event on incoming keep-alive connection from ${
record.remoteIP
} after ${plugins.prettyMs(
this.settings.socketTimeout || 3600000 this.settings.socketTimeout || 3600000
)}. Connection preserved.` )}. Connection preserved.`
); );
@ -670,9 +687,9 @@ export class PortProxy {
// For non-keep-alive connections, proceed with normal cleanup // For non-keep-alive connections, proceed with normal cleanup
console.log( console.log(
`[${connectionId}] Timeout on incoming side from ${record.remoteIP} after ${plugins.prettyMs( `[${connectionId}] Timeout on incoming side from ${
this.settings.socketTimeout || 3600000 record.remoteIP
)}` } after ${plugins.prettyMs(this.settings.socketTimeout || 3600000)}`
); );
if (record.incomingTerminationReason === null) { if (record.incomingTerminationReason === null) {
record.incomingTerminationReason = 'timeout'; record.incomingTerminationReason = 'timeout';
@ -685,7 +702,9 @@ export class PortProxy {
// For keep-alive connections, just log a warning instead of closing // For keep-alive connections, just log a warning instead of closing
if (record.hasKeepAlive) { if (record.hasKeepAlive) {
console.log( console.log(
`[${connectionId}] Timeout event on outgoing keep-alive connection from ${record.remoteIP} after ${plugins.prettyMs( `[${connectionId}] Timeout event on outgoing keep-alive connection from ${
record.remoteIP
} after ${plugins.prettyMs(
this.settings.socketTimeout || 3600000 this.settings.socketTimeout || 3600000
)}. Connection preserved.` )}. Connection preserved.`
); );
@ -695,9 +714,9 @@ export class PortProxy {
// For non-keep-alive connections, proceed with normal cleanup // For non-keep-alive connections, proceed with normal cleanup
console.log( console.log(
`[${connectionId}] Timeout on outgoing side from ${record.remoteIP} after ${plugins.prettyMs( `[${connectionId}] Timeout on outgoing side from ${
this.settings.socketTimeout || 3600000 record.remoteIP
)}` } after ${plugins.prettyMs(this.settings.socketTimeout || 3600000)}`
); );
if (record.outgoingTerminationReason === null) { if (record.outgoingTerminationReason === null) {
record.outgoingTerminationReason = 'timeout'; record.outgoingTerminationReason = 'timeout';
@ -713,7 +732,9 @@ export class PortProxy {
targetSocket.setTimeout(0); targetSocket.setTimeout(0);
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] Disabled socket timeouts for immortal keep-alive connection`); console.log(
`[${connectionId}] Disabled socket timeouts for immortal keep-alive connection`
);
} }
} else { } else {
// Set normal timeouts for other connections // Set normal timeouts for other connections
@ -743,9 +764,7 @@ export class PortProxy {
const combinedData = Buffer.concat(record.pendingData); const combinedData = Buffer.concat(record.pendingData);
targetSocket.write(combinedData, (err) => { targetSocket.write(combinedData, (err) => {
if (err) { if (err) {
console.log( console.log(`[${connectionId}] Error writing pending data to target: ${err.message}`);
`[${connectionId}] Error writing pending data to target: ${err.message}`
);
return this.initiateCleanupOnce(record, 'write_error'); return this.initiateCleanupOnce(record, 'write_error');
} }
@ -764,7 +783,9 @@ export class PortProxy {
? ` (Port-based for domain: ${domainConfig.domains.join(', ')})` ? ` (Port-based for domain: ${domainConfig.domains.join(', ')})`
: '' : ''
}` + }` +
` TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${record.hasKeepAlive ? 'Yes' : 'No'}` ` TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${
record.hasKeepAlive ? 'Yes' : 'No'
}`
); );
} else { } else {
console.log( console.log(
@ -795,7 +816,9 @@ export class PortProxy {
? ` (Port-based for domain: ${domainConfig.domains.join(', ')})` ? ` (Port-based for domain: ${domainConfig.domains.join(', ')})`
: '' : ''
}` + }` +
` TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${record.hasKeepAlive ? 'Yes' : 'No'}` ` TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${
record.hasKeepAlive ? 'Yes' : 'No'
}`
); );
} else { } else {
console.log( console.log(
@ -849,7 +872,9 @@ export class PortProxy {
// For immortal keep-alive connections, skip setting a timeout completely // For immortal keep-alive connections, skip setting a timeout completely
if (record.hasKeepAlive && this.settings.keepAliveTreatment === 'immortal') { if (record.hasKeepAlive && this.settings.keepAliveTreatment === 'immortal') {
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] Keep-alive connection with immortal treatment - no max lifetime`); console.log(
`[${connectionId}] Keep-alive connection with immortal treatment - no max lifetime`
);
} }
// No cleanup timer for immortal connections // No cleanup timer for immortal connections
} }
@ -862,7 +887,9 @@ export class PortProxy {
record.cleanupTimer = setTimeout(() => { record.cleanupTimer = setTimeout(() => {
console.log( console.log(
`[${connectionId}] TLS keep-alive connection from ${record.remoteIP} exceeded extended lifetime (${plugins.prettyMs( `[${connectionId}] TLS keep-alive connection from ${
record.remoteIP
} exceeded extended lifetime (${plugins.prettyMs(
tlsKeepAliveTimeout tlsKeepAliveTimeout
)}), forcing cleanup.` )}), forcing cleanup.`
); );
@ -875,7 +902,11 @@ export class PortProxy {
} }
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] TLS keep-alive connection with enhanced protection, lifetime: ${plugins.prettyMs(tlsKeepAliveTimeout)}`); console.log(
`[${connectionId}] TLS keep-alive connection with enhanced protection, lifetime: ${plugins.prettyMs(
tlsKeepAliveTimeout
)}`
);
} }
} }
// For extended keep-alive connections, use extended timeout // For extended keep-alive connections, use extended timeout
@ -885,9 +916,9 @@ export class PortProxy {
record.cleanupTimer = setTimeout(() => { record.cleanupTimer = setTimeout(() => {
console.log( console.log(
`[${connectionId}] Keep-alive connection from ${record.remoteIP} exceeded extended lifetime (${plugins.prettyMs( `[${connectionId}] Keep-alive connection from ${
extendedTimeout record.remoteIP
)}), forcing cleanup.` } exceeded extended lifetime (${plugins.prettyMs(extendedTimeout)}), forcing cleanup.`
); );
this.initiateCleanupOnce(record, 'extended_lifetime'); this.initiateCleanupOnce(record, 'extended_lifetime');
}, safeTimeout); }, safeTimeout);
@ -898,20 +929,25 @@ export class PortProxy {
} }
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] Keep-alive connection with extended lifetime of ${plugins.prettyMs(extendedTimeout)}`); console.log(
`[${connectionId}] Keep-alive connection with extended lifetime of ${plugins.prettyMs(
extendedTimeout
)}`
);
} }
} }
// For standard connections, use normal timeout // For standard connections, use normal timeout
else { else {
// Use domain-specific timeout if available, otherwise use default // Use domain-specific timeout if available, otherwise use default
const connectionTimeout = record.domainConfig?.connectionTimeout || this.settings.maxConnectionLifetime!; const connectionTimeout =
record.domainConfig?.connectionTimeout || this.settings.maxConnectionLifetime!;
const safeTimeout = ensureSafeTimeout(connectionTimeout); const safeTimeout = ensureSafeTimeout(connectionTimeout);
record.cleanupTimer = setTimeout(() => { record.cleanupTimer = setTimeout(() => {
console.log( console.log(
`[${connectionId}] Connection from ${record.remoteIP} exceeded max lifetime (${plugins.prettyMs( `[${connectionId}] Connection from ${
connectionTimeout record.remoteIP
)}), forcing cleanup.` } exceeded max lifetime (${plugins.prettyMs(connectionTimeout)}), forcing cleanup.`
); );
this.initiateCleanupOnce(record, 'connection_timeout'); this.initiateCleanupOnce(record, 'connection_timeout');
}, safeTimeout); }, safeTimeout);
@ -1010,14 +1046,25 @@ export class PortProxy {
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log( console.log(
`[${record.id}] Detected possible system sleep for ${plugins.prettyMs(timeDiff)}. ` + `[${record.id}] Detected possible system sleep for ${plugins.prettyMs(timeDiff)}. ` +
`Preserving keep-alive connection.` `Handling keep-alive connection after long inactivity.`
); );
} }
// For keep-alive connections after sleep, we should refresh the TLS state if needed // For TLS keep-alive connections after sleep/long inactivity, force close
// to make browser establish a new connection with fresh certificate context
if (record.isTLS && record.tlsHandshakeComplete) { if (record.isTLS && record.tlsHandshakeComplete) {
if (timeDiff > 4 * 60 * 60 * 1000) {
// If inactive for more than 4 hours
console.log(
`[${record.id}] TLS connection inactive for ${plugins.prettyMs(timeDiff)}. ` +
`Closing to force new connection with fresh certificate.`
);
return this.initiateCleanupOnce(record, 'certificate_refresh_needed');
} else {
// For shorter inactivity periods, try to refresh the TLS state
this.refreshTlsStateAfterSleep(record); this.refreshTlsStateAfterSleep(record);
} }
}
// Mark that we detected sleep // Mark that we detected sleep
record.possibleSystemSleep = true; record.possibleSystemSleep = true;
@ -1046,7 +1093,21 @@ export class PortProxy {
try { try {
// For outgoing connections that might need to be refreshed // For outgoing connections that might need to be refreshed
if (record.outgoing && !record.outgoing.destroyed) { if (record.outgoing && !record.outgoing.destroyed) {
// Send a zero-byte packet to test the connection // Check how long this connection has been established
const connectionAge = Date.now() - record.incomingStartTime;
const hourInMs = 60 * 60 * 1000;
// For TLS browser connections that are very old, it's better to force a new connection
// rather than trying to refresh the state, to avoid certificate issues
if (record.isTLS && record.hasKeepAlive && connectionAge > 12 * hourInMs) {
console.log(
`[${record.id}] Long-lived TLS connection (${plugins.prettyMs(connectionAge)}). ` +
`Closing to ensure proper certificate handling on browser reconnect.`
);
return this.initiateCleanupOnce(record, 'certificate_context_refresh');
}
// For newer connections, try to send a refresh packet
record.outgoing.write(Buffer.alloc(0)); record.outgoing.write(Buffer.alloc(0));
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
@ -1056,8 +1117,9 @@ export class PortProxy {
} catch (err) { } catch (err) {
console.log(`[${record.id}] Error refreshing TLS state: ${err}`); console.log(`[${record.id}] Error refreshing TLS state: ${err}`);
// If we can't refresh, don't terminate - client will re-establish if needed // If we hit an error, it's likely the connection is already broken
// Just log the issue but preserve the connection // Force cleanup to ensure browser reconnects cleanly
return this.initiateCleanupOnce(record, 'tls_refresh_error');
} }
} }
@ -1158,7 +1220,9 @@ export class PortProxy {
` Duration: ${plugins.prettyMs( ` Duration: ${plugins.prettyMs(
duration duration
)}, Bytes IN: ${bytesReceived}, OUT: ${bytesSent}, ` + )}, Bytes IN: ${bytesReceived}, OUT: ${bytesSent}, ` +
`TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${record.hasKeepAlive ? 'Yes' : 'No'}` + `TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${
record.hasKeepAlive ? 'Yes' : 'No'
}` +
`${record.usingNetworkProxy ? `, NetworkProxy: ${record.networkProxyIndex}` : ''}` `${record.usingNetworkProxy ? `, NetworkProxy: ${record.networkProxyIndex}` : ''}`
); );
} else { } else {
@ -1190,7 +1254,10 @@ export class PortProxy {
console.log(`[${record.id}] Connection cleanup initiated for ${record.remoteIP} (${reason})`); console.log(`[${record.id}] Connection cleanup initiated for ${record.remoteIP} (${reason})`);
} }
if (record.incomingTerminationReason === null || record.incomingTerminationReason === undefined) { if (
record.incomingTerminationReason === null ||
record.incomingTerminationReason === undefined
) {
record.incomingTerminationReason = reason; record.incomingTerminationReason = reason;
this.incrementTerminationStat('incoming', reason); this.incrementTerminationStat('incoming', reason);
} }
@ -1347,7 +1414,7 @@ export class PortProxy {
usingNetworkProxy: false, usingNetworkProxy: false,
// Initialize sleep detection fields // Initialize sleep detection fields
possibleSystemSleep: false possibleSystemSleep: false,
}; };
// Apply keep-alive settings if enabled // Apply keep-alive settings if enabled
@ -1368,7 +1435,9 @@ export class PortProxy {
} catch (err) { } catch (err) {
// Ignore errors - these are optional enhancements // Ignore errors - these are optional enhancements
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${connectionId}] Enhanced TCP keep-alive settings not supported: ${err}`); console.log(
`[${connectionId}] Enhanced TCP keep-alive settings not supported: ${err}`
);
} }
} }
} }
@ -1808,17 +1877,24 @@ export class PortProxy {
} }
// Skip inactivity check if disabled or for immortal keep-alive connections // Skip inactivity check if disabled or for immortal keep-alive connections
if (!this.settings.disableInactivityCheck && if (
!(record.hasKeepAlive && this.settings.keepAliveTreatment === 'immortal')) { !this.settings.disableInactivityCheck &&
!(record.hasKeepAlive && this.settings.keepAliveTreatment === 'immortal')
) {
const inactivityTime = now - record.lastActivity; const inactivityTime = now - record.lastActivity;
// Special handling for TLS keep-alive connections // Special handling for TLS keep-alive connections
if (record.hasKeepAlive && record.isTLS && inactivityTime > this.settings.inactivityTimeout! / 2) { if (
record.hasKeepAlive &&
record.isTLS &&
inactivityTime > this.settings.inactivityTimeout! / 2
) {
// For TLS keep-alive connections that are getting stale, try to refresh before closing // For TLS keep-alive connections that are getting stale, try to refresh before closing
if (!record.inactivityWarningIssued) { if (!record.inactivityWarningIssued) {
console.log( console.log(
`[${id}] TLS keep-alive connection from ${record.remoteIP} inactive for ${plugins.prettyMs(inactivityTime)}. ` + `[${id}] TLS keep-alive connection from ${
record.remoteIP
} inactive for ${plugins.prettyMs(inactivityTime)}. ` +
`Attempting to preserve connection.` `Attempting to preserve connection.`
); );
@ -1827,7 +1903,7 @@ export class PortProxy {
// For TLS connections, extend the last activity time considerably // For TLS connections, extend the last activity time considerably
// This gives browsers more time to re-establish the connection properly // This gives browsers more time to re-establish the connection properly
record.lastActivity = now - (this.settings.inactivityTimeout! / 3); record.lastActivity = now - this.settings.inactivityTimeout! / 3;
// Try to stimulate the connection with a probe packet // Try to stimulate the connection with a probe packet
if (record.outgoing && !record.outgoing.destroyed) { if (record.outgoing && !record.outgoing.destroyed) {
@ -1860,7 +1936,9 @@ export class PortProxy {
// For keep-alive connections, issue a warning first // For keep-alive connections, issue a warning first
if (record.hasKeepAlive && !record.inactivityWarningIssued) { if (record.hasKeepAlive && !record.inactivityWarningIssued) {
console.log( console.log(
`[${id}] Warning: Keep-alive connection from ${record.remoteIP} inactive for ${plugins.prettyMs(inactivityTime)}. ` + `[${id}] Warning: Keep-alive connection from ${
record.remoteIP
} inactive for ${plugins.prettyMs(inactivityTime)}. ` +
`Will close in 10 minutes if no activity.` `Will close in 10 minutes if no activity.`
); );
@ -1882,16 +1960,31 @@ export class PortProxy {
} }
} else { } else {
// MODIFIED: For TLS connections, be more lenient before closing // MODIFIED: For TLS connections, be more lenient before closing
// For TLS browser connections, we need to handle certificate context properly
if (record.isTLS && record.hasKeepAlive) { if (record.isTLS && record.hasKeepAlive) {
// For TLS keep-alive connections, add additional grace period // For very long inactivity, it's better to close the connection
// This helps with browsers reconnecting after sleep // so the browser establishes a new one with a fresh certificate context
if (inactivityTime > 6 * 60 * 60 * 1000) {
// 6 hours
console.log( console.log(
`[${id}] TLS keep-alive connection from ${record.remoteIP} inactive for ${plugins.prettyMs(inactivityTime)}. ` + `[${id}] TLS keep-alive connection from ${
record.remoteIP
} inactive for ${plugins.prettyMs(inactivityTime)}. ` +
`Closing to ensure proper certificate handling on browser reconnect.`
);
this.cleanupConnection(record, 'tls_certificate_refresh');
} else {
// For shorter inactivity periods, add grace period
console.log(
`[${id}] TLS keep-alive connection from ${
record.remoteIP
} inactive for ${plugins.prettyMs(inactivityTime)}. ` +
`Adding extra grace period.` `Adding extra grace period.`
); );
// Give additional time for browsers to reconnect properly // Give additional time for browsers to reconnect properly
record.lastActivity = now - (effectiveTimeout / 2); record.lastActivity = now - effectiveTimeout / 2;
}
} else { } else {
// For non-keep-alive or after warning, close the connection // For non-keep-alive or after warning, close the connection
console.log( console.log(
@ -1905,7 +1998,9 @@ export class PortProxy {
} else if (inactivityTime <= effectiveTimeout && record.inactivityWarningIssued) { } else if (inactivityTime <= effectiveTimeout && record.inactivityWarningIssued) {
// If activity detected after warning, clear the warning // If activity detected after warning, clear the warning
if (this.settings.enableDetailedLogging) { if (this.settings.enableDetailedLogging) {
console.log(`[${id}] Connection activity detected after inactivity warning, resetting warning`); console.log(
`[${id}] Connection activity detected after inactivity warning, resetting warning`
);
} }
record.inactivityWarningIssued = false; record.inactivityWarningIssued = false;
} }