Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
b3dcc0ae22 | |||
b96d7dec98 | |||
0d0a1c740b | |||
9bd87b8437 | |||
0e281b3243 | |||
a14b7802c4 | |||
138900ca8b | |||
cb6c2503e2 |
25
changelog.md
25
changelog.md
@ -1,5 +1,30 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-03-07 - 3.28.5 - fix(core)
|
||||
Ensure proper resource cleanup during server shutdown.
|
||||
|
||||
- Fixed potential hanging of server shutdown due to improper cleanup in promise handling.
|
||||
- Corrected potential memory leaks by ensuring all pending and active connections are properly closed during shutdown.
|
||||
|
||||
## 2025-03-07 - 3.28.4 - fix(router)
|
||||
Improve path pattern matching and hostname prioritization in router
|
||||
|
||||
- Enhance path pattern matching capabilities
|
||||
- Ensure hostname prioritization in routing logic
|
||||
|
||||
## 2025-03-06 - 3.28.3 - fix(PortProxy)
|
||||
Ensure timeout values are within Node.js safe limits
|
||||
|
||||
- Implemented `ensureSafeTimeout` to keep timeout values under the maximum safe integer for Node.js.
|
||||
- Updated timeout configurations in `PortProxy` to include safety checks.
|
||||
|
||||
## 2025-03-06 - 3.28.2 - fix(portproxy)
|
||||
Adjust safe timeout defaults in PortProxy to prevent overflow issues.
|
||||
|
||||
- Adjusted socketTimeout to maximum safe limit (~24.8 days) for PortProxy.
|
||||
- Adjusted maxConnectionLifetime to maximum safe limit (~24.8 days) for PortProxy.
|
||||
- Ensured enhanced default timeout settings in PortProxy.
|
||||
|
||||
## 2025-03-06 - 3.28.1 - fix(PortProxy)
|
||||
Improved code formatting and readability in PortProxy class by adjusting spacing and comments.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@push.rocks/smartproxy",
|
||||
"version": "3.28.1",
|
||||
"version": "3.28.5",
|
||||
"private": false,
|
||||
"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.",
|
||||
"main": "dist_ts/index.js",
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartproxy',
|
||||
version: '3.28.1',
|
||||
version: '3.28.5',
|
||||
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.'
|
||||
}
|
||||
|
@ -290,10 +290,17 @@ const isTlsHandshake = (buffer: Buffer): boolean => {
|
||||
return buffer.length > 0 && buffer[0] === 22; // ContentType.handshake
|
||||
};
|
||||
|
||||
// Helper: Ensure timeout values don't exceed Node.js max safe integer
|
||||
const ensureSafeTimeout = (timeout: number): number => {
|
||||
const MAX_SAFE_TIMEOUT = 2147483647; // Maximum safe value (2^31 - 1)
|
||||
return Math.min(Math.floor(timeout), MAX_SAFE_TIMEOUT);
|
||||
};
|
||||
|
||||
// Helper: Generate a slightly randomized timeout to prevent thundering herd
|
||||
const randomizeTimeout = (baseTimeout: number, variationPercent: number = 5): number => {
|
||||
const variation = baseTimeout * (variationPercent / 100);
|
||||
return baseTimeout + Math.floor(Math.random() * variation * 2) - variation;
|
||||
const safeBaseTimeout = ensureSafeTimeout(baseTimeout);
|
||||
const variation = safeBaseTimeout * (variationPercent / 100);
|
||||
return ensureSafeTimeout(safeBaseTimeout + Math.floor(Math.random() * variation * 2) - variation);
|
||||
};
|
||||
|
||||
export class PortProxy {
|
||||
@ -325,12 +332,12 @@ export class PortProxy {
|
||||
...settingsArg,
|
||||
targetIP: settingsArg.targetIP || 'localhost',
|
||||
|
||||
// Timeout settings with our enhanced defaults
|
||||
// Timeout settings with safe maximum values
|
||||
initialDataTimeout: settingsArg.initialDataTimeout || 60000, // 60 seconds for initial handshake
|
||||
socketTimeout: settingsArg.socketTimeout || 2592000000, // 30 days socket timeout
|
||||
socketTimeout: ensureSafeTimeout(settingsArg.socketTimeout || 2147483647), // Maximum safe value (~24.8 days)
|
||||
inactivityCheckInterval: settingsArg.inactivityCheckInterval || 60000, // 60 seconds interval
|
||||
maxConnectionLifetime: settingsArg.maxConnectionLifetime || 2592000000, // 30 days max lifetime
|
||||
inactivityTimeout: settingsArg.inactivityTimeout || 14400000, // 4 hours inactivity timeout
|
||||
maxConnectionLifetime: ensureSafeTimeout(settingsArg.maxConnectionLifetime || 2147483647), // Maximum safe value (~24.8 days)
|
||||
inactivityTimeout: ensureSafeTimeout(settingsArg.inactivityTimeout || 14400000), // 4 hours inactivity timeout
|
||||
|
||||
gracefulShutdownTimeout: settingsArg.gracefulShutdownTimeout || 30000, // 30 seconds
|
||||
|
||||
@ -415,19 +422,19 @@ export class PortProxy {
|
||||
* Get connection timeout based on domain config or default settings
|
||||
*/
|
||||
private getConnectionTimeout(record: IConnectionRecord): number {
|
||||
// If the connection has a domain-specific timeout, use that
|
||||
// If the connection has a domain-specific timeout, use that with safety check
|
||||
if (record.domainConfig?.connectionTimeout) {
|
||||
return record.domainConfig.connectionTimeout;
|
||||
return ensureSafeTimeout(record.domainConfig.connectionTimeout);
|
||||
}
|
||||
|
||||
// Use default timeout, potentially randomized
|
||||
// Use default timeout, potentially randomized with safety check
|
||||
const baseTimeout = this.settings.maxConnectionLifetime!;
|
||||
|
||||
if (this.settings.enableRandomizedTimeouts) {
|
||||
return randomizeTimeout(baseTimeout);
|
||||
}
|
||||
|
||||
return baseTimeout;
|
||||
return ensureSafeTimeout(baseTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1040,9 +1047,9 @@ export class PortProxy {
|
||||
initiateCleanupOnce('timeout_outgoing');
|
||||
});
|
||||
|
||||
// Set appropriate timeouts using the configured value
|
||||
socket.setTimeout(this.settings.socketTimeout || 3600000);
|
||||
targetSocket.setTimeout(this.settings.socketTimeout || 3600000);
|
||||
// Set appropriate timeouts using the configured value with safety
|
||||
socket.setTimeout(ensureSafeTimeout(this.settings.socketTimeout || 3600000));
|
||||
targetSocket.setTimeout(ensureSafeTimeout(this.settings.socketTimeout || 3600000));
|
||||
|
||||
// Track outgoing data for bytes counting
|
||||
targetSocket.on('data', (chunk: Buffer) => {
|
||||
@ -1169,8 +1176,10 @@ export class PortProxy {
|
||||
clearTimeout(connectionRecord.cleanupTimer);
|
||||
}
|
||||
|
||||
// Set timeout based on domain config or default
|
||||
// Set timeout based on domain config or default with safety check
|
||||
const connectionTimeout = this.getConnectionTimeout(connectionRecord);
|
||||
const safeTimeout = ensureSafeTimeout(connectionTimeout); // Ensure timeout is safe
|
||||
|
||||
connectionRecord.cleanupTimer = setTimeout(() => {
|
||||
console.log(
|
||||
`[${connectionId}] Connection from ${remoteIP} exceeded max lifetime (${plugins.prettyMs(
|
||||
@ -1178,7 +1187,7 @@ export class PortProxy {
|
||||
)}), forcing cleanup.`
|
||||
);
|
||||
initiateCleanupOnce('connection_timeout');
|
||||
}, connectionTimeout);
|
||||
}, safeTimeout);
|
||||
|
||||
// Make sure timeout doesn't keep the process alive
|
||||
if (connectionRecord.cleanupTimer.unref) {
|
||||
|
Reference in New Issue
Block a user