@push.rocks/smartproxy 19.3.10 → 19.3.12
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/core/utils/index.d.ts +1 -0
- package/dist_ts/core/utils/index.js +2 -1
- package/dist_ts/core/utils/logger.d.ts +2 -0
- package/dist_ts/core/utils/logger.js +8 -0
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +4 -2
- package/dist_ts/proxies/smart-proxy/certificate-manager.js +26 -25
- package/dist_ts/proxies/smart-proxy/connection-manager.js +90 -27
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +269 -67
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +42 -27
- package/package.json +2 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/utils/index.ts +1 -0
- package/ts/core/utils/logger.ts +10 -0
- package/ts/plugins.ts +4 -0
- package/ts/proxies/smart-proxy/certificate-manager.ts +25 -24
- package/ts/proxies/smart-proxy/connection-manager.ts +95 -48
- package/ts/proxies/smart-proxy/route-connection-handler.ts +286 -139
- package/ts/proxies/smart-proxy/smart-proxy.ts +41 -28
|
@@ -2,6 +2,7 @@ import * as plugins from '../../plugins.js';
|
|
|
2
2
|
import type { IConnectionRecord, ISmartProxyOptions } from './models/interfaces.js';
|
|
3
3
|
import { SecurityManager } from './security-manager.js';
|
|
4
4
|
import { TimeoutManager } from './timeout-manager.js';
|
|
5
|
+
import { logger } from '../../core/utils/logger.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Manages connection lifecycle, tracking, and cleanup
|
|
@@ -97,7 +98,7 @@ export class ConnectionManager {
|
|
|
97
98
|
*/
|
|
98
99
|
public initiateCleanupOnce(record: IConnectionRecord, reason: string = 'normal'): void {
|
|
99
100
|
if (this.settings.enableDetailedLogging) {
|
|
100
|
-
|
|
101
|
+
logger.log('info', `Connection cleanup initiated`, { connectionId: record.id, remoteIP: record.remoteIP, reason, component: 'connection-manager' });
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
if (
|
|
@@ -139,7 +140,7 @@ export class ConnectionManager {
|
|
|
139
140
|
// Reset the handler references
|
|
140
141
|
record.renegotiationHandler = undefined;
|
|
141
142
|
} catch (err) {
|
|
142
|
-
|
|
143
|
+
logger.log('error', `Error removing data handlers for connection ${record.id}: ${err}`, { connectionId: record.id, error: err, component: 'connection-manager' });
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
|
|
@@ -160,16 +161,36 @@ export class ConnectionManager {
|
|
|
160
161
|
|
|
161
162
|
// Log connection details
|
|
162
163
|
if (this.settings.enableDetailedLogging) {
|
|
163
|
-
|
|
164
|
-
`
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
logger.log('info',
|
|
165
|
+
`Connection from ${record.remoteIP} on port ${record.localPort} terminated (${reason}). ` +
|
|
166
|
+
`Duration: ${plugins.prettyMs(duration)}, Bytes IN: ${bytesReceived}, OUT: ${bytesSent}, ` +
|
|
167
|
+
`TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${record.hasKeepAlive ? 'Yes' : 'No'}` +
|
|
168
|
+
`${record.usingNetworkProxy ? ', Using NetworkProxy' : ''}` +
|
|
169
|
+
`${record.domainSwitches ? `, Domain switches: ${record.domainSwitches}` : ''}`,
|
|
170
|
+
{
|
|
171
|
+
connectionId: record.id,
|
|
172
|
+
remoteIP: record.remoteIP,
|
|
173
|
+
localPort: record.localPort,
|
|
174
|
+
reason,
|
|
175
|
+
duration: plugins.prettyMs(duration),
|
|
176
|
+
bytes: { in: bytesReceived, out: bytesSent },
|
|
177
|
+
tls: record.isTLS,
|
|
178
|
+
keepAlive: record.hasKeepAlive,
|
|
179
|
+
usingNetworkProxy: record.usingNetworkProxy,
|
|
180
|
+
domainSwitches: record.domainSwitches || 0,
|
|
181
|
+
component: 'connection-manager'
|
|
182
|
+
}
|
|
169
183
|
);
|
|
170
184
|
} else {
|
|
171
|
-
|
|
172
|
-
`
|
|
185
|
+
logger.log('info',
|
|
186
|
+
`Connection from ${record.remoteIP} terminated (${reason}). Active connections: ${this.connectionRecords.size}`,
|
|
187
|
+
{
|
|
188
|
+
connectionId: record.id,
|
|
189
|
+
remoteIP: record.remoteIP,
|
|
190
|
+
reason,
|
|
191
|
+
activeConnections: this.connectionRecords.size,
|
|
192
|
+
component: 'connection-manager'
|
|
193
|
+
}
|
|
173
194
|
);
|
|
174
195
|
}
|
|
175
196
|
}
|
|
@@ -189,7 +210,7 @@ export class ConnectionManager {
|
|
|
189
210
|
socket.destroy();
|
|
190
211
|
}
|
|
191
212
|
} catch (err) {
|
|
192
|
-
|
|
213
|
+
logger.log('error', `Error destroying ${side} socket for connection ${record.id}: ${err}`, { connectionId: record.id, side, error: err, component: 'connection-manager' });
|
|
193
214
|
}
|
|
194
215
|
}, 1000);
|
|
195
216
|
|
|
@@ -199,13 +220,13 @@ export class ConnectionManager {
|
|
|
199
220
|
}
|
|
200
221
|
}
|
|
201
222
|
} catch (err) {
|
|
202
|
-
|
|
223
|
+
logger.log('error', `Error closing ${side} socket for connection ${record.id}: ${err}`, { connectionId: record.id, side, error: err, component: 'connection-manager' });
|
|
203
224
|
try {
|
|
204
225
|
if (!socket.destroyed) {
|
|
205
226
|
socket.destroy();
|
|
206
227
|
}
|
|
207
228
|
} catch (destroyErr) {
|
|
208
|
-
|
|
229
|
+
logger.log('error', `Error destroying ${side} socket for connection ${record.id}: ${destroyErr}`, { connectionId: record.id, side, error: destroyErr, component: 'connection-manager' });
|
|
209
230
|
}
|
|
210
231
|
}
|
|
211
232
|
}
|
|
@@ -224,21 +245,36 @@ export class ConnectionManager {
|
|
|
224
245
|
|
|
225
246
|
if (code === 'ECONNRESET') {
|
|
226
247
|
reason = 'econnreset';
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
248
|
+
logger.log('warn', `ECONNRESET on ${side} connection from ${record.remoteIP}. Error: ${err.message}. Duration: ${plugins.prettyMs(connectionDuration)}, Last activity: ${plugins.prettyMs(lastActivityAge)}`, {
|
|
249
|
+
connectionId: record.id,
|
|
250
|
+
side,
|
|
251
|
+
remoteIP: record.remoteIP,
|
|
252
|
+
error: err.message,
|
|
253
|
+
duration: plugins.prettyMs(connectionDuration),
|
|
254
|
+
lastActivity: plugins.prettyMs(lastActivityAge),
|
|
255
|
+
component: 'connection-manager'
|
|
256
|
+
});
|
|
231
257
|
} else if (code === 'ETIMEDOUT') {
|
|
232
258
|
reason = 'etimedout';
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
259
|
+
logger.log('warn', `ETIMEDOUT on ${side} connection from ${record.remoteIP}. Error: ${err.message}. Duration: ${plugins.prettyMs(connectionDuration)}, Last activity: ${plugins.prettyMs(lastActivityAge)}`, {
|
|
260
|
+
connectionId: record.id,
|
|
261
|
+
side,
|
|
262
|
+
remoteIP: record.remoteIP,
|
|
263
|
+
error: err.message,
|
|
264
|
+
duration: plugins.prettyMs(connectionDuration),
|
|
265
|
+
lastActivity: plugins.prettyMs(lastActivityAge),
|
|
266
|
+
component: 'connection-manager'
|
|
267
|
+
});
|
|
237
268
|
} else {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
269
|
+
logger.log('error', `Error on ${side} connection from ${record.remoteIP}: ${err.message}. Duration: ${plugins.prettyMs(connectionDuration)}, Last activity: ${plugins.prettyMs(lastActivityAge)}`, {
|
|
270
|
+
connectionId: record.id,
|
|
271
|
+
side,
|
|
272
|
+
remoteIP: record.remoteIP,
|
|
273
|
+
error: err.message,
|
|
274
|
+
duration: plugins.prettyMs(connectionDuration),
|
|
275
|
+
lastActivity: plugins.prettyMs(lastActivityAge),
|
|
276
|
+
component: 'connection-manager'
|
|
277
|
+
});
|
|
242
278
|
}
|
|
243
279
|
|
|
244
280
|
if (side === 'incoming' && record.incomingTerminationReason === null) {
|
|
@@ -259,7 +295,12 @@ export class ConnectionManager {
|
|
|
259
295
|
public handleClose(side: 'incoming' | 'outgoing', record: IConnectionRecord) {
|
|
260
296
|
return () => {
|
|
261
297
|
if (this.settings.enableDetailedLogging) {
|
|
262
|
-
|
|
298
|
+
logger.log('info', `Connection closed on ${side} side`, {
|
|
299
|
+
connectionId: record.id,
|
|
300
|
+
side,
|
|
301
|
+
remoteIP: record.remoteIP,
|
|
302
|
+
component: 'connection-manager'
|
|
303
|
+
});
|
|
263
304
|
}
|
|
264
305
|
|
|
265
306
|
if (side === 'incoming' && record.incomingTerminationReason === null) {
|
|
@@ -321,11 +362,13 @@ export class ConnectionManager {
|
|
|
321
362
|
if (inactivityTime > effectiveTimeout && !record.connectionClosed) {
|
|
322
363
|
// For keep-alive connections, issue a warning first
|
|
323
364
|
if (record.hasKeepAlive && !record.inactivityWarningIssued) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
365
|
+
logger.log('warn', `Keep-alive connection ${id} from ${record.remoteIP} inactive for ${plugins.prettyMs(inactivityTime)}. Will close in 10 minutes if no activity.`, {
|
|
366
|
+
connectionId: id,
|
|
367
|
+
remoteIP: record.remoteIP,
|
|
368
|
+
inactiveFor: plugins.prettyMs(inactivityTime),
|
|
369
|
+
closureWarning: '10 minutes',
|
|
370
|
+
component: 'connection-manager'
|
|
371
|
+
});
|
|
329
372
|
|
|
330
373
|
// Set warning flag and add grace period
|
|
331
374
|
record.inactivityWarningIssued = true;
|
|
@@ -337,27 +380,30 @@ export class ConnectionManager {
|
|
|
337
380
|
record.outgoing.write(Buffer.alloc(0));
|
|
338
381
|
|
|
339
382
|
if (this.settings.enableDetailedLogging) {
|
|
340
|
-
|
|
383
|
+
logger.log('info', `Sent probe packet to test keep-alive connection ${id}`, { connectionId: id, component: 'connection-manager' });
|
|
341
384
|
}
|
|
342
385
|
} catch (err) {
|
|
343
|
-
|
|
386
|
+
logger.log('error', `Error sending probe packet to connection ${id}: ${err}`, { connectionId: id, error: err, component: 'connection-manager' });
|
|
344
387
|
}
|
|
345
388
|
}
|
|
346
389
|
} else {
|
|
347
390
|
// For non-keep-alive or after warning, close the connection
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
391
|
+
logger.log('warn', `Closing inactive connection ${id} from ${record.remoteIP} (inactive for ${plugins.prettyMs(inactivityTime)}, keep-alive: ${record.hasKeepAlive ? 'Yes' : 'No'})`, {
|
|
392
|
+
connectionId: id,
|
|
393
|
+
remoteIP: record.remoteIP,
|
|
394
|
+
inactiveFor: plugins.prettyMs(inactivityTime),
|
|
395
|
+
hasKeepAlive: record.hasKeepAlive,
|
|
396
|
+
component: 'connection-manager'
|
|
397
|
+
});
|
|
353
398
|
this.cleanupConnection(record, 'inactivity');
|
|
354
399
|
}
|
|
355
400
|
} else if (inactivityTime <= effectiveTimeout && record.inactivityWarningIssued) {
|
|
356
401
|
// If activity detected after warning, clear the warning
|
|
357
402
|
if (this.settings.enableDetailedLogging) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
403
|
+
logger.log('info', `Connection ${id} activity detected after inactivity warning`, {
|
|
404
|
+
connectionId: id,
|
|
405
|
+
component: 'connection-manager'
|
|
406
|
+
});
|
|
361
407
|
}
|
|
362
408
|
record.inactivityWarningIssued = false;
|
|
363
409
|
}
|
|
@@ -369,11 +415,12 @@ export class ConnectionManager {
|
|
|
369
415
|
!record.connectionClosed &&
|
|
370
416
|
now - record.outgoingClosedTime > 120000
|
|
371
417
|
) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
418
|
+
logger.log('warn', `Parity check: Connection ${id} from ${record.remoteIP} has incoming socket still active ${plugins.prettyMs(now - record.outgoingClosedTime)} after outgoing socket closed`, {
|
|
419
|
+
connectionId: id,
|
|
420
|
+
remoteIP: record.remoteIP,
|
|
421
|
+
timeElapsed: plugins.prettyMs(now - record.outgoingClosedTime),
|
|
422
|
+
component: 'connection-manager'
|
|
423
|
+
});
|
|
377
424
|
this.cleanupConnection(record, 'parity_check');
|
|
378
425
|
}
|
|
379
426
|
}
|
|
@@ -406,7 +453,7 @@ export class ConnectionManager {
|
|
|
406
453
|
record.outgoing.end();
|
|
407
454
|
}
|
|
408
455
|
} catch (err) {
|
|
409
|
-
|
|
456
|
+
logger.log('error', `Error during graceful end of connection ${id}: ${err}`, { connectionId: id, error: err, component: 'connection-manager' });
|
|
410
457
|
}
|
|
411
458
|
}
|
|
412
459
|
}
|
|
@@ -433,7 +480,7 @@ export class ConnectionManager {
|
|
|
433
480
|
}
|
|
434
481
|
}
|
|
435
482
|
} catch (err) {
|
|
436
|
-
|
|
483
|
+
logger.log('error', `Error during forced destruction of connection ${id}: ${err}`, { connectionId: id, error: err, component: 'connection-manager' });
|
|
437
484
|
}
|
|
438
485
|
}
|
|
439
486
|
}
|