@push.rocks/smartproxy 3.20.2 → 3.22.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.portproxy.d.ts +15 -4
- package/dist_ts/classes.portproxy.js +381 -103
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.portproxy.ts +440 -106
|
@@ -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
|
|
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,82 @@ 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
|
};
|
|
112
|
+
// Debug logging for constructor settings
|
|
113
|
+
console.log(`PortProxy initialized with targetIP: ${this.settings.targetIP}, toPort: ${this.settings.toPort}, fromPort: ${this.settings.fromPort}, sniEnabled: ${this.settings.sniEnabled}`);
|
|
106
114
|
}
|
|
107
115
|
incrementTerminationStat(side, reason) {
|
|
108
116
|
this.terminationStats[side][reason] = (this.terminationStats[side][reason] || 0) + 1;
|
|
109
117
|
}
|
|
110
118
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
|
|
119
|
+
* Initiates the cleanup process for a connection.
|
|
120
|
+
* Sets the flag to prevent duplicate cleanup attempts and schedules actual cleanup.
|
|
121
|
+
*/
|
|
122
|
+
initiateCleanup(record, reason = 'normal') {
|
|
123
|
+
if (record.cleanupInitiated)
|
|
124
|
+
return;
|
|
125
|
+
record.cleanupInitiated = true;
|
|
126
|
+
const remoteIP = record.incoming.remoteAddress || 'unknown';
|
|
127
|
+
console.log(`Initiating cleanup for connection ${record.id} from ${remoteIP} (reason: ${reason})`);
|
|
128
|
+
// Execute cleanup immediately to prevent lingering connections
|
|
129
|
+
this.executeCleanup(record);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Executes the actual cleanup of a connection.
|
|
133
|
+
* Destroys sockets, clears timers, and removes the record.
|
|
114
134
|
*/
|
|
115
|
-
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
135
|
+
executeCleanup(record) {
|
|
136
|
+
if (record.connectionClosed)
|
|
137
|
+
return;
|
|
138
|
+
record.connectionClosed = true;
|
|
139
|
+
const remoteIP = record.incoming.remoteAddress || 'unknown';
|
|
140
|
+
if (record.cleanupTimer) {
|
|
141
|
+
clearTimeout(record.cleanupTimer);
|
|
142
|
+
record.cleanupTimer = undefined;
|
|
143
|
+
}
|
|
144
|
+
// End the sockets first to allow for graceful closure
|
|
145
|
+
try {
|
|
146
|
+
if (!record.incoming.destroyed) {
|
|
147
|
+
record.incoming.end();
|
|
148
|
+
// Set a safety timeout to force destroy if end doesn't complete
|
|
149
|
+
setTimeout(() => {
|
|
150
|
+
if (!record.incoming.destroyed) {
|
|
151
|
+
console.log(`Forcing destruction of incoming socket for ${remoteIP}`);
|
|
152
|
+
record.incoming.destroy();
|
|
153
|
+
}
|
|
154
|
+
}, 1000);
|
|
120
155
|
}
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
console.error(`Error ending incoming socket for ${remoteIP}:`, err);
|
|
121
159
|
if (!record.incoming.destroyed) {
|
|
122
160
|
record.incoming.destroy();
|
|
123
161
|
}
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
124
164
|
if (record.outgoing && !record.outgoing.destroyed) {
|
|
125
|
-
record.outgoing.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
165
|
+
record.outgoing.end();
|
|
166
|
+
// Set a safety timeout to force destroy if end doesn't complete
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
if (record.outgoing && !record.outgoing.destroyed) {
|
|
169
|
+
console.log(`Forcing destruction of outgoing socket for ${remoteIP}`);
|
|
170
|
+
record.outgoing.destroy();
|
|
171
|
+
}
|
|
172
|
+
}, 1000);
|
|
131
173
|
}
|
|
132
|
-
|
|
133
|
-
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
console.error(`Error ending outgoing socket for ${remoteIP}:`, err);
|
|
177
|
+
if (record.outgoing && !record.outgoing.destroyed) {
|
|
178
|
+
record.outgoing.destroy();
|
|
134
179
|
}
|
|
135
180
|
}
|
|
181
|
+
// Remove the record after a delay to ensure all events have propagated
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
this.connectionRecords.delete(record.id);
|
|
184
|
+
console.log(`Connection ${record.id} from ${remoteIP} fully cleaned up. Active connections: ${this.connectionRecords.size}`);
|
|
185
|
+
}, 2000);
|
|
136
186
|
}
|
|
137
187
|
getTargetIP(domainConfig) {
|
|
138
188
|
if (domainConfig.targetIPs && domainConfig.targetIPs.length > 0) {
|
|
@@ -143,25 +193,52 @@ export class PortProxy {
|
|
|
143
193
|
}
|
|
144
194
|
return this.settings.targetIP;
|
|
145
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Updates the last activity timestamp for a connection record
|
|
198
|
+
*/
|
|
199
|
+
updateActivity(record) {
|
|
200
|
+
record.lastActivity = Date.now();
|
|
201
|
+
// Reset the inactivity timer if one is set
|
|
202
|
+
if (this.settings.maxConnectionLifetime && record.cleanupTimer) {
|
|
203
|
+
clearTimeout(record.cleanupTimer);
|
|
204
|
+
// Set a new cleanup timer
|
|
205
|
+
record.cleanupTimer = setTimeout(() => {
|
|
206
|
+
const now = Date.now();
|
|
207
|
+
const inactivityTime = now - record.lastActivity;
|
|
208
|
+
const remoteIP = record.incoming.remoteAddress || 'unknown';
|
|
209
|
+
console.log(`Connection ${record.id} from ${remoteIP} exceeded max lifetime or inactivity period (${inactivityTime}ms), forcing cleanup.`);
|
|
210
|
+
this.initiateCleanup(record, 'timeout');
|
|
211
|
+
}, this.settings.maxConnectionLifetime);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
146
214
|
async start() {
|
|
147
215
|
// Define a unified connection handler for all listening ports.
|
|
148
216
|
const connectionHandler = (socket) => {
|
|
217
|
+
if (this.isShuttingDown) {
|
|
218
|
+
socket.end();
|
|
219
|
+
socket.destroy();
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
149
222
|
const remoteIP = socket.remoteAddress || '';
|
|
150
223
|
const localPort = socket.localPort; // The port on which this connection was accepted.
|
|
224
|
+
const connectionId = generateConnectionId();
|
|
151
225
|
const connectionRecord = {
|
|
226
|
+
id: connectionId,
|
|
152
227
|
incoming: socket,
|
|
153
228
|
outgoing: null,
|
|
154
229
|
incomingStartTime: Date.now(),
|
|
230
|
+
lastActivity: Date.now(),
|
|
155
231
|
connectionClosed: false,
|
|
232
|
+
cleanupInitiated: false
|
|
156
233
|
};
|
|
157
|
-
this.connectionRecords.
|
|
158
|
-
console.log(`New connection from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionRecords.size}`);
|
|
234
|
+
this.connectionRecords.set(connectionId, connectionRecord);
|
|
235
|
+
console.log(`New connection ${connectionId} from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionRecords.size}`);
|
|
159
236
|
let initialDataReceived = false;
|
|
160
237
|
let incomingTerminationReason = null;
|
|
161
238
|
let outgoingTerminationReason = null;
|
|
162
239
|
// Local cleanup function that delegates to the class method.
|
|
163
|
-
const
|
|
164
|
-
this.
|
|
240
|
+
const initiateCleanupOnce = (reason = 'normal') => {
|
|
241
|
+
this.initiateCleanup(connectionRecord, reason);
|
|
165
242
|
};
|
|
166
243
|
// Helper to reject an incoming connection.
|
|
167
244
|
const rejectIncomingConnection = (reason, logMessage) => {
|
|
@@ -171,13 +248,50 @@ export class PortProxy {
|
|
|
171
248
|
incomingTerminationReason = reason;
|
|
172
249
|
this.incrementTerminationStat('incoming', reason);
|
|
173
250
|
}
|
|
174
|
-
|
|
251
|
+
initiateCleanupOnce(reason);
|
|
175
252
|
};
|
|
253
|
+
// Set an initial timeout only if SNI is enabled or this is not a chained proxy
|
|
254
|
+
// For chained proxies, we need to allow more time for data to flow through
|
|
255
|
+
const initialTimeoutMs = this.settings.initialDataTimeout ||
|
|
256
|
+
(this.settings.sniEnabled ? 15000 : 0); // Increased timeout for SNI, disabled for non-SNI by default
|
|
257
|
+
let initialTimeout = null;
|
|
258
|
+
if (initialTimeoutMs > 0) {
|
|
259
|
+
console.log(`Setting initial data timeout of ${initialTimeoutMs}ms for connection from ${remoteIP}`);
|
|
260
|
+
initialTimeout = setTimeout(() => {
|
|
261
|
+
if (!initialDataReceived) {
|
|
262
|
+
console.log(`Initial connection timeout for ${remoteIP} (no data received after ${initialTimeoutMs}ms)`);
|
|
263
|
+
if (incomingTerminationReason === null) {
|
|
264
|
+
incomingTerminationReason = 'initial_timeout';
|
|
265
|
+
this.incrementTerminationStat('incoming', 'initial_timeout');
|
|
266
|
+
}
|
|
267
|
+
initiateCleanupOnce('initial_timeout');
|
|
268
|
+
}
|
|
269
|
+
}, initialTimeoutMs);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
console.log(`No initial timeout set for connection from ${remoteIP} (likely chained proxy)`);
|
|
273
|
+
// Mark as received immediately if we're not waiting for data
|
|
274
|
+
initialDataReceived = true;
|
|
275
|
+
}
|
|
176
276
|
socket.on('error', (err) => {
|
|
177
277
|
const errorMessage = initialDataReceived
|
|
178
278
|
? `(Immediate) Incoming socket error from ${remoteIP}: ${err.message}`
|
|
179
279
|
: `(Premature) Incoming socket error from ${remoteIP} before data received: ${err.message}`;
|
|
180
280
|
console.log(errorMessage);
|
|
281
|
+
// Clear the initial timeout if it exists
|
|
282
|
+
if (initialTimeout) {
|
|
283
|
+
clearTimeout(initialTimeout);
|
|
284
|
+
initialTimeout = null;
|
|
285
|
+
}
|
|
286
|
+
// For premature errors, we need to handle them explicitly
|
|
287
|
+
// since the standard error handlers might not be set up yet
|
|
288
|
+
if (!initialDataReceived) {
|
|
289
|
+
if (incomingTerminationReason === null) {
|
|
290
|
+
incomingTerminationReason = 'premature_error';
|
|
291
|
+
this.incrementTerminationStat('incoming', 'premature_error');
|
|
292
|
+
}
|
|
293
|
+
initiateCleanupOnce('premature_error');
|
|
294
|
+
}
|
|
181
295
|
});
|
|
182
296
|
const handleError = (side) => (err) => {
|
|
183
297
|
const code = err.code;
|
|
@@ -186,6 +300,10 @@ export class PortProxy {
|
|
|
186
300
|
reason = 'econnreset';
|
|
187
301
|
console.log(`ECONNRESET on ${side} side from ${remoteIP}: ${err.message}`);
|
|
188
302
|
}
|
|
303
|
+
else if (code === 'ECONNREFUSED') {
|
|
304
|
+
reason = 'econnrefused';
|
|
305
|
+
console.log(`ECONNREFUSED on ${side} side from ${remoteIP}: ${err.message}`);
|
|
306
|
+
}
|
|
189
307
|
else {
|
|
190
308
|
console.log(`Error on ${side} side from ${remoteIP}: ${err.message}`);
|
|
191
309
|
}
|
|
@@ -197,7 +315,7 @@ export class PortProxy {
|
|
|
197
315
|
outgoingTerminationReason = reason;
|
|
198
316
|
this.incrementTerminationStat('outgoing', reason);
|
|
199
317
|
}
|
|
200
|
-
|
|
318
|
+
initiateCleanupOnce(reason);
|
|
201
319
|
};
|
|
202
320
|
const handleClose = (side) => () => {
|
|
203
321
|
console.log(`Connection closed on ${side} side from ${remoteIP}`);
|
|
@@ -210,40 +328,72 @@ export class PortProxy {
|
|
|
210
328
|
this.incrementTerminationStat('outgoing', 'normal');
|
|
211
329
|
// Record the time when outgoing socket closed.
|
|
212
330
|
connectionRecord.outgoingClosedTime = Date.now();
|
|
331
|
+
// If incoming is still active but outgoing closed, set a shorter timeout
|
|
332
|
+
if (!connectionRecord.incoming.destroyed) {
|
|
333
|
+
console.log(`Outgoing socket closed but incoming still active for ${remoteIP}. Setting cleanup timeout.`);
|
|
334
|
+
setTimeout(() => {
|
|
335
|
+
if (!connectionRecord.connectionClosed && !connectionRecord.incoming.destroyed) {
|
|
336
|
+
console.log(`Incoming socket still active ${Date.now() - connectionRecord.outgoingClosedTime}ms after outgoing closed for ${remoteIP}. Cleaning up.`);
|
|
337
|
+
initiateCleanupOnce('outgoing_closed_timeout');
|
|
338
|
+
}
|
|
339
|
+
}, 10000); // 10 second timeout instead of waiting for the next parity check
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// If both sides are closed/destroyed, clean up
|
|
343
|
+
if ((side === 'incoming' && connectionRecord.outgoing?.destroyed) ||
|
|
344
|
+
(side === 'outgoing' && connectionRecord.incoming.destroyed)) {
|
|
345
|
+
initiateCleanupOnce('both_closed');
|
|
213
346
|
}
|
|
214
|
-
cleanupOnce();
|
|
215
347
|
};
|
|
216
348
|
/**
|
|
217
349
|
* Sets up the connection to the target host.
|
|
218
350
|
* @param serverName - The SNI hostname (unused when forcedDomain is provided).
|
|
219
351
|
* @param initialChunk - Optional initial data chunk.
|
|
220
352
|
* @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
|
|
353
|
+
* @param overridePort - If provided, use this port for the outgoing connection.
|
|
222
354
|
*/
|
|
223
355
|
const setupConnection = (serverName, initialChunk, forcedDomain, overridePort) => {
|
|
356
|
+
// Clear the initial timeout since we've received data
|
|
357
|
+
if (initialTimeout) {
|
|
358
|
+
clearTimeout(initialTimeout);
|
|
359
|
+
}
|
|
224
360
|
// If a forcedDomain is provided (port-based routing), use it; otherwise, use SNI-based lookup.
|
|
225
361
|
const domainConfig = forcedDomain
|
|
226
362
|
? forcedDomain
|
|
227
363
|
: (serverName ? this.settings.domainConfigs.find(config => config.domains.some(d => plugins.minimatch(serverName, d))) : undefined);
|
|
228
364
|
// Effective IP check: merge allowed IPs with default allowed, and remove blocked IPs.
|
|
365
|
+
// In a chained proxy, relax IP validation unless explicitly configured
|
|
366
|
+
// If this is the first proxy in the chain, normal validation applies
|
|
229
367
|
if (domainConfig) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
368
|
+
// Has specific domain config - check IP restrictions only if allowedIPs is non-empty
|
|
369
|
+
if (domainConfig.allowedIPs.length > 0) {
|
|
370
|
+
const effectiveAllowedIPs = [
|
|
371
|
+
...domainConfig.allowedIPs,
|
|
372
|
+
...(this.settings.defaultAllowedIPs || [])
|
|
373
|
+
];
|
|
374
|
+
const effectiveBlockedIPs = [
|
|
375
|
+
...(domainConfig.blockedIPs || []),
|
|
376
|
+
...(this.settings.defaultBlockedIPs || [])
|
|
377
|
+
];
|
|
378
|
+
if (!isGlobIPAllowed(remoteIP, effectiveAllowedIPs, effectiveBlockedIPs)) {
|
|
379
|
+
return rejectIncomingConnection('rejected', `Connection rejected: IP ${remoteIP} not allowed for domain ${domainConfig.domains.join(', ')}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
console.log(`Domain config for ${domainConfig.domains.join(', ')} has empty allowedIPs, skipping IP validation`);
|
|
240
384
|
}
|
|
241
385
|
}
|
|
242
|
-
else if (this.settings.defaultAllowedIPs) {
|
|
386
|
+
else if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
|
|
387
|
+
// No domain config but has default IP restrictions
|
|
243
388
|
if (!isGlobIPAllowed(remoteIP, this.settings.defaultAllowedIPs, this.settings.defaultBlockedIPs || [])) {
|
|
244
389
|
return rejectIncomingConnection('rejected', `Connection rejected: IP ${remoteIP} not allowed by default allowed list`);
|
|
245
390
|
}
|
|
246
391
|
}
|
|
392
|
+
else {
|
|
393
|
+
// No domain config and no default allowed IPs
|
|
394
|
+
// In a chained proxy setup, we'll allow this connection
|
|
395
|
+
console.log(`No specific IP restrictions found for ${remoteIP}. Allowing connection in potential chained proxy setup.`);
|
|
396
|
+
}
|
|
247
397
|
const targetHost = domainConfig ? this.getTargetIP(domainConfig) : this.settings.targetIP;
|
|
248
398
|
const connectionOptions = {
|
|
249
399
|
host: targetHost,
|
|
@@ -252,29 +402,81 @@ export class PortProxy {
|
|
|
252
402
|
if (this.settings.preserveSourceIP) {
|
|
253
403
|
connectionOptions.localAddress = remoteIP.replace('::ffff:', '');
|
|
254
404
|
}
|
|
405
|
+
// Add explicit connection timeout and error handling
|
|
406
|
+
let connectionTimeout = null;
|
|
407
|
+
let connectionSucceeded = false;
|
|
408
|
+
// Set connection timeout - longer for chained proxies
|
|
409
|
+
connectionTimeout = setTimeout(() => {
|
|
410
|
+
if (!connectionSucceeded) {
|
|
411
|
+
console.log(`Connection timeout connecting to ${targetHost}:${connectionOptions.port} for ${remoteIP}`);
|
|
412
|
+
if (outgoingTerminationReason === null) {
|
|
413
|
+
outgoingTerminationReason = 'connection_timeout';
|
|
414
|
+
this.incrementTerminationStat('outgoing', 'connection_timeout');
|
|
415
|
+
}
|
|
416
|
+
initiateCleanupOnce('connection_timeout');
|
|
417
|
+
}
|
|
418
|
+
}, 10000); // Increased from 5s to 10s to accommodate chained proxies
|
|
419
|
+
console.log(`Attempting to connect to ${targetHost}:${connectionOptions.port} for client ${remoteIP}...`);
|
|
420
|
+
// Create the target socket
|
|
255
421
|
const targetSocket = plugins.net.connect(connectionOptions);
|
|
256
422
|
connectionRecord.outgoing = targetSocket;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
423
|
+
// Handle successful connection
|
|
424
|
+
targetSocket.once('connect', () => {
|
|
425
|
+
connectionSucceeded = true;
|
|
426
|
+
if (connectionTimeout) {
|
|
427
|
+
clearTimeout(connectionTimeout);
|
|
428
|
+
connectionTimeout = null;
|
|
429
|
+
}
|
|
430
|
+
connectionRecord.outgoingStartTime = Date.now();
|
|
431
|
+
console.log(`Connection established: ${remoteIP} -> ${targetHost}:${connectionOptions.port}` +
|
|
432
|
+
`${serverName ? ` (SNI: ${serverName})` : forcedDomain ? ` (Port-based for domain: ${forcedDomain.domains.join(', ')})` : ''}`);
|
|
433
|
+
// Setup data flow after confirmed connection
|
|
434
|
+
setupDataFlow(targetSocket, initialChunk);
|
|
435
|
+
});
|
|
436
|
+
// Handle connection errors early
|
|
437
|
+
targetSocket.once('error', (err) => {
|
|
438
|
+
if (!connectionSucceeded) {
|
|
439
|
+
// This is an initial connection error
|
|
440
|
+
console.log(`Failed to connect to ${targetHost}:${connectionOptions.port} for ${remoteIP}: ${err.message}`);
|
|
441
|
+
if (connectionTimeout) {
|
|
442
|
+
clearTimeout(connectionTimeout);
|
|
443
|
+
connectionTimeout = null;
|
|
444
|
+
}
|
|
445
|
+
if (outgoingTerminationReason === null) {
|
|
446
|
+
outgoingTerminationReason = 'connection_failed';
|
|
447
|
+
this.incrementTerminationStat('outgoing', 'connection_failed');
|
|
448
|
+
}
|
|
449
|
+
initiateCleanupOnce('connection_failed');
|
|
450
|
+
}
|
|
451
|
+
// Other errors will be handled by the main error handler
|
|
452
|
+
});
|
|
453
|
+
};
|
|
454
|
+
/**
|
|
455
|
+
* Sets up the data flow between sockets after successful connection
|
|
456
|
+
*/
|
|
457
|
+
const setupDataFlow = (targetSocket, initialChunk) => {
|
|
260
458
|
if (initialChunk) {
|
|
261
459
|
socket.unshift(initialChunk);
|
|
262
460
|
}
|
|
461
|
+
// Set appropriate timeouts for both sockets
|
|
263
462
|
socket.setTimeout(120000);
|
|
463
|
+
targetSocket.setTimeout(120000);
|
|
464
|
+
// Set up the pipe in both directions
|
|
264
465
|
socket.pipe(targetSocket);
|
|
265
466
|
targetSocket.pipe(socket);
|
|
266
|
-
// Attach error and close handlers
|
|
467
|
+
// Attach error and close handlers
|
|
267
468
|
socket.on('error', handleError('incoming'));
|
|
268
469
|
targetSocket.on('error', handleError('outgoing'));
|
|
269
470
|
socket.on('close', handleClose('incoming'));
|
|
270
471
|
targetSocket.on('close', handleClose('outgoing'));
|
|
472
|
+
// Handle timeout events
|
|
271
473
|
socket.on('timeout', () => {
|
|
272
474
|
console.log(`Timeout on incoming side from ${remoteIP}`);
|
|
273
475
|
if (incomingTerminationReason === null) {
|
|
274
476
|
incomingTerminationReason = 'timeout';
|
|
275
477
|
this.incrementTerminationStat('incoming', 'timeout');
|
|
276
478
|
}
|
|
277
|
-
|
|
479
|
+
initiateCleanupOnce('timeout');
|
|
278
480
|
});
|
|
279
481
|
targetSocket.on('timeout', () => {
|
|
280
482
|
console.log(`Timeout on outgoing side from ${remoteIP}`);
|
|
@@ -282,48 +484,23 @@ export class PortProxy {
|
|
|
282
484
|
outgoingTerminationReason = 'timeout';
|
|
283
485
|
this.incrementTerminationStat('outgoing', 'timeout');
|
|
284
486
|
}
|
|
285
|
-
|
|
487
|
+
initiateCleanupOnce('timeout');
|
|
286
488
|
});
|
|
287
489
|
socket.on('end', handleClose('incoming'));
|
|
288
490
|
targetSocket.on('end', handleClose('outgoing'));
|
|
289
|
-
//
|
|
491
|
+
// Track activity for both sockets to reset inactivity timers
|
|
492
|
+
socket.on('data', (data) => {
|
|
493
|
+
this.updateActivity(connectionRecord);
|
|
494
|
+
});
|
|
495
|
+
targetSocket.on('data', (data) => {
|
|
496
|
+
this.updateActivity(connectionRecord);
|
|
497
|
+
});
|
|
498
|
+
// Initialize a cleanup timer for max connection lifetime
|
|
290
499
|
if (this.settings.maxConnectionLifetime) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
-
});
|
|
500
|
+
connectionRecord.cleanupTimer = setTimeout(() => {
|
|
501
|
+
console.log(`Connection from ${remoteIP} exceeded max lifetime (${this.settings.maxConnectionLifetime}ms), forcing cleanup.`);
|
|
502
|
+
initiateCleanupOnce('max_lifetime');
|
|
503
|
+
}, this.settings.maxConnectionLifetime);
|
|
327
504
|
}
|
|
328
505
|
};
|
|
329
506
|
// --- PORT RANGE-BASED HANDLING ---
|
|
@@ -333,6 +510,7 @@ export class PortProxy {
|
|
|
333
510
|
if (this.settings.defaultAllowedIPs && !isAllowed(remoteIP, this.settings.defaultAllowedIPs)) {
|
|
334
511
|
console.log(`Connection from ${remoteIP} rejected: IP ${remoteIP} not allowed in global default allowed list.`);
|
|
335
512
|
socket.end();
|
|
513
|
+
initiateCleanupOnce('rejected');
|
|
336
514
|
return;
|
|
337
515
|
}
|
|
338
516
|
console.log(`Port-based connection from ${remoteIP} on port ${localPort} forwarded to global target IP ${this.settings.targetIP}.`);
|
|
@@ -360,6 +538,7 @@ export class PortProxy {
|
|
|
360
538
|
if (!isGlobIPAllowed(remoteIP, effectiveAllowedIPs, effectiveBlockedIPs)) {
|
|
361
539
|
console.log(`Connection from ${remoteIP} rejected: IP not allowed for domain ${forcedDomain.domains.join(', ')} on port ${localPort}.`);
|
|
362
540
|
socket.end();
|
|
541
|
+
initiateCleanupOnce('rejected');
|
|
363
542
|
return;
|
|
364
543
|
}
|
|
365
544
|
console.log(`Port-based connection from ${remoteIP} on port ${localPort} matched domain ${forcedDomain.domains.join(', ')}.`);
|
|
@@ -371,27 +550,53 @@ export class PortProxy {
|
|
|
371
550
|
}
|
|
372
551
|
// --- FALLBACK: SNI-BASED HANDLING (or default when SNI is disabled) ---
|
|
373
552
|
if (this.settings.sniEnabled) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
553
|
+
// If using SNI, we need to wait for data to establish the connection
|
|
554
|
+
if (initialDataReceived) {
|
|
555
|
+
console.log(`Initial data already marked as received for ${remoteIP}, but SNI is enabled. This is unexpected.`);
|
|
556
|
+
}
|
|
557
|
+
initialDataReceived = false;
|
|
558
|
+
console.log(`Waiting for TLS ClientHello from ${remoteIP} to extract SNI...`);
|
|
379
559
|
socket.once('data', (chunk) => {
|
|
380
|
-
|
|
560
|
+
if (initialTimeout) {
|
|
561
|
+
clearTimeout(initialTimeout);
|
|
562
|
+
initialTimeout = null;
|
|
563
|
+
}
|
|
381
564
|
initialDataReceived = true;
|
|
382
|
-
|
|
565
|
+
console.log(`Received initial data from ${remoteIP}, length: ${chunk.length} bytes`);
|
|
566
|
+
let serverName = '';
|
|
567
|
+
try {
|
|
568
|
+
// Only try to extract SNI if the chunk looks like a TLS ClientHello
|
|
569
|
+
if (chunk.length > 5 && chunk.readUInt8(0) === 22) {
|
|
570
|
+
serverName = extractSNI(chunk) || '';
|
|
571
|
+
console.log(`Extracted SNI: "${serverName}" from connection ${remoteIP}`);
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
console.log(`Data from ${remoteIP} doesn't appear to be a TLS ClientHello. First byte: ${chunk.length > 0 ? chunk.readUInt8(0) : 'N/A'}`);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
catch (err) {
|
|
578
|
+
console.log(`Error extracting SNI from chunk: ${err}. Proceeding without SNI.`);
|
|
579
|
+
}
|
|
383
580
|
// Lock the connection to the negotiated SNI.
|
|
384
581
|
connectionRecord.lockedDomain = serverName;
|
|
385
|
-
console.log(`Received connection from ${remoteIP} with SNI: ${serverName}`);
|
|
386
582
|
// Delay adding the renegotiation listener until the next tick,
|
|
387
583
|
// so the initial ClientHello is not reprocessed.
|
|
388
584
|
setImmediate(() => {
|
|
389
585
|
socket.on('data', (renegChunk) => {
|
|
390
586
|
if (renegChunk.length > 0 && renegChunk.readUInt8(0) === 22) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
587
|
+
try {
|
|
588
|
+
// Try to extract SNI from potential renegotiation
|
|
589
|
+
const newSNI = extractSNI(renegChunk);
|
|
590
|
+
if (newSNI && newSNI !== connectionRecord.lockedDomain) {
|
|
591
|
+
console.log(`Rehandshake detected with different SNI: ${newSNI} vs locked ${connectionRecord.lockedDomain}. Terminating connection.`);
|
|
592
|
+
initiateCleanupOnce('sni_mismatch');
|
|
593
|
+
}
|
|
594
|
+
else if (newSNI) {
|
|
595
|
+
console.log(`Rehandshake detected with same SNI: ${newSNI}. Allowing.`);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
catch (err) {
|
|
599
|
+
console.log(`Error processing potential renegotiation: ${err}. Allowing connection to continue.`);
|
|
395
600
|
}
|
|
396
601
|
}
|
|
397
602
|
});
|
|
@@ -400,10 +605,20 @@ export class PortProxy {
|
|
|
400
605
|
});
|
|
401
606
|
}
|
|
402
607
|
else {
|
|
608
|
+
// Non-SNI mode: we can proceed immediately without waiting for data
|
|
609
|
+
if (initialTimeout) {
|
|
610
|
+
clearTimeout(initialTimeout);
|
|
611
|
+
initialTimeout = null;
|
|
612
|
+
}
|
|
403
613
|
initialDataReceived = true;
|
|
404
|
-
|
|
405
|
-
|
|
614
|
+
console.log(`SNI disabled for connection from ${remoteIP}, proceeding directly to connection setup`);
|
|
615
|
+
// Check IP restrictions only if explicitly configured
|
|
616
|
+
if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
|
|
617
|
+
if (!isAllowed(remoteIP, this.settings.defaultAllowedIPs)) {
|
|
618
|
+
return rejectIncomingConnection('rejected', `Connection rejected: IP ${remoteIP} not allowed for non-SNI connection`);
|
|
619
|
+
}
|
|
406
620
|
}
|
|
621
|
+
// Proceed with connection setup
|
|
407
622
|
setupConnection('');
|
|
408
623
|
}
|
|
409
624
|
};
|
|
@@ -435,21 +650,41 @@ export class PortProxy {
|
|
|
435
650
|
});
|
|
436
651
|
this.netServers.push(server);
|
|
437
652
|
}
|
|
438
|
-
// Log active connection count,
|
|
653
|
+
// Log active connection count, run parity checks, and check for connection issues every 10 seconds.
|
|
439
654
|
this.connectionLogger = setInterval(() => {
|
|
655
|
+
if (this.isShuttingDown)
|
|
656
|
+
return;
|
|
440
657
|
const now = Date.now();
|
|
441
658
|
let maxIncoming = 0;
|
|
442
659
|
let maxOutgoing = 0;
|
|
443
|
-
|
|
660
|
+
// Create a copy of the keys to avoid modification during iteration
|
|
661
|
+
const connectionIds = [...this.connectionRecords.keys()];
|
|
662
|
+
for (const id of connectionIds) {
|
|
663
|
+
const record = this.connectionRecords.get(id);
|
|
664
|
+
if (!record)
|
|
665
|
+
continue;
|
|
444
666
|
maxIncoming = Math.max(maxIncoming, now - record.incomingStartTime);
|
|
445
667
|
if (record.outgoingStartTime) {
|
|
446
668
|
maxOutgoing = Math.max(maxOutgoing, now - record.outgoingStartTime);
|
|
447
669
|
}
|
|
448
|
-
// Parity check: if outgoing socket closed and incoming remains active for >
|
|
449
|
-
if (record.outgoingClosedTime &&
|
|
670
|
+
// Parity check: if outgoing socket closed and incoming remains active for >30 seconds, trigger cleanup
|
|
671
|
+
if (record.outgoingClosedTime &&
|
|
672
|
+
!record.incoming.destroyed &&
|
|
673
|
+
!record.connectionClosed &&
|
|
674
|
+
!record.cleanupInitiated &&
|
|
675
|
+
(now - record.outgoingClosedTime > 30000)) {
|
|
676
|
+
const remoteIP = record.incoming.remoteAddress || 'unknown';
|
|
677
|
+
console.log(`Parity check triggered: Incoming socket for ${remoteIP} has been active >30s after outgoing closed.`);
|
|
678
|
+
this.initiateCleanup(record, 'parity_check');
|
|
679
|
+
}
|
|
680
|
+
// Inactivity check: if no activity for a long time but sockets still open
|
|
681
|
+
const inactivityTime = now - record.lastActivity;
|
|
682
|
+
if (inactivityTime > 180000 && // 3 minutes
|
|
683
|
+
!record.connectionClosed &&
|
|
684
|
+
!record.cleanupInitiated) {
|
|
450
685
|
const remoteIP = record.incoming.remoteAddress || 'unknown';
|
|
451
|
-
console.log(`
|
|
452
|
-
this.
|
|
686
|
+
console.log(`Inactivity check triggered: No activity on connection from ${remoteIP} for ${plugins.prettyMs(inactivityTime)}.`);
|
|
687
|
+
this.initiateCleanup(record, 'inactivity');
|
|
453
688
|
}
|
|
454
689
|
}
|
|
455
690
|
console.log(`(Interval Log) Active connections: ${this.connectionRecords.size}. ` +
|
|
@@ -459,15 +694,58 @@ export class PortProxy {
|
|
|
459
694
|
}, 10000);
|
|
460
695
|
}
|
|
461
696
|
async stop() {
|
|
462
|
-
|
|
463
|
-
|
|
697
|
+
console.log("PortProxy shutting down...");
|
|
698
|
+
this.isShuttingDown = true;
|
|
699
|
+
// Stop accepting new connections
|
|
700
|
+
const closeServerPromises = this.netServers.map(server => new Promise((resolve) => {
|
|
464
701
|
server.close(() => resolve());
|
|
465
702
|
}));
|
|
703
|
+
// Stop the connection logger
|
|
466
704
|
if (this.connectionLogger) {
|
|
467
705
|
clearInterval(this.connectionLogger);
|
|
468
706
|
this.connectionLogger = null;
|
|
469
707
|
}
|
|
470
|
-
|
|
708
|
+
// Wait for servers to close
|
|
709
|
+
await Promise.all(closeServerPromises);
|
|
710
|
+
console.log("All servers closed. Cleaning up active connections...");
|
|
711
|
+
// Gracefully close active connections
|
|
712
|
+
const connectionIds = [...this.connectionRecords.keys()];
|
|
713
|
+
console.log(`Cleaning up ${connectionIds.length} active connections...`);
|
|
714
|
+
for (const id of connectionIds) {
|
|
715
|
+
const record = this.connectionRecords.get(id);
|
|
716
|
+
if (record && !record.connectionClosed && !record.cleanupInitiated) {
|
|
717
|
+
this.initiateCleanup(record, 'shutdown');
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
// Wait for graceful shutdown or timeout
|
|
721
|
+
const shutdownTimeout = this.settings.gracefulShutdownTimeout || 30000;
|
|
722
|
+
await new Promise((resolve) => {
|
|
723
|
+
const checkInterval = setInterval(() => {
|
|
724
|
+
if (this.connectionRecords.size === 0) {
|
|
725
|
+
clearInterval(checkInterval);
|
|
726
|
+
resolve();
|
|
727
|
+
}
|
|
728
|
+
}, 1000);
|
|
729
|
+
// Force resolve after timeout
|
|
730
|
+
setTimeout(() => {
|
|
731
|
+
clearInterval(checkInterval);
|
|
732
|
+
if (this.connectionRecords.size > 0) {
|
|
733
|
+
console.log(`Forcing shutdown with ${this.connectionRecords.size} connections still active`);
|
|
734
|
+
// Force destroy any remaining connections
|
|
735
|
+
for (const record of this.connectionRecords.values()) {
|
|
736
|
+
if (!record.incoming.destroyed) {
|
|
737
|
+
record.incoming.destroy();
|
|
738
|
+
}
|
|
739
|
+
if (record.outgoing && !record.outgoing.destroyed) {
|
|
740
|
+
record.outgoing.destroy();
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
this.connectionRecords.clear();
|
|
744
|
+
}
|
|
745
|
+
resolve();
|
|
746
|
+
}, shutdownTimeout);
|
|
747
|
+
});
|
|
748
|
+
console.log("PortProxy shutdown complete.");
|
|
471
749
|
}
|
|
472
750
|
}
|
|
473
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQTBCeEM7Ozs7R0FJRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV4QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLElBQUksVUFBVSxLQUFLLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlCQUFpQjtJQUUxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsWUFBWTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRXZELE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9DLElBQUksYUFBYSxLQUFLLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGtCQUFrQjtJQUU3RCxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBQ3JELE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsaUNBQWlDO0lBRW5ELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsTUFBTSxJQUFJLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxrQkFBa0I7SUFFakQsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FB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
|
|
751
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQTRCeEM7Ozs7R0FJRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV4QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLElBQUksVUFBVSxLQUFLLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlCQUFpQjtJQUUxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsWUFBWTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRXZELE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9DLElBQUksYUFBYSxLQUFLLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQyxDQUFDLGtCQUFrQjtJQUU3RCxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBQ3JELE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsaUNBQWlDO0lBRW5ELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsTUFBTSxJQUFJLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxrQkFBa0I7SUFFakQsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FB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
|