@push.rocks/smartproxy 3.23.1 → 3.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -90,6 +90,29 @@ const isGlobIPAllowed = (ip, allowed, blocked = []) => {
90
90
  const generateConnectionId = () => {
91
91
  return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
92
92
  };
93
+ // Protocol detection helpers
94
+ const isHttpRequest = (buffer) => {
95
+ if (buffer.length < 4)
96
+ return false;
97
+ const start = buffer.toString('ascii', 0, 4).toUpperCase();
98
+ return (start.startsWith('GET ') ||
99
+ start.startsWith('POST') ||
100
+ start.startsWith('PUT ') ||
101
+ start.startsWith('HEAD') ||
102
+ start.startsWith('DELE') ||
103
+ start.startsWith('PATC') ||
104
+ start.startsWith('OPTI'));
105
+ };
106
+ const isWebSocketUpgrade = (buffer) => {
107
+ if (buffer.length < 20)
108
+ return false;
109
+ const data = buffer.toString('ascii', 0, Math.min(buffer.length, 200));
110
+ return (data.includes('Upgrade: websocket') ||
111
+ data.includes('Upgrade: WebSocket'));
112
+ };
113
+ const isTlsHandshake = (buffer) => {
114
+ return buffer.length > 0 && buffer[0] === 22; // ContentType.handshake
115
+ };
93
116
  export class PortProxy {
94
117
  constructor(settingsArg) {
95
118
  this.netServers = [];
@@ -98,20 +121,195 @@ export class PortProxy {
98
121
  this.isShuttingDown = false;
99
122
  // Map to track round robin indices for each domain config
100
123
  this.domainTargetIndices = new Map();
124
+ // Enhanced stats tracking
101
125
  this.terminationStats = {
102
126
  incoming: {},
103
127
  outgoing: {},
104
128
  };
129
+ // Connection tracking by IP for rate limiting
130
+ this.connectionsByIP = new Map();
131
+ this.connectionRateByIP = new Map();
132
+ // Set reasonable defaults for all settings
105
133
  this.settings = {
106
134
  ...settingsArg,
107
135
  targetIP: settingsArg.targetIP || 'localhost',
108
- maxConnectionLifetime: settingsArg.maxConnectionLifetime || 600000,
109
- gracefulShutdownTimeout: settingsArg.gracefulShutdownTimeout || 30000,
136
+ // Timeout settings with browser-friendly defaults
137
+ initialDataTimeout: settingsArg.initialDataTimeout || 15000, // 15 seconds
138
+ socketTimeout: settingsArg.socketTimeout || 300000, // 5 minutes
139
+ inactivityCheckInterval: settingsArg.inactivityCheckInterval || 30000, // 30 seconds
140
+ // Protocol-specific timeouts
141
+ maxConnectionLifetime: settingsArg.maxConnectionLifetime || 3600000, // 1 hour default
142
+ httpConnectionTimeout: settingsArg.httpConnectionTimeout || 1800000, // 30 minutes
143
+ wsConnectionTimeout: settingsArg.wsConnectionTimeout || 14400000, // 4 hours
144
+ httpKeepAliveTimeout: settingsArg.httpKeepAliveTimeout || 1200000, // 20 minutes
145
+ gracefulShutdownTimeout: settingsArg.gracefulShutdownTimeout || 30000, // 30 seconds
146
+ // Socket optimization settings
147
+ noDelay: settingsArg.noDelay !== undefined ? settingsArg.noDelay : true,
148
+ keepAlive: settingsArg.keepAlive !== undefined ? settingsArg.keepAlive : true,
149
+ keepAliveInitialDelay: settingsArg.keepAliveInitialDelay || 60000, // 1 minute
150
+ maxPendingDataSize: settingsArg.maxPendingDataSize || 1024 * 1024, // 1MB
151
+ // Feature flags
152
+ disableInactivityCheck: settingsArg.disableInactivityCheck || false,
153
+ enableKeepAliveProbes: settingsArg.enableKeepAliveProbes || false,
154
+ enableProtocolDetection: settingsArg.enableProtocolDetection !== undefined ? settingsArg.enableProtocolDetection : true,
155
+ enableDetailedLogging: settingsArg.enableDetailedLogging || false,
156
+ // Rate limiting defaults
157
+ maxConnectionsPerIP: settingsArg.maxConnectionsPerIP || 100, // 100 connections per IP
158
+ connectionRateLimitPerMinute: settingsArg.connectionRateLimitPerMinute || 300, // 300 per minute
110
159
  };
111
160
  }
161
+ /**
162
+ * Get connections count by IP
163
+ */
164
+ getConnectionCountByIP(ip) {
165
+ return this.connectionsByIP.get(ip)?.size || 0;
166
+ }
167
+ /**
168
+ * Check and update connection rate for an IP
169
+ */
170
+ checkConnectionRate(ip) {
171
+ const now = Date.now();
172
+ const minute = 60 * 1000;
173
+ if (!this.connectionRateByIP.has(ip)) {
174
+ this.connectionRateByIP.set(ip, [now]);
175
+ return true;
176
+ }
177
+ // Get timestamps and filter out entries older than 1 minute
178
+ const timestamps = this.connectionRateByIP.get(ip).filter(time => now - time < minute);
179
+ timestamps.push(now);
180
+ this.connectionRateByIP.set(ip, timestamps);
181
+ // Check if rate exceeds limit
182
+ return timestamps.length <= this.settings.connectionRateLimitPerMinute;
183
+ }
184
+ /**
185
+ * Track connection by IP
186
+ */
187
+ trackConnectionByIP(ip, connectionId) {
188
+ if (!this.connectionsByIP.has(ip)) {
189
+ this.connectionsByIP.set(ip, new Set());
190
+ }
191
+ this.connectionsByIP.get(ip).add(connectionId);
192
+ }
193
+ /**
194
+ * Remove connection tracking for an IP
195
+ */
196
+ removeConnectionByIP(ip, connectionId) {
197
+ if (this.connectionsByIP.has(ip)) {
198
+ const connections = this.connectionsByIP.get(ip);
199
+ connections.delete(connectionId);
200
+ if (connections.size === 0) {
201
+ this.connectionsByIP.delete(ip);
202
+ }
203
+ }
204
+ }
205
+ /**
206
+ * Track connection termination statistic
207
+ */
112
208
  incrementTerminationStat(side, reason) {
113
209
  this.terminationStats[side][reason] = (this.terminationStats[side][reason] || 0) + 1;
114
210
  }
211
+ /**
212
+ * Get protocol-specific timeout based on connection type
213
+ */
214
+ getProtocolTimeout(record, domainConfig) {
215
+ // If the protocol has a domain-specific timeout, use that
216
+ if (domainConfig) {
217
+ if (record.protocolType === 'http' && domainConfig.httpTimeout) {
218
+ return domainConfig.httpTimeout;
219
+ }
220
+ if (record.protocolType === 'websocket' && domainConfig.wsTimeout) {
221
+ return domainConfig.wsTimeout;
222
+ }
223
+ }
224
+ // Use HTTP keep-alive timeout from headers if available
225
+ if (record.httpKeepAliveTimeout) {
226
+ return record.httpKeepAliveTimeout;
227
+ }
228
+ // Otherwise use default protocol-specific timeout
229
+ switch (record.protocolType) {
230
+ case 'http':
231
+ return this.settings.httpConnectionTimeout;
232
+ case 'websocket':
233
+ return this.settings.wsConnectionTimeout;
234
+ case 'https':
235
+ case 'tls':
236
+ return this.settings.httpConnectionTimeout; // Use HTTP timeout for HTTPS by default
237
+ default:
238
+ return this.settings.maxConnectionLifetime;
239
+ }
240
+ }
241
+ /**
242
+ * Detect protocol and update connection record
243
+ */
244
+ detectProtocol(data, record) {
245
+ if (!this.settings.enableProtocolDetection || record.protocolType !== 'unknown') {
246
+ return;
247
+ }
248
+ try {
249
+ // Detect TLS/HTTPS
250
+ if (isTlsHandshake(data)) {
251
+ record.protocolType = 'tls';
252
+ if (this.settings.enableDetailedLogging) {
253
+ console.log(`[${record.id}] Protocol detected: TLS`);
254
+ }
255
+ return;
256
+ }
257
+ // Detect HTTP including WebSocket upgrades
258
+ if (isHttpRequest(data)) {
259
+ record.httpRequests++;
260
+ record.lastHttpRequest = Date.now();
261
+ // Check for WebSocket upgrade
262
+ if (isWebSocketUpgrade(data)) {
263
+ record.protocolType = 'websocket';
264
+ if (this.settings.enableDetailedLogging) {
265
+ console.log(`[${record.id}] Protocol detected: WebSocket Upgrade`);
266
+ }
267
+ }
268
+ else {
269
+ record.protocolType = 'http';
270
+ // Parse HTTP keep-alive headers
271
+ this.parseHttpHeaders(data, record);
272
+ if (this.settings.enableDetailedLogging) {
273
+ console.log(`[${record.id}] Protocol detected: HTTP${record.isPooledConnection ? ' (KeepAlive)' : ''}`);
274
+ }
275
+ }
276
+ }
277
+ }
278
+ catch (err) {
279
+ console.log(`[${record.id}] Error detecting protocol: ${err}`);
280
+ }
281
+ }
282
+ /**
283
+ * Parse HTTP headers for keep-alive and other connection info
284
+ */
285
+ parseHttpHeaders(data, record) {
286
+ try {
287
+ const headerStr = data.toString('utf8', 0, Math.min(data.length, 1024));
288
+ // Check for HTTP keep-alive
289
+ const connectionHeader = headerStr.match(/\r\nConnection:\s*([^\r\n]+)/i);
290
+ if (connectionHeader && connectionHeader[1].toLowerCase().includes('keep-alive')) {
291
+ record.isPooledConnection = true;
292
+ // Check for Keep-Alive timeout value
293
+ const keepAliveHeader = headerStr.match(/\r\nKeep-Alive:\s*([^\r\n]+)/i);
294
+ if (keepAliveHeader) {
295
+ const timeoutMatch = keepAliveHeader[1].match(/timeout=(\d+)/i);
296
+ if (timeoutMatch && timeoutMatch[1]) {
297
+ const timeoutSec = parseInt(timeoutMatch[1], 10);
298
+ if (!isNaN(timeoutSec) && timeoutSec > 0) {
299
+ // Convert seconds to milliseconds and add some buffer
300
+ record.httpKeepAliveTimeout = (timeoutSec * 1000) + 5000;
301
+ if (this.settings.enableDetailedLogging) {
302
+ console.log(`[${record.id}] HTTP Keep-Alive timeout set to ${timeoutSec} seconds`);
303
+ }
304
+ }
305
+ }
306
+ }
307
+ }
308
+ }
309
+ catch (err) {
310
+ console.log(`[${record.id}] Error parsing HTTP headers: ${err}`);
311
+ }
312
+ }
115
313
  /**
116
314
  * Cleans up a connection record.
117
315
  * Destroys both incoming and outgoing sockets, clears timers, and removes the record.
@@ -121,53 +319,104 @@ export class PortProxy {
121
319
  cleanupConnection(record, reason = 'normal') {
122
320
  if (!record.connectionClosed) {
123
321
  record.connectionClosed = true;
322
+ // Track connection termination
323
+ this.removeConnectionByIP(record.remoteIP, record.id);
124
324
  if (record.cleanupTimer) {
125
325
  clearTimeout(record.cleanupTimer);
126
326
  record.cleanupTimer = undefined;
127
327
  }
328
+ // Detailed logging data
329
+ const duration = Date.now() - record.incomingStartTime;
330
+ const bytesReceived = record.bytesReceived;
331
+ const bytesSent = record.bytesSent;
332
+ const httpRequests = record.httpRequests;
128
333
  try {
129
334
  if (!record.incoming.destroyed) {
130
335
  // Try graceful shutdown first, then force destroy after a short timeout
131
336
  record.incoming.end();
132
- setTimeout(() => {
133
- if (record && !record.incoming.destroyed) {
134
- record.incoming.destroy();
337
+ const incomingTimeout = setTimeout(() => {
338
+ try {
339
+ if (record && !record.incoming.destroyed) {
340
+ record.incoming.destroy();
341
+ }
342
+ }
343
+ catch (err) {
344
+ console.log(`[${record.id}] Error destroying incoming socket: ${err}`);
135
345
  }
136
346
  }, 1000);
347
+ // Ensure the timeout doesn't block Node from exiting
348
+ if (incomingTimeout.unref) {
349
+ incomingTimeout.unref();
350
+ }
137
351
  }
138
352
  }
139
353
  catch (err) {
140
- console.log(`Error closing incoming socket: ${err}`);
141
- if (!record.incoming.destroyed) {
142
- record.incoming.destroy();
354
+ console.log(`[${record.id}] Error closing incoming socket: ${err}`);
355
+ try {
356
+ if (!record.incoming.destroyed) {
357
+ record.incoming.destroy();
358
+ }
359
+ }
360
+ catch (destroyErr) {
361
+ console.log(`[${record.id}] Error destroying incoming socket: ${destroyErr}`);
143
362
  }
144
363
  }
145
364
  try {
146
365
  if (record.outgoing && !record.outgoing.destroyed) {
147
366
  // Try graceful shutdown first, then force destroy after a short timeout
148
367
  record.outgoing.end();
149
- setTimeout(() => {
150
- if (record && record.outgoing && !record.outgoing.destroyed) {
151
- record.outgoing.destroy();
368
+ const outgoingTimeout = setTimeout(() => {
369
+ try {
370
+ if (record && record.outgoing && !record.outgoing.destroyed) {
371
+ record.outgoing.destroy();
372
+ }
373
+ }
374
+ catch (err) {
375
+ console.log(`[${record.id}] Error destroying outgoing socket: ${err}`);
152
376
  }
153
377
  }, 1000);
378
+ // Ensure the timeout doesn't block Node from exiting
379
+ if (outgoingTimeout.unref) {
380
+ outgoingTimeout.unref();
381
+ }
154
382
  }
155
383
  }
156
384
  catch (err) {
157
- console.log(`Error closing outgoing socket: ${err}`);
158
- if (record.outgoing && !record.outgoing.destroyed) {
159
- record.outgoing.destroy();
385
+ console.log(`[${record.id}] Error closing outgoing socket: ${err}`);
386
+ try {
387
+ if (record.outgoing && !record.outgoing.destroyed) {
388
+ record.outgoing.destroy();
389
+ }
390
+ }
391
+ catch (destroyErr) {
392
+ console.log(`[${record.id}] Error destroying outgoing socket: ${destroyErr}`);
160
393
  }
161
394
  }
395
+ // Clear pendingData to avoid memory leaks
396
+ record.pendingData = [];
397
+ record.pendingDataSize = 0;
162
398
  // Remove the record from the tracking map
163
399
  this.connectionRecords.delete(record.id);
164
- const remoteIP = record.incoming.remoteAddress || 'unknown';
165
- console.log(`Connection from ${remoteIP} terminated (${reason}). Active connections: ${this.connectionRecords.size}`);
400
+ // Log connection details
401
+ if (this.settings.enableDetailedLogging) {
402
+ console.log(`[${record.id}] Connection from ${record.remoteIP} on port ${record.localPort} terminated (${reason}).` +
403
+ ` Duration: ${plugins.prettyMs(duration)}, Bytes IN: ${bytesReceived}, OUT: ${bytesSent}, ` +
404
+ `HTTP Requests: ${httpRequests}, Protocol: ${record.protocolType}, Pooled: ${record.isPooledConnection}`);
405
+ }
406
+ else {
407
+ console.log(`[${record.id}] Connection from ${record.remoteIP} terminated (${reason}). Active connections: ${this.connectionRecords.size}`);
408
+ }
166
409
  }
167
410
  }
411
+ /**
412
+ * Update connection activity timestamp
413
+ */
168
414
  updateActivity(record) {
169
415
  record.lastActivity = Date.now();
170
416
  }
417
+ /**
418
+ * Get target IP with round-robin support
419
+ */
171
420
  getTargetIP(domainConfig) {
172
421
  if (domainConfig.targetIPs && domainConfig.targetIPs.length > 0) {
173
422
  const currentIndex = this.domainTargetIndices.get(domainConfig) || 0;
@@ -177,7 +426,15 @@ export class PortProxy {
177
426
  }
178
427
  return this.settings.targetIP;
179
428
  }
429
+ /**
430
+ * Main method to start the proxy
431
+ */
180
432
  async start() {
433
+ // Don't start if already shutting down
434
+ if (this.isShuttingDown) {
435
+ console.log("Cannot start PortProxy while it's shutting down");
436
+ return;
437
+ }
181
438
  // Define a unified connection handler for all listening ports.
182
439
  const connectionHandler = (socket) => {
183
440
  if (this.isShuttingDown) {
@@ -186,7 +443,27 @@ export class PortProxy {
186
443
  return;
187
444
  }
188
445
  const remoteIP = socket.remoteAddress || '';
189
- const localPort = socket.localPort; // The port on which this connection was accepted.
446
+ const localPort = socket.localPort || 0; // The port on which this connection was accepted.
447
+ // Check rate limits
448
+ if (this.settings.maxConnectionsPerIP &&
449
+ this.getConnectionCountByIP(remoteIP) >= this.settings.maxConnectionsPerIP) {
450
+ console.log(`Connection rejected from ${remoteIP}: Maximum connections per IP (${this.settings.maxConnectionsPerIP}) exceeded`);
451
+ socket.end();
452
+ socket.destroy();
453
+ return;
454
+ }
455
+ if (this.settings.connectionRateLimitPerMinute && !this.checkConnectionRate(remoteIP)) {
456
+ console.log(`Connection rejected from ${remoteIP}: Connection rate limit (${this.settings.connectionRateLimitPerMinute}/min) exceeded`);
457
+ socket.end();
458
+ socket.destroy();
459
+ return;
460
+ }
461
+ // Apply socket optimizations
462
+ socket.setNoDelay(this.settings.noDelay);
463
+ if (this.settings.keepAlive) {
464
+ socket.setKeepAlive(true, this.settings.keepAliveInitialDelay);
465
+ }
466
+ // Create a unique connection ID and record
190
467
  const connectionId = generateConnectionId();
191
468
  const connectionRecord = {
192
469
  id: connectionId,
@@ -195,10 +472,26 @@ export class PortProxy {
195
472
  incomingStartTime: Date.now(),
196
473
  lastActivity: Date.now(),
197
474
  connectionClosed: false,
198
- pendingData: [] // Initialize buffer for pending data
475
+ pendingData: [],
476
+ pendingDataSize: 0,
477
+ // Initialize enhanced tracking fields
478
+ protocolType: 'unknown',
479
+ isPooledConnection: false,
480
+ bytesReceived: 0,
481
+ bytesSent: 0,
482
+ remoteIP: remoteIP,
483
+ localPort: localPort,
484
+ httpRequests: 0
199
485
  };
486
+ // Track connection by IP
487
+ this.trackConnectionByIP(remoteIP, connectionId);
200
488
  this.connectionRecords.set(connectionId, connectionRecord);
201
- console.log(`New connection from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionRecords.size}`);
489
+ if (this.settings.enableDetailedLogging) {
490
+ console.log(`[${connectionId}] New connection from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionRecords.size}`);
491
+ }
492
+ else {
493
+ console.log(`New connection from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionRecords.size}`);
494
+ }
202
495
  let initialDataReceived = false;
203
496
  let incomingTerminationReason = null;
204
497
  let outgoingTerminationReason = null;
@@ -206,14 +499,20 @@ export class PortProxy {
206
499
  const cleanupOnce = () => {
207
500
  this.cleanupConnection(connectionRecord);
208
501
  };
209
- // Define initiateCleanupOnce for compatibility with potential future improvements
502
+ // Define initiateCleanupOnce for compatibility
210
503
  const initiateCleanupOnce = (reason = 'normal') => {
211
- console.log(`Connection cleanup initiated for ${remoteIP} (${reason})`);
504
+ if (this.settings.enableDetailedLogging) {
505
+ console.log(`[${connectionId}] Connection cleanup initiated for ${remoteIP} (${reason})`);
506
+ }
507
+ if (incomingTerminationReason === null) {
508
+ incomingTerminationReason = reason;
509
+ this.incrementTerminationStat('incoming', reason);
510
+ }
212
511
  cleanupOnce();
213
512
  };
214
513
  // Helper to reject an incoming connection
215
514
  const rejectIncomingConnection = (reason, logMessage) => {
216
- console.log(logMessage);
515
+ console.log(`[${connectionId}] ${logMessage}`);
217
516
  socket.end();
218
517
  if (incomingTerminationReason === null) {
219
518
  incomingTerminationReason = reason;
@@ -226,27 +525,74 @@ export class PortProxy {
226
525
  if (this.settings.sniEnabled) {
227
526
  initialTimeout = setTimeout(() => {
228
527
  if (!initialDataReceived) {
229
- console.log(`Initial data timeout for ${remoteIP}`);
528
+ console.log(`[${connectionId}] Initial data timeout (${this.settings.initialDataTimeout}ms) for connection from ${remoteIP} on port ${localPort}`);
529
+ if (incomingTerminationReason === null) {
530
+ incomingTerminationReason = 'initial_timeout';
531
+ this.incrementTerminationStat('incoming', 'initial_timeout');
532
+ }
230
533
  socket.end();
231
534
  cleanupOnce();
232
535
  }
233
- }, 5000);
536
+ }, this.settings.initialDataTimeout);
234
537
  }
235
538
  else {
236
539
  initialDataReceived = true;
237
540
  }
238
541
  socket.on('error', (err) => {
239
- console.log(`Incoming socket error from ${remoteIP}: ${err.message}`);
542
+ console.log(`[${connectionId}] Incoming socket error from ${remoteIP}: ${err.message}`);
543
+ });
544
+ // Track data for bytes counting
545
+ socket.on('data', (chunk) => {
546
+ connectionRecord.bytesReceived += chunk.length;
547
+ this.updateActivity(connectionRecord);
548
+ // Detect protocol on first data chunk
549
+ if (connectionRecord.protocolType === 'unknown') {
550
+ this.detectProtocol(chunk, connectionRecord);
551
+ // Update timeout based on protocol
552
+ if (connectionRecord.cleanupTimer) {
553
+ clearTimeout(connectionRecord.cleanupTimer);
554
+ // Set new timeout based on protocol
555
+ const protocolTimeout = this.getProtocolTimeout(connectionRecord);
556
+ connectionRecord.cleanupTimer = setTimeout(() => {
557
+ console.log(`[${connectionId}] ${connectionRecord.protocolType} connection timeout after ${plugins.prettyMs(protocolTimeout)}`);
558
+ initiateCleanupOnce(`${connectionRecord.protocolType}_timeout`);
559
+ }, protocolTimeout);
560
+ }
561
+ }
562
+ else if (connectionRecord.protocolType === 'http' && isHttpRequest(chunk)) {
563
+ // Additional HTTP request on the same connection
564
+ connectionRecord.httpRequests++;
565
+ connectionRecord.lastHttpRequest = Date.now();
566
+ // Parse HTTP headers again for keep-alive changes
567
+ this.parseHttpHeaders(chunk, connectionRecord);
568
+ // Update timeout based on new HTTP headers
569
+ if (connectionRecord.cleanupTimer) {
570
+ clearTimeout(connectionRecord.cleanupTimer);
571
+ // Set new timeout based on updated HTTP info
572
+ const protocolTimeout = this.getProtocolTimeout(connectionRecord);
573
+ connectionRecord.cleanupTimer = setTimeout(() => {
574
+ console.log(`[${connectionId}] HTTP connection timeout after ${plugins.prettyMs(protocolTimeout)}`);
575
+ initiateCleanupOnce('http_timeout');
576
+ }, protocolTimeout);
577
+ }
578
+ }
240
579
  });
241
580
  const handleError = (side) => (err) => {
242
581
  const code = err.code;
243
582
  let reason = 'error';
583
+ const now = Date.now();
584
+ const connectionDuration = now - connectionRecord.incomingStartTime;
585
+ const lastActivityAge = now - connectionRecord.lastActivity;
244
586
  if (code === 'ECONNRESET') {
245
587
  reason = 'econnreset';
246
- console.log(`ECONNRESET on ${side} side from ${remoteIP}: ${err.message}`);
588
+ console.log(`[${connectionId}] ECONNRESET on ${side} side from ${remoteIP}: ${err.message}. Duration: ${plugins.prettyMs(connectionDuration)}, Last activity: ${plugins.prettyMs(lastActivityAge)} ago`);
589
+ }
590
+ else if (code === 'ETIMEDOUT') {
591
+ reason = 'etimedout';
592
+ console.log(`[${connectionId}] ETIMEDOUT on ${side} side from ${remoteIP}: ${err.message}. Duration: ${plugins.prettyMs(connectionDuration)}, Last activity: ${plugins.prettyMs(lastActivityAge)} ago`);
247
593
  }
248
594
  else {
249
- console.log(`Error on ${side} side from ${remoteIP}: ${err.message}`);
595
+ console.log(`[${connectionId}] Error on ${side} side from ${remoteIP}: ${err.message}. Duration: ${plugins.prettyMs(connectionDuration)}, Last activity: ${plugins.prettyMs(lastActivityAge)} ago`);
250
596
  }
251
597
  if (side === 'incoming' && incomingTerminationReason === null) {
252
598
  incomingTerminationReason = reason;
@@ -259,7 +605,9 @@ export class PortProxy {
259
605
  initiateCleanupOnce(reason);
260
606
  };
261
607
  const handleClose = (side) => () => {
262
- console.log(`Connection closed on ${side} side from ${remoteIP}`);
608
+ if (this.settings.enableDetailedLogging) {
609
+ console.log(`[${connectionId}] Connection closed on ${side} side from ${remoteIP}`);
610
+ }
263
611
  if (side === 'incoming' && incomingTerminationReason === null) {
264
612
  incomingTerminationReason = 'normal';
265
613
  this.incrementTerminationStat('incoming', 'normal');
@@ -285,6 +633,10 @@ export class PortProxy {
285
633
  clearTimeout(initialTimeout);
286
634
  initialTimeout = null;
287
635
  }
636
+ // Detect protocol if initial chunk is available
637
+ if (initialChunk && this.settings.enableProtocolDetection) {
638
+ this.detectProtocol(initialChunk, connectionRecord);
639
+ }
288
640
  // If a forcedDomain is provided (port-based routing), use it; otherwise, use SNI-based lookup.
289
641
  const domainConfig = forcedDomain
290
642
  ? forcedDomain
@@ -317,29 +669,81 @@ export class PortProxy {
317
669
  if (this.settings.preserveSourceIP) {
318
670
  connectionOptions.localAddress = remoteIP.replace('::ffff:', '');
319
671
  }
672
+ // Pause the incoming socket to prevent buffer overflows
673
+ socket.pause();
320
674
  // Temporary handler to collect data during connection setup
321
675
  const tempDataHandler = (chunk) => {
676
+ // Track bytes received
677
+ connectionRecord.bytesReceived += chunk.length;
678
+ // Detect protocol even during connection setup
679
+ if (this.settings.enableProtocolDetection && connectionRecord.protocolType === 'unknown') {
680
+ this.detectProtocol(chunk, connectionRecord);
681
+ }
682
+ // Check if adding this chunk would exceed the buffer limit
683
+ const newSize = connectionRecord.pendingDataSize + chunk.length;
684
+ if (this.settings.maxPendingDataSize && newSize > this.settings.maxPendingDataSize) {
685
+ console.log(`[${connectionId}] Buffer limit exceeded for connection from ${remoteIP}: ${newSize} bytes > ${this.settings.maxPendingDataSize} bytes`);
686
+ socket.end(); // Gracefully close the socket
687
+ return initiateCleanupOnce('buffer_limit_exceeded');
688
+ }
689
+ // Buffer the chunk and update the size counter
322
690
  connectionRecord.pendingData.push(Buffer.from(chunk));
691
+ connectionRecord.pendingDataSize = newSize;
323
692
  this.updateActivity(connectionRecord);
324
693
  };
325
694
  // Add the temp handler to capture all incoming data during connection setup
326
695
  socket.on('data', tempDataHandler);
327
696
  // Add initial chunk to pending data if present
328
697
  if (initialChunk) {
698
+ connectionRecord.bytesReceived += initialChunk.length;
329
699
  connectionRecord.pendingData.push(Buffer.from(initialChunk));
700
+ connectionRecord.pendingDataSize = initialChunk.length;
330
701
  }
331
702
  // Create the target socket but don't set up piping immediately
332
703
  const targetSocket = plugins.net.connect(connectionOptions);
333
704
  connectionRecord.outgoing = targetSocket;
334
705
  connectionRecord.outgoingStartTime = Date.now();
335
- // Setup error handlers immediately
336
- socket.on('error', handleError('incoming'));
337
- targetSocket.on('error', handleError('outgoing'));
338
- socket.on('close', handleClose('incoming'));
706
+ // Apply socket optimizations
707
+ targetSocket.setNoDelay(this.settings.noDelay);
708
+ if (this.settings.keepAlive) {
709
+ targetSocket.setKeepAlive(true, this.settings.keepAliveInitialDelay);
710
+ }
711
+ // Setup specific error handler for connection phase
712
+ targetSocket.once('error', (err) => {
713
+ // This handler runs only once during the initial connection phase
714
+ const code = err.code;
715
+ console.log(`[${connectionId}] Connection setup error to ${targetHost}:${connectionOptions.port}: ${err.message} (${code})`);
716
+ // Resume the incoming socket to prevent it from hanging
717
+ socket.resume();
718
+ if (code === 'ECONNREFUSED') {
719
+ console.log(`[${connectionId}] Target ${targetHost}:${connectionOptions.port} refused connection`);
720
+ }
721
+ else if (code === 'ETIMEDOUT') {
722
+ console.log(`[${connectionId}] Connection to ${targetHost}:${connectionOptions.port} timed out`);
723
+ }
724
+ else if (code === 'ECONNRESET') {
725
+ console.log(`[${connectionId}] Connection to ${targetHost}:${connectionOptions.port} was reset`);
726
+ }
727
+ else if (code === 'EHOSTUNREACH') {
728
+ console.log(`[${connectionId}] Host ${targetHost} is unreachable`);
729
+ }
730
+ // Clear any existing error handler after connection phase
731
+ targetSocket.removeAllListeners('error');
732
+ // Re-add the normal error handler for established connections
733
+ targetSocket.on('error', handleError('outgoing'));
734
+ if (outgoingTerminationReason === null) {
735
+ outgoingTerminationReason = 'connection_failed';
736
+ this.incrementTerminationStat('outgoing', 'connection_failed');
737
+ }
738
+ // Clean up the connection
739
+ initiateCleanupOnce(`connection_failed_${code}`);
740
+ });
741
+ // Setup close handler
339
742
  targetSocket.on('close', handleClose('outgoing'));
743
+ socket.on('close', handleClose('incoming'));
340
744
  // Handle timeouts
341
745
  socket.on('timeout', () => {
342
- console.log(`Timeout on incoming side from ${remoteIP}`);
746
+ console.log(`[${connectionId}] Timeout on incoming side from ${remoteIP} after ${plugins.prettyMs(this.settings.socketTimeout || 300000)}`);
343
747
  if (incomingTerminationReason === null) {
344
748
  incomingTerminationReason = 'timeout';
345
749
  this.incrementTerminationStat('incoming', 'timeout');
@@ -347,18 +751,27 @@ export class PortProxy {
347
751
  initiateCleanupOnce('timeout_incoming');
348
752
  });
349
753
  targetSocket.on('timeout', () => {
350
- console.log(`Timeout on outgoing side from ${remoteIP}`);
754
+ console.log(`[${connectionId}] Timeout on outgoing side from ${remoteIP} after ${plugins.prettyMs(this.settings.socketTimeout || 300000)}`);
351
755
  if (outgoingTerminationReason === null) {
352
756
  outgoingTerminationReason = 'timeout';
353
757
  this.incrementTerminationStat('outgoing', 'timeout');
354
758
  }
355
759
  initiateCleanupOnce('timeout_outgoing');
356
760
  });
357
- // Set appropriate timeouts
358
- socket.setTimeout(120000);
359
- targetSocket.setTimeout(120000);
761
+ // Set appropriate timeouts using the configured value
762
+ socket.setTimeout(this.settings.socketTimeout || 300000);
763
+ targetSocket.setTimeout(this.settings.socketTimeout || 300000);
764
+ // Track outgoing data for bytes counting
765
+ targetSocket.on('data', (chunk) => {
766
+ connectionRecord.bytesSent += chunk.length;
767
+ this.updateActivity(connectionRecord);
768
+ });
360
769
  // Wait for the outgoing connection to be ready before setting up piping
361
770
  targetSocket.once('connect', () => {
771
+ // Clear the initial connection error handler
772
+ targetSocket.removeAllListeners('error');
773
+ // Add the normal error handler for established connections
774
+ targetSocket.on('error', handleError('outgoing'));
362
775
  // Remove temporary data handler
363
776
  socket.removeListener('data', tempDataHandler);
364
777
  // Flush all pending data to target
@@ -366,34 +779,43 @@ export class PortProxy {
366
779
  const combinedData = Buffer.concat(connectionRecord.pendingData);
367
780
  targetSocket.write(combinedData, (err) => {
368
781
  if (err) {
369
- console.log(`Error writing pending data to target: ${err.message}`);
782
+ console.log(`[${connectionId}] Error writing pending data to target: ${err.message}`);
370
783
  return initiateCleanupOnce('write_error');
371
784
  }
372
- // Now set up piping for future data
785
+ // Now set up piping for future data and resume the socket
373
786
  socket.pipe(targetSocket);
374
787
  targetSocket.pipe(socket);
375
- console.log(`Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
376
- `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}`);
788
+ socket.resume(); // Resume the socket after piping is established
789
+ if (this.settings.enableDetailedLogging) {
790
+ console.log(`[${connectionId}] Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
791
+ `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}` +
792
+ ` Protocol: ${connectionRecord.protocolType}`);
793
+ }
794
+ else {
795
+ console.log(`Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
796
+ `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}`);
797
+ }
377
798
  });
378
799
  }
379
800
  else {
380
801
  // No pending data, so just set up piping
381
802
  socket.pipe(targetSocket);
382
803
  targetSocket.pipe(socket);
383
- console.log(`Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
384
- `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}`);
804
+ socket.resume(); // Resume the socket after piping is established
805
+ if (this.settings.enableDetailedLogging) {
806
+ console.log(`[${connectionId}] Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
807
+ `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}` +
808
+ ` Protocol: ${connectionRecord.protocolType}`);
809
+ }
810
+ else {
811
+ console.log(`Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
812
+ `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}`);
813
+ }
385
814
  }
386
815
  // Clear the buffer now that we've processed it
387
816
  connectionRecord.pendingData = [];
388
- // Set up activity tracking
389
- socket.on('data', () => {
390
- connectionRecord.lastActivity = Date.now();
391
- });
392
- targetSocket.on('data', () => {
393
- connectionRecord.lastActivity = Date.now();
394
- });
395
- // Add the renegotiation listener (we don't need setImmediate here anymore
396
- // since we're already in the connect callback)
817
+ connectionRecord.pendingDataSize = 0;
818
+ // Add the renegotiation listener for SNI validation
397
819
  if (serverName) {
398
820
  socket.on('data', (renegChunk) => {
399
821
  if (renegChunk.length > 0 && renegChunk.readUInt8(0) === 22) {
@@ -401,38 +823,43 @@ export class PortProxy {
401
823
  // Try to extract SNI from potential renegotiation
402
824
  const newSNI = extractSNI(renegChunk);
403
825
  if (newSNI && newSNI !== connectionRecord.lockedDomain) {
404
- console.log(`Rehandshake detected with different SNI: ${newSNI} vs locked ${connectionRecord.lockedDomain}. Terminating connection.`);
826
+ console.log(`[${connectionId}] Rehandshake detected with different SNI: ${newSNI} vs locked ${connectionRecord.lockedDomain}. Terminating connection.`);
405
827
  initiateCleanupOnce('sni_mismatch');
406
828
  }
407
- else if (newSNI) {
408
- console.log(`Rehandshake detected with same SNI: ${newSNI}. Allowing.`);
829
+ else if (newSNI && this.settings.enableDetailedLogging) {
830
+ console.log(`[${connectionId}] Rehandshake detected with same SNI: ${newSNI}. Allowing.`);
409
831
  }
410
832
  }
411
833
  catch (err) {
412
- console.log(`Error processing potential renegotiation: ${err}. Allowing connection to continue.`);
834
+ console.log(`[${connectionId}] Error processing potential renegotiation: ${err}. Allowing connection to continue.`);
413
835
  }
414
836
  }
415
837
  });
416
838
  }
417
- });
418
- // Initialize a cleanup timer for max connection lifetime
419
- if (this.settings.maxConnectionLifetime) {
839
+ // Set protocol-specific timeout based on detected protocol
840
+ if (connectionRecord.cleanupTimer) {
841
+ clearTimeout(connectionRecord.cleanupTimer);
842
+ }
843
+ // Set timeout based on protocol
844
+ const protocolTimeout = this.getProtocolTimeout(connectionRecord, domainConfig);
420
845
  connectionRecord.cleanupTimer = setTimeout(() => {
421
- console.log(`Connection from ${remoteIP} exceeded max lifetime (${this.settings.maxConnectionLifetime}ms), forcing cleanup.`);
422
- initiateCleanupOnce('max_lifetime');
423
- }, this.settings.maxConnectionLifetime);
424
- }
846
+ console.log(`[${connectionId}] ${connectionRecord.protocolType} connection exceeded max lifetime (${plugins.prettyMs(protocolTimeout)}), forcing cleanup.`);
847
+ initiateCleanupOnce(`${connectionRecord.protocolType}_max_lifetime`);
848
+ }, protocolTimeout);
849
+ });
425
850
  };
426
851
  // --- PORT RANGE-BASED HANDLING ---
427
852
  // Only apply port-based rules if the incoming port is within one of the global port ranges.
428
853
  if (this.settings.globalPortRanges && isPortInRanges(localPort, this.settings.globalPortRanges)) {
429
854
  if (this.settings.forwardAllGlobalRanges) {
430
855
  if (this.settings.defaultAllowedIPs && !isAllowed(remoteIP, this.settings.defaultAllowedIPs)) {
431
- console.log(`Connection from ${remoteIP} rejected: IP ${remoteIP} not allowed in global default allowed list.`);
856
+ console.log(`[${connectionId}] Connection from ${remoteIP} rejected: IP ${remoteIP} not allowed in global default allowed list.`);
432
857
  socket.end();
433
858
  return;
434
859
  }
435
- console.log(`Port-based connection from ${remoteIP} on port ${localPort} forwarded to global target IP ${this.settings.targetIP}.`);
860
+ if (this.settings.enableDetailedLogging) {
861
+ console.log(`[${connectionId}] Port-based connection from ${remoteIP} on port ${localPort} forwarded to global target IP ${this.settings.targetIP}.`);
862
+ }
436
863
  setupConnection('', undefined, {
437
864
  domains: ['global'],
438
865
  allowedIPs: this.settings.defaultAllowedIPs || [],
@@ -455,11 +882,13 @@ export class PortProxy {
455
882
  ...(this.settings.defaultBlockedIPs || [])
456
883
  ];
457
884
  if (!isGlobIPAllowed(remoteIP, effectiveAllowedIPs, effectiveBlockedIPs)) {
458
- console.log(`Connection from ${remoteIP} rejected: IP not allowed for domain ${forcedDomain.domains.join(', ')} on port ${localPort}.`);
885
+ console.log(`[${connectionId}] Connection from ${remoteIP} rejected: IP not allowed for domain ${forcedDomain.domains.join(', ')} on port ${localPort}.`);
459
886
  socket.end();
460
887
  return;
461
888
  }
462
- console.log(`Port-based connection from ${remoteIP} on port ${localPort} matched domain ${forcedDomain.domains.join(', ')}.`);
889
+ if (this.settings.enableDetailedLogging) {
890
+ console.log(`[${connectionId}] Port-based connection from ${remoteIP} on port ${localPort} matched domain ${forcedDomain.domains.join(', ')}.`);
891
+ }
463
892
  setupConnection('', undefined, forcedDomain, localPort);
464
893
  return;
465
894
  }
@@ -478,7 +907,9 @@ export class PortProxy {
478
907
  const serverName = extractSNI(chunk) || '';
479
908
  // Lock the connection to the negotiated SNI.
480
909
  connectionRecord.lockedDomain = serverName;
481
- console.log(`Received connection from ${remoteIP} with SNI: ${serverName}`);
910
+ if (this.settings.enableDetailedLogging) {
911
+ console.log(`[${connectionId}] Received connection from ${remoteIP} with SNI: ${serverName || '(empty)'}`);
912
+ }
482
913
  setupConnection(serverName, chunk);
483
914
  });
484
915
  }
@@ -518,19 +949,44 @@ export class PortProxy {
518
949
  });
519
950
  this.netServers.push(server);
520
951
  }
521
- // Log active connection count, longest running durations, and run parity checks every 10 seconds.
952
+ // Log active connection count, longest running durations, and run parity checks periodically
522
953
  this.connectionLogger = setInterval(() => {
954
+ // Immediately return if shutting down
523
955
  if (this.isShuttingDown)
524
956
  return;
525
957
  const now = Date.now();
526
958
  let maxIncoming = 0;
527
959
  let maxOutgoing = 0;
960
+ let httpConnections = 0;
961
+ let wsConnections = 0;
962
+ let tlsConnections = 0;
963
+ let unknownConnections = 0;
964
+ let pooledConnections = 0;
528
965
  // Create a copy of the keys to avoid modification during iteration
529
966
  const connectionIds = [...this.connectionRecords.keys()];
530
967
  for (const id of connectionIds) {
531
968
  const record = this.connectionRecords.get(id);
532
969
  if (!record)
533
970
  continue;
971
+ // Track connection stats by protocol
972
+ switch (record.protocolType) {
973
+ case 'http':
974
+ httpConnections++;
975
+ break;
976
+ case 'websocket':
977
+ wsConnections++;
978
+ break;
979
+ case 'tls':
980
+ case 'https':
981
+ tlsConnections++;
982
+ break;
983
+ default:
984
+ unknownConnections++;
985
+ break;
986
+ }
987
+ if (record.isPooledConnection) {
988
+ pooledConnections++;
989
+ }
534
990
  maxIncoming = Math.max(maxIncoming, now - record.incomingStartTime);
535
991
  if (record.outgoingStartTime) {
536
992
  maxOutgoing = Math.max(maxOutgoing, now - record.outgoingStartTime);
@@ -540,31 +996,60 @@ export class PortProxy {
540
996
  !record.incoming.destroyed &&
541
997
  !record.connectionClosed &&
542
998
  (now - record.outgoingClosedTime > 30000)) {
543
- const remoteIP = record.incoming.remoteAddress || 'unknown';
544
- console.log(`Parity check: Incoming socket for ${remoteIP} still active ${plugins.prettyMs(now - record.outgoingClosedTime)} after outgoing closed.`);
999
+ const remoteIP = record.remoteIP;
1000
+ console.log(`[${id}] Parity check: Incoming socket for ${remoteIP} still active ${plugins.prettyMs(now - record.outgoingClosedTime)} after outgoing closed.`);
545
1001
  this.cleanupConnection(record, 'parity_check');
546
1002
  }
547
- // Inactivity check
548
- const inactivityTime = now - record.lastActivity;
549
- if (inactivityTime > 180000 && // 3 minutes
550
- !record.connectionClosed) {
551
- const remoteIP = record.incoming.remoteAddress || 'unknown';
552
- console.log(`Inactivity check: No activity on connection from ${remoteIP} for ${plugins.prettyMs(inactivityTime)}.`);
553
- this.cleanupConnection(record, 'inactivity');
1003
+ // Skip inactivity check if disabled
1004
+ if (!this.settings.disableInactivityCheck) {
1005
+ // Inactivity check - use protocol-specific values
1006
+ let inactivityThreshold = 180000; // 3 minutes default
1007
+ // Set protocol-specific inactivity thresholds
1008
+ if (record.protocolType === 'http' && record.isPooledConnection) {
1009
+ inactivityThreshold = this.settings.httpKeepAliveTimeout || 1200000; // 20 minutes for pooled HTTP
1010
+ }
1011
+ else if (record.protocolType === 'websocket') {
1012
+ inactivityThreshold = this.settings.wsConnectionTimeout || 14400000; // 4 hours for WebSocket
1013
+ }
1014
+ else if (record.protocolType === 'http') {
1015
+ inactivityThreshold = this.settings.httpConnectionTimeout || 1800000; // 30 minutes for HTTP
1016
+ }
1017
+ const inactivityTime = now - record.lastActivity;
1018
+ if (inactivityTime > inactivityThreshold && !record.connectionClosed) {
1019
+ console.log(`[${id}] Inactivity check: No activity on ${record.protocolType} connection from ${record.remoteIP} for ${plugins.prettyMs(inactivityTime)}.`);
1020
+ this.cleanupConnection(record, 'inactivity');
1021
+ }
554
1022
  }
555
1023
  }
556
- console.log(`(Interval Log) Active connections: ${this.connectionRecords.size}. ` +
557
- `Longest running incoming: ${plugins.prettyMs(maxIncoming)}, outgoing: ${plugins.prettyMs(maxOutgoing)}. ` +
558
- `Termination stats (incoming): ${JSON.stringify(this.terminationStats.incoming)}, ` +
559
- `(outgoing): ${JSON.stringify(this.terminationStats.outgoing)}`);
560
- }, 10000);
1024
+ // Log detailed stats periodically
1025
+ console.log(`Active connections: ${this.connectionRecords.size}. ` +
1026
+ `Types: HTTP=${httpConnections}, WS=${wsConnections}, TLS=${tlsConnections}, Unknown=${unknownConnections}, Pooled=${pooledConnections}. ` +
1027
+ `Longest running: IN=${plugins.prettyMs(maxIncoming)}, OUT=${plugins.prettyMs(maxOutgoing)}. ` +
1028
+ `Termination stats: ${JSON.stringify({ IN: this.terminationStats.incoming, OUT: this.terminationStats.outgoing })}`);
1029
+ }, this.settings.inactivityCheckInterval || 30000);
1030
+ // Make sure the interval doesn't keep the process alive
1031
+ if (this.connectionLogger.unref) {
1032
+ this.connectionLogger.unref();
1033
+ }
561
1034
  }
1035
+ /**
1036
+ * Gracefully shut down the proxy
1037
+ */
562
1038
  async stop() {
563
1039
  console.log("PortProxy shutting down...");
564
1040
  this.isShuttingDown = true;
565
1041
  // Stop accepting new connections
566
1042
  const closeServerPromises = this.netServers.map(server => new Promise((resolve) => {
567
- server.close(() => resolve());
1043
+ if (!server.listening) {
1044
+ resolve();
1045
+ return;
1046
+ }
1047
+ server.close((err) => {
1048
+ if (err) {
1049
+ console.log(`Error closing server: ${err.message}`);
1050
+ }
1051
+ resolve();
1052
+ });
568
1053
  }));
569
1054
  // Stop the connection logger
570
1055
  if (this.connectionLogger) {
@@ -574,44 +1059,70 @@ export class PortProxy {
574
1059
  // Wait for servers to close
575
1060
  await Promise.all(closeServerPromises);
576
1061
  console.log("All servers closed. Cleaning up active connections...");
577
- // Clean up active connections
1062
+ // Force destroy all active connections immediately
578
1063
  const connectionIds = [...this.connectionRecords.keys()];
579
1064
  console.log(`Cleaning up ${connectionIds.length} active connections...`);
1065
+ // First pass: End all connections gracefully
580
1066
  for (const id of connectionIds) {
581
1067
  const record = this.connectionRecords.get(id);
582
- if (record && !record.connectionClosed) {
583
- this.cleanupConnection(record, 'shutdown');
1068
+ if (record) {
1069
+ try {
1070
+ // Clear any timers
1071
+ if (record.cleanupTimer) {
1072
+ clearTimeout(record.cleanupTimer);
1073
+ record.cleanupTimer = undefined;
1074
+ }
1075
+ // End sockets gracefully
1076
+ if (record.incoming && !record.incoming.destroyed) {
1077
+ record.incoming.end();
1078
+ }
1079
+ if (record.outgoing && !record.outgoing.destroyed) {
1080
+ record.outgoing.end();
1081
+ }
1082
+ }
1083
+ catch (err) {
1084
+ console.log(`Error during graceful connection end for ${id}: ${err}`);
1085
+ }
584
1086
  }
585
1087
  }
586
- // Wait for graceful shutdown or timeout
587
- const shutdownTimeout = this.settings.gracefulShutdownTimeout || 30000;
588
- await new Promise((resolve) => {
589
- const checkInterval = setInterval(() => {
590
- if (this.connectionRecords.size === 0) {
591
- clearInterval(checkInterval);
592
- resolve(); // lets resolve here as early as we reach 0 remaining connections
593
- }
594
- }, 1000);
595
- // Force resolve after timeout
596
- setTimeout(() => {
597
- clearInterval(checkInterval);
598
- if (this.connectionRecords.size > 0) {
599
- console.log(`Forcing shutdown with ${this.connectionRecords.size} connections still active`);
600
- // Force destroy any remaining connections
601
- for (const record of this.connectionRecords.values()) {
1088
+ // Short delay to allow graceful ends to process
1089
+ await new Promise(resolve => setTimeout(resolve, 100));
1090
+ // Second pass: Force destroy everything
1091
+ for (const id of connectionIds) {
1092
+ const record = this.connectionRecords.get(id);
1093
+ if (record) {
1094
+ try {
1095
+ // Remove all listeners to prevent memory leaks
1096
+ if (record.incoming) {
1097
+ record.incoming.removeAllListeners();
602
1098
  if (!record.incoming.destroyed) {
603
1099
  record.incoming.destroy();
604
1100
  }
605
- if (record.outgoing && !record.outgoing.destroyed) {
1101
+ }
1102
+ if (record.outgoing) {
1103
+ record.outgoing.removeAllListeners();
1104
+ if (!record.outgoing.destroyed) {
606
1105
  record.outgoing.destroy();
607
1106
  }
608
1107
  }
609
- this.connectionRecords.clear();
610
1108
  }
611
- resolve();
612
- }, shutdownTimeout);
613
- });
1109
+ catch (err) {
1110
+ console.log(`Error during forced connection destruction for ${id}: ${err}`);
1111
+ }
1112
+ }
1113
+ }
1114
+ // Clear all tracking maps
1115
+ this.connectionRecords.clear();
1116
+ this.domainTargetIndices.clear();
1117
+ this.connectionsByIP.clear();
1118
+ this.connectionRateByIP.clear();
1119
+ this.netServers = [];
1120
+ // Reset termination stats
1121
+ this.terminationStats = {
1122
+ incoming: {},
1123
+ outgoing: {}
1124
+ };
614
1125
  console.log("PortProxy shutdown complete.");
615
1126
  }
616
1127
  }
617
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQTJCeEM7Ozs7R0FJRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV4QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLElBQUksVUFBVSxLQUFLLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlCQUFpQjtJQUUxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsWUFBWTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRXZELE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9DLElBQUksYUFBYSxLQUFLLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGtCQUFrQjtJQUU3RCxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBQ3JELE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsaUNBQWlDO0lBRW5ELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsTUFBTSxJQUFJLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxrQkFBa0I7SUFFakQsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FB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
1128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQXlGeEM7Ozs7R0FJRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV4QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLElBQUksVUFBVSxLQUFLLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlCQUFpQjtJQUUxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsWUFBWTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRXZELE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9DLElBQUksYUFBYSxLQUFLLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGtCQUFrQjtJQUU3RCxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBQ3JELE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsaUNBQWlDO0lBRW5ELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsTUFBTSxJQUFJLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxrQkFBa0I7SUFFakQsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FB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