@push.rocks/smartproxy 3.20.2 → 3.21.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.
@@ -86,12 +86,17 @@ const isGlobIPAllowed = (ip, allowed, blocked = []) => {
86
86
  return false;
87
87
  return isAllowed(ip, allowed);
88
88
  };
89
+ // Helper: Generate a unique ID for a connection
90
+ const generateConnectionId = () => {
91
+ return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
92
+ };
89
93
  export class PortProxy {
90
94
  constructor(settingsArg) {
91
95
  this.netServers = [];
92
96
  // Unified record tracking each connection pair.
93
- this.connectionRecords = new Set();
97
+ this.connectionRecords = new Map();
94
98
  this.connectionLogger = null;
99
+ this.isShuttingDown = false;
95
100
  // Map to track round robin indices for each domain config.
96
101
  this.domainTargetIndices = new Map();
97
102
  this.terminationStats = {
@@ -102,37 +107,80 @@ export class PortProxy {
102
107
  ...settingsArg,
103
108
  targetIP: settingsArg.targetIP || 'localhost',
104
109
  maxConnectionLifetime: settingsArg.maxConnectionLifetime || 600000,
110
+ gracefulShutdownTimeout: settingsArg.gracefulShutdownTimeout || 30000,
105
111
  };
106
112
  }
107
113
  incrementTerminationStat(side, reason) {
108
114
  this.terminationStats[side][reason] = (this.terminationStats[side][reason] || 0) + 1;
109
115
  }
110
116
  /**
111
- * Cleans up a connection record if not already cleaned up.
112
- * Destroys both incoming and outgoing sockets, clears timers, and removes the record.
113
- * Logs the cleanup event.
117
+ * Initiates the cleanup process for a connection.
118
+ * Sets the flag to prevent duplicate cleanup attempts and schedules actual cleanup.
119
+ */
120
+ initiateCleanup(record, reason = 'normal') {
121
+ if (record.cleanupInitiated)
122
+ return;
123
+ record.cleanupInitiated = true;
124
+ const remoteIP = record.incoming.remoteAddress || 'unknown';
125
+ console.log(`Initiating cleanup for connection ${record.id} from ${remoteIP} (reason: ${reason})`);
126
+ // Execute cleanup immediately to prevent lingering connections
127
+ this.executeCleanup(record);
128
+ }
129
+ /**
130
+ * Executes the actual cleanup of a connection.
131
+ * Destroys sockets, clears timers, and removes the record.
114
132
  */
115
- cleanupConnection(record, special = false) {
116
- if (!record.connectionClosed) {
117
- record.connectionClosed = true;
118
- if (record.cleanupTimer) {
119
- clearTimeout(record.cleanupTimer);
133
+ executeCleanup(record) {
134
+ if (record.connectionClosed)
135
+ return;
136
+ record.connectionClosed = true;
137
+ const remoteIP = record.incoming.remoteAddress || 'unknown';
138
+ if (record.cleanupTimer) {
139
+ clearTimeout(record.cleanupTimer);
140
+ record.cleanupTimer = undefined;
141
+ }
142
+ // End the sockets first to allow for graceful closure
143
+ try {
144
+ if (!record.incoming.destroyed) {
145
+ record.incoming.end();
146
+ // Set a safety timeout to force destroy if end doesn't complete
147
+ setTimeout(() => {
148
+ if (!record.incoming.destroyed) {
149
+ console.log(`Forcing destruction of incoming socket for ${remoteIP}`);
150
+ record.incoming.destroy();
151
+ }
152
+ }, 1000);
120
153
  }
154
+ }
155
+ catch (err) {
156
+ console.error(`Error ending incoming socket for ${remoteIP}:`, err);
121
157
  if (!record.incoming.destroyed) {
122
158
  record.incoming.destroy();
123
159
  }
160
+ }
161
+ try {
124
162
  if (record.outgoing && !record.outgoing.destroyed) {
125
- record.outgoing.destroy();
126
- }
127
- this.connectionRecords.delete(record);
128
- const remoteIP = record.incoming.remoteAddress || 'unknown';
129
- if (special) {
130
- console.log(`Special parity cleanup: Connection from ${remoteIP} cleaned up due to duration difference.`);
163
+ record.outgoing.end();
164
+ // Set a safety timeout to force destroy if end doesn't complete
165
+ setTimeout(() => {
166
+ if (record.outgoing && !record.outgoing.destroyed) {
167
+ console.log(`Forcing destruction of outgoing socket for ${remoteIP}`);
168
+ record.outgoing.destroy();
169
+ }
170
+ }, 1000);
131
171
  }
132
- else {
133
- console.log(`Connection from ${remoteIP} terminated. Active connections: ${this.connectionRecords.size}`);
172
+ }
173
+ catch (err) {
174
+ console.error(`Error ending outgoing socket for ${remoteIP}:`, err);
175
+ if (record.outgoing && !record.outgoing.destroyed) {
176
+ record.outgoing.destroy();
134
177
  }
135
178
  }
179
+ // Remove the record after a delay to ensure all events have propagated
180
+ setTimeout(() => {
181
+ this.connectionRecords.delete(record.id);
182
+ console.log(`Connection ${record.id} from ${remoteIP} fully cleaned up. Active connections: ${this.connectionRecords.size}`);
183
+ }, 2000);
136
184
  }
137
185
  getTargetIP(domainConfig) {
138
186
  if (domainConfig.targetIPs && domainConfig.targetIPs.length > 0) {
@@ -143,25 +191,52 @@ export class PortProxy {
143
191
  }
144
192
  return this.settings.targetIP;
145
193
  }
194
+ /**
195
+ * Updates the last activity timestamp for a connection record
196
+ */
197
+ updateActivity(record) {
198
+ record.lastActivity = Date.now();
199
+ // Reset the inactivity timer if one is set
200
+ if (this.settings.maxConnectionLifetime && record.cleanupTimer) {
201
+ clearTimeout(record.cleanupTimer);
202
+ // Set a new cleanup timer
203
+ record.cleanupTimer = setTimeout(() => {
204
+ const now = Date.now();
205
+ const inactivityTime = now - record.lastActivity;
206
+ const remoteIP = record.incoming.remoteAddress || 'unknown';
207
+ console.log(`Connection ${record.id} from ${remoteIP} exceeded max lifetime or inactivity period (${inactivityTime}ms), forcing cleanup.`);
208
+ this.initiateCleanup(record, 'timeout');
209
+ }, this.settings.maxConnectionLifetime);
210
+ }
211
+ }
146
212
  async start() {
147
213
  // Define a unified connection handler for all listening ports.
148
214
  const connectionHandler = (socket) => {
215
+ if (this.isShuttingDown) {
216
+ socket.end();
217
+ socket.destroy();
218
+ return;
219
+ }
149
220
  const remoteIP = socket.remoteAddress || '';
150
221
  const localPort = socket.localPort; // The port on which this connection was accepted.
222
+ const connectionId = generateConnectionId();
151
223
  const connectionRecord = {
224
+ id: connectionId,
152
225
  incoming: socket,
153
226
  outgoing: null,
154
227
  incomingStartTime: Date.now(),
228
+ lastActivity: Date.now(),
155
229
  connectionClosed: false,
230
+ cleanupInitiated: false
156
231
  };
157
- this.connectionRecords.add(connectionRecord);
158
- console.log(`New connection from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionRecords.size}`);
232
+ this.connectionRecords.set(connectionId, connectionRecord);
233
+ console.log(`New connection ${connectionId} from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionRecords.size}`);
159
234
  let initialDataReceived = false;
160
235
  let incomingTerminationReason = null;
161
236
  let outgoingTerminationReason = null;
162
237
  // Local cleanup function that delegates to the class method.
163
- const cleanupOnce = () => {
164
- this.cleanupConnection(connectionRecord);
238
+ const initiateCleanupOnce = (reason = 'normal') => {
239
+ this.initiateCleanup(connectionRecord, reason);
165
240
  };
166
241
  // Helper to reject an incoming connection.
167
242
  const rejectIncomingConnection = (reason, logMessage) => {
@@ -171,13 +246,28 @@ export class PortProxy {
171
246
  incomingTerminationReason = reason;
172
247
  this.incrementTerminationStat('incoming', reason);
173
248
  }
174
- cleanupOnce();
249
+ initiateCleanupOnce(reason);
175
250
  };
251
+ // Set an initial timeout immediately
252
+ const initialTimeout = setTimeout(() => {
253
+ if (!initialDataReceived) {
254
+ console.log(`Initial connection timeout for ${remoteIP} (no data received)`);
255
+ if (incomingTerminationReason === null) {
256
+ incomingTerminationReason = 'initial_timeout';
257
+ this.incrementTerminationStat('incoming', 'initial_timeout');
258
+ }
259
+ initiateCleanupOnce('initial_timeout');
260
+ }
261
+ }, 5000);
176
262
  socket.on('error', (err) => {
177
263
  const errorMessage = initialDataReceived
178
264
  ? `(Immediate) Incoming socket error from ${remoteIP}: ${err.message}`
179
265
  : `(Premature) Incoming socket error from ${remoteIP} before data received: ${err.message}`;
180
266
  console.log(errorMessage);
267
+ // Clear the initial timeout if it exists
268
+ if (initialTimeout) {
269
+ clearTimeout(initialTimeout);
270
+ }
181
271
  });
182
272
  const handleError = (side) => (err) => {
183
273
  const code = err.code;
@@ -186,6 +276,10 @@ export class PortProxy {
186
276
  reason = 'econnreset';
187
277
  console.log(`ECONNRESET on ${side} side from ${remoteIP}: ${err.message}`);
188
278
  }
279
+ else if (code === 'ECONNREFUSED') {
280
+ reason = 'econnrefused';
281
+ console.log(`ECONNREFUSED on ${side} side from ${remoteIP}: ${err.message}`);
282
+ }
189
283
  else {
190
284
  console.log(`Error on ${side} side from ${remoteIP}: ${err.message}`);
191
285
  }
@@ -197,7 +291,7 @@ export class PortProxy {
197
291
  outgoingTerminationReason = reason;
198
292
  this.incrementTerminationStat('outgoing', reason);
199
293
  }
200
- cleanupOnce();
294
+ initiateCleanupOnce(reason);
201
295
  };
202
296
  const handleClose = (side) => () => {
203
297
  console.log(`Connection closed on ${side} side from ${remoteIP}`);
@@ -210,17 +304,35 @@ export class PortProxy {
210
304
  this.incrementTerminationStat('outgoing', 'normal');
211
305
  // Record the time when outgoing socket closed.
212
306
  connectionRecord.outgoingClosedTime = Date.now();
307
+ // If incoming is still active but outgoing closed, set a shorter timeout
308
+ if (!connectionRecord.incoming.destroyed) {
309
+ console.log(`Outgoing socket closed but incoming still active for ${remoteIP}. Setting cleanup timeout.`);
310
+ setTimeout(() => {
311
+ if (!connectionRecord.connectionClosed && !connectionRecord.incoming.destroyed) {
312
+ console.log(`Incoming socket still active ${Date.now() - connectionRecord.outgoingClosedTime}ms after outgoing closed for ${remoteIP}. Cleaning up.`);
313
+ initiateCleanupOnce('outgoing_closed_timeout');
314
+ }
315
+ }, 10000); // 10 second timeout instead of waiting for the next parity check
316
+ }
317
+ }
318
+ // If both sides are closed/destroyed, clean up
319
+ if ((side === 'incoming' && connectionRecord.outgoing?.destroyed) ||
320
+ (side === 'outgoing' && connectionRecord.incoming.destroyed)) {
321
+ initiateCleanupOnce('both_closed');
213
322
  }
214
- cleanupOnce();
215
323
  };
216
324
  /**
217
325
  * Sets up the connection to the target host.
218
326
  * @param serverName - The SNI hostname (unused when forcedDomain is provided).
219
327
  * @param initialChunk - Optional initial data chunk.
220
328
  * @param forcedDomain - If provided, overrides SNI/domain lookup (used for port-based routing).
221
- * @param overridePort - If provided, use this port for the outgoing connection (typically the same as the incoming port).
329
+ * @param overridePort - If provided, use this port for the outgoing connection.
222
330
  */
223
331
  const setupConnection = (serverName, initialChunk, forcedDomain, overridePort) => {
332
+ // Clear the initial timeout since we've received data
333
+ if (initialTimeout) {
334
+ clearTimeout(initialTimeout);
335
+ }
224
336
  // If a forcedDomain is provided (port-based routing), use it; otherwise, use SNI-based lookup.
225
337
  const domainConfig = forcedDomain
226
338
  ? forcedDomain
@@ -239,11 +351,15 @@ export class PortProxy {
239
351
  return rejectIncomingConnection('rejected', `Connection rejected: IP ${remoteIP} not allowed for domain ${domainConfig.domains.join(', ')}`);
240
352
  }
241
353
  }
242
- else if (this.settings.defaultAllowedIPs) {
354
+ else if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
243
355
  if (!isGlobIPAllowed(remoteIP, this.settings.defaultAllowedIPs, this.settings.defaultBlockedIPs || [])) {
244
356
  return rejectIncomingConnection('rejected', `Connection rejected: IP ${remoteIP} not allowed by default allowed list`);
245
357
  }
246
358
  }
359
+ else {
360
+ // No domain config and no default allowed IPs - reject the connection
361
+ return rejectIncomingConnection('no_config', `Connection rejected: No matching domain configuration or default allowed IPs for ${remoteIP}`);
362
+ }
247
363
  const targetHost = domainConfig ? this.getTargetIP(domainConfig) : this.settings.targetIP;
248
364
  const connectionOptions = {
249
365
  host: targetHost,
@@ -252,29 +368,81 @@ export class PortProxy {
252
368
  if (this.settings.preserveSourceIP) {
253
369
  connectionOptions.localAddress = remoteIP.replace('::ffff:', '');
254
370
  }
371
+ // Add explicit connection timeout and error handling
372
+ let connectionTimeout = null;
373
+ let connectionSucceeded = false;
374
+ // Set connection timeout
375
+ connectionTimeout = setTimeout(() => {
376
+ if (!connectionSucceeded) {
377
+ console.log(`Connection timeout connecting to ${targetHost}:${connectionOptions.port} for ${remoteIP}`);
378
+ if (outgoingTerminationReason === null) {
379
+ outgoingTerminationReason = 'connection_timeout';
380
+ this.incrementTerminationStat('outgoing', 'connection_timeout');
381
+ }
382
+ initiateCleanupOnce('connection_timeout');
383
+ }
384
+ }, 5000);
385
+ console.log(`Attempting to connect to ${targetHost}:${connectionOptions.port} for client ${remoteIP}...`);
386
+ // Create the target socket
255
387
  const targetSocket = plugins.net.connect(connectionOptions);
256
388
  connectionRecord.outgoing = targetSocket;
257
- connectionRecord.outgoingStartTime = Date.now();
258
- console.log(`Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
259
- `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}`);
389
+ // Handle successful connection
390
+ targetSocket.once('connect', () => {
391
+ connectionSucceeded = true;
392
+ if (connectionTimeout) {
393
+ clearTimeout(connectionTimeout);
394
+ connectionTimeout = null;
395
+ }
396
+ connectionRecord.outgoingStartTime = Date.now();
397
+ console.log(`Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
398
+ `${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}`);
399
+ // Setup data flow after confirmed connection
400
+ setupDataFlow(targetSocket, initialChunk);
401
+ });
402
+ // Handle connection errors early
403
+ targetSocket.once('error', (err) => {
404
+ if (!connectionSucceeded) {
405
+ // This is an initial connection error
406
+ console.log(`Failed to connect to ${targetHost}:${connectionOptions.port} for ${remoteIP}: ${err.message}`);
407
+ if (connectionTimeout) {
408
+ clearTimeout(connectionTimeout);
409
+ connectionTimeout = null;
410
+ }
411
+ if (outgoingTerminationReason === null) {
412
+ outgoingTerminationReason = 'connection_failed';
413
+ this.incrementTerminationStat('outgoing', 'connection_failed');
414
+ }
415
+ initiateCleanupOnce('connection_failed');
416
+ }
417
+ // Other errors will be handled by the main error handler
418
+ });
419
+ };
420
+ /**
421
+ * Sets up the data flow between sockets after successful connection
422
+ */
423
+ const setupDataFlow = (targetSocket, initialChunk) => {
260
424
  if (initialChunk) {
261
425
  socket.unshift(initialChunk);
262
426
  }
427
+ // Set appropriate timeouts for both sockets
263
428
  socket.setTimeout(120000);
429
+ targetSocket.setTimeout(120000);
430
+ // Set up the pipe in both directions
264
431
  socket.pipe(targetSocket);
265
432
  targetSocket.pipe(socket);
266
- // Attach error and close handlers.
433
+ // Attach error and close handlers
267
434
  socket.on('error', handleError('incoming'));
268
435
  targetSocket.on('error', handleError('outgoing'));
269
436
  socket.on('close', handleClose('incoming'));
270
437
  targetSocket.on('close', handleClose('outgoing'));
438
+ // Handle timeout events
271
439
  socket.on('timeout', () => {
272
440
  console.log(`Timeout on incoming side from ${remoteIP}`);
273
441
  if (incomingTerminationReason === null) {
274
442
  incomingTerminationReason = 'timeout';
275
443
  this.incrementTerminationStat('incoming', 'timeout');
276
444
  }
277
- cleanupOnce();
445
+ initiateCleanupOnce('timeout');
278
446
  });
279
447
  targetSocket.on('timeout', () => {
280
448
  console.log(`Timeout on outgoing side from ${remoteIP}`);
@@ -282,48 +450,23 @@ export class PortProxy {
282
450
  outgoingTerminationReason = 'timeout';
283
451
  this.incrementTerminationStat('outgoing', 'timeout');
284
452
  }
285
- cleanupOnce();
453
+ initiateCleanupOnce('timeout');
286
454
  });
287
455
  socket.on('end', handleClose('incoming'));
288
456
  targetSocket.on('end', handleClose('outgoing'));
289
- // Initialize a cleanup timer for max connection lifetime.
457
+ // Track activity for both sockets to reset inactivity timers
458
+ socket.on('data', (data) => {
459
+ this.updateActivity(connectionRecord);
460
+ });
461
+ targetSocket.on('data', (data) => {
462
+ this.updateActivity(connectionRecord);
463
+ });
464
+ // Initialize a cleanup timer for max connection lifetime
290
465
  if (this.settings.maxConnectionLifetime) {
291
- // Flags to track if data was seen from each side.
292
- let incomingActive = false;
293
- let outgoingActive = false;
294
- const resetCleanupTimer = () => {
295
- if (this.settings.maxConnectionLifetime) {
296
- if (connectionRecord.cleanupTimer) {
297
- clearTimeout(connectionRecord.cleanupTimer);
298
- }
299
- connectionRecord.cleanupTimer = setTimeout(() => {
300
- console.log(`Connection from ${remoteIP} exceeded max lifetime with inactivity (${this.settings.maxConnectionLifetime}ms), forcing cleanup.`);
301
- cleanupOnce();
302
- }, this.settings.maxConnectionLifetime);
303
- }
304
- };
305
- resetCleanupTimer();
306
- // Only reset the timer if outgoing socket is still active.
307
- socket.on('data', () => {
308
- incomingActive = true;
309
- // Check if outgoing has not been closed before resetting timer.
310
- if (!connectionRecord.outgoingClosedTime && incomingActive && outgoingActive) {
311
- resetCleanupTimer();
312
- incomingActive = false;
313
- outgoingActive = false;
314
- }
315
- });
316
- targetSocket.on('data', () => {
317
- // If outgoing is closed, do not set outgoingActive.
318
- if (connectionRecord.outgoingClosedTime)
319
- return;
320
- outgoingActive = true;
321
- if (incomingActive && outgoingActive) {
322
- resetCleanupTimer();
323
- incomingActive = false;
324
- outgoingActive = false;
325
- }
326
- });
466
+ connectionRecord.cleanupTimer = setTimeout(() => {
467
+ console.log(`Connection from ${remoteIP} exceeded max lifetime (${this.settings.maxConnectionLifetime}ms), forcing cleanup.`);
468
+ initiateCleanupOnce('max_lifetime');
469
+ }, this.settings.maxConnectionLifetime);
327
470
  }
328
471
  };
329
472
  // --- PORT RANGE-BASED HANDLING ---
@@ -333,6 +476,7 @@ export class PortProxy {
333
476
  if (this.settings.defaultAllowedIPs && !isAllowed(remoteIP, this.settings.defaultAllowedIPs)) {
334
477
  console.log(`Connection from ${remoteIP} rejected: IP ${remoteIP} not allowed in global default allowed list.`);
335
478
  socket.end();
479
+ initiateCleanupOnce('rejected');
336
480
  return;
337
481
  }
338
482
  console.log(`Port-based connection from ${remoteIP} on port ${localPort} forwarded to global target IP ${this.settings.targetIP}.`);
@@ -360,6 +504,7 @@ export class PortProxy {
360
504
  if (!isGlobIPAllowed(remoteIP, effectiveAllowedIPs, effectiveBlockedIPs)) {
361
505
  console.log(`Connection from ${remoteIP} rejected: IP not allowed for domain ${forcedDomain.domains.join(', ')} on port ${localPort}.`);
362
506
  socket.end();
507
+ initiateCleanupOnce('rejected');
363
508
  return;
364
509
  }
365
510
  console.log(`Port-based connection from ${remoteIP} on port ${localPort} matched domain ${forcedDomain.domains.join(', ')}.`);
@@ -371,13 +516,8 @@ export class PortProxy {
371
516
  }
372
517
  // --- FALLBACK: SNI-BASED HANDLING (or default when SNI is disabled) ---
373
518
  if (this.settings.sniEnabled) {
374
- socket.setTimeout(5000, () => {
375
- console.log(`Initial data timeout for ${remoteIP}`);
376
- socket.end();
377
- cleanupOnce();
378
- });
519
+ initialDataReceived = false;
379
520
  socket.once('data', (chunk) => {
380
- socket.setTimeout(0);
381
521
  initialDataReceived = true;
382
522
  const serverName = extractSNI(chunk) || '';
383
523
  // Lock the connection to the negotiated SNI.
@@ -388,10 +528,19 @@ export class PortProxy {
388
528
  setImmediate(() => {
389
529
  socket.on('data', (renegChunk) => {
390
530
  if (renegChunk.length > 0 && renegChunk.readUInt8(0) === 22) {
391
- const newSNI = extractSNI(renegChunk);
392
- if (newSNI && newSNI !== connectionRecord.lockedDomain) {
393
- console.log(`Rehandshake detected with different SNI: ${newSNI} vs locked ${connectionRecord.lockedDomain}. Terminating connection.`);
394
- cleanupOnce();
531
+ try {
532
+ // Try to extract SNI from potential renegotiation
533
+ const newSNI = extractSNI(renegChunk);
534
+ if (newSNI && newSNI !== connectionRecord.lockedDomain) {
535
+ console.log(`Rehandshake detected with different SNI: ${newSNI} vs locked ${connectionRecord.lockedDomain}. Terminating connection.`);
536
+ initiateCleanupOnce('sni_mismatch');
537
+ }
538
+ else if (newSNI) {
539
+ console.log(`Rehandshake detected with same SNI: ${newSNI}. Allowing.`);
540
+ }
541
+ }
542
+ catch (err) {
543
+ console.log(`Error processing potential renegotiation: ${err}. Allowing connection to continue.`);
395
544
  }
396
545
  }
397
546
  });
@@ -435,21 +584,41 @@ export class PortProxy {
435
584
  });
436
585
  this.netServers.push(server);
437
586
  }
438
- // Log active connection count, longest running durations, and run parity checks every 10 seconds.
587
+ // Log active connection count, run parity checks, and check for connection issues every 10 seconds.
439
588
  this.connectionLogger = setInterval(() => {
589
+ if (this.isShuttingDown)
590
+ return;
440
591
  const now = Date.now();
441
592
  let maxIncoming = 0;
442
593
  let maxOutgoing = 0;
443
- for (const record of this.connectionRecords) {
594
+ // Create a copy of the keys to avoid modification during iteration
595
+ const connectionIds = [...this.connectionRecords.keys()];
596
+ for (const id of connectionIds) {
597
+ const record = this.connectionRecords.get(id);
598
+ if (!record)
599
+ continue;
444
600
  maxIncoming = Math.max(maxIncoming, now - record.incomingStartTime);
445
601
  if (record.outgoingStartTime) {
446
602
  maxOutgoing = Math.max(maxOutgoing, now - record.outgoingStartTime);
447
603
  }
448
- // Parity check: if outgoing socket closed and incoming remains active for >1 minute, trigger special cleanup.
449
- if (record.outgoingClosedTime && !record.incoming.destroyed && (now - record.outgoingClosedTime > 60000)) {
604
+ // Parity check: if outgoing socket closed and incoming remains active for >30 seconds, trigger cleanup
605
+ if (record.outgoingClosedTime &&
606
+ !record.incoming.destroyed &&
607
+ !record.connectionClosed &&
608
+ !record.cleanupInitiated &&
609
+ (now - record.outgoingClosedTime > 30000)) {
610
+ const remoteIP = record.incoming.remoteAddress || 'unknown';
611
+ console.log(`Parity check triggered: Incoming socket for ${remoteIP} has been active >30s after outgoing closed.`);
612
+ this.initiateCleanup(record, 'parity_check');
613
+ }
614
+ // Inactivity check: if no activity for a long time but sockets still open
615
+ const inactivityTime = now - record.lastActivity;
616
+ if (inactivityTime > 180000 && // 3 minutes
617
+ !record.connectionClosed &&
618
+ !record.cleanupInitiated) {
450
619
  const remoteIP = record.incoming.remoteAddress || 'unknown';
451
- console.log(`Parity check triggered: Incoming socket for ${remoteIP} has been active >1 minute after outgoing closed.`);
452
- this.cleanupConnection(record, true);
620
+ console.log(`Inactivity check triggered: No activity on connection from ${remoteIP} for ${plugins.prettyMs(inactivityTime)}.`);
621
+ this.initiateCleanup(record, 'inactivity');
453
622
  }
454
623
  }
455
624
  console.log(`(Interval Log) Active connections: ${this.connectionRecords.size}. ` +
@@ -459,15 +628,58 @@ export class PortProxy {
459
628
  }, 10000);
460
629
  }
461
630
  async stop() {
462
- // Close all servers.
463
- const closePromises = this.netServers.map(server => new Promise((resolve) => {
631
+ console.log("PortProxy shutting down...");
632
+ this.isShuttingDown = true;
633
+ // Stop accepting new connections
634
+ const closeServerPromises = this.netServers.map(server => new Promise((resolve) => {
464
635
  server.close(() => resolve());
465
636
  }));
637
+ // Stop the connection logger
466
638
  if (this.connectionLogger) {
467
639
  clearInterval(this.connectionLogger);
468
640
  this.connectionLogger = null;
469
641
  }
470
- await Promise.all(closePromises);
642
+ // Wait for servers to close
643
+ await Promise.all(closeServerPromises);
644
+ console.log("All servers closed. Cleaning up active connections...");
645
+ // Gracefully close active connections
646
+ const connectionIds = [...this.connectionRecords.keys()];
647
+ console.log(`Cleaning up ${connectionIds.length} active connections...`);
648
+ for (const id of connectionIds) {
649
+ const record = this.connectionRecords.get(id);
650
+ if (record && !record.connectionClosed && !record.cleanupInitiated) {
651
+ this.initiateCleanup(record, 'shutdown');
652
+ }
653
+ }
654
+ // Wait for graceful shutdown or timeout
655
+ const shutdownTimeout = this.settings.gracefulShutdownTimeout || 30000;
656
+ await new Promise((resolve) => {
657
+ const checkInterval = setInterval(() => {
658
+ if (this.connectionRecords.size === 0) {
659
+ clearInterval(checkInterval);
660
+ resolve();
661
+ }
662
+ }, 1000);
663
+ // Force resolve after timeout
664
+ setTimeout(() => {
665
+ clearInterval(checkInterval);
666
+ if (this.connectionRecords.size > 0) {
667
+ console.log(`Forcing shutdown with ${this.connectionRecords.size} connections still active`);
668
+ // Force destroy any remaining connections
669
+ for (const record of this.connectionRecords.values()) {
670
+ if (!record.incoming.destroyed) {
671
+ record.incoming.destroy();
672
+ }
673
+ if (record.outgoing && !record.outgoing.destroyed) {
674
+ record.outgoing.destroy();
675
+ }
676
+ }
677
+ this.connectionRecords.clear();
678
+ }
679
+ resolve();
680
+ }, shutdownTimeout);
681
+ });
682
+ console.log("PortProxy shutdown complete.");
471
683
  }
472
684
  }
473
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQTBCeEM7Ozs7R0FJRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV4QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLElBQUksVUFBVSxLQUFLLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlCQUFpQjtJQUUxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsWUFBWTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRXZELE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9DLElBQUksYUFBYSxLQUFLLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGtCQUFrQjtJQUU3RCxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBQ3JELE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsaUNBQWlDO0lBRW5ELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsTUFBTSxJQUFJLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxrQkFBa0I7SUFFakQsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FB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
685
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQTJCeEM7Ozs7R0FJRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV4QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLElBQUksVUFBVSxLQUFLLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlCQUFpQjtJQUUxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsWUFBWTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRXZELE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9DLElBQUksYUFBYSxLQUFLLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGtCQUFrQjtJQUU3RCxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBQ3JELE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsaUNBQWlDO0lBRW5ELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsTUFBTSxJQUFJLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxrQkFBa0I7SUFFakQsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FB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