@push.rocks/smartproxy 19.6.2 → 19.6.7

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.
Files changed (52) hide show
  1. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +4 -7
  2. package/dist_ts/proxies/smart-proxy/connection-manager.js +22 -22
  3. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +4 -3
  4. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +9 -9
  5. package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +68 -56
  6. package/dist_ts/proxies/smart-proxy/metrics-collector.js +226 -176
  7. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -0
  8. package/dist_ts/proxies/smart-proxy/models/metrics-types.d.ts +94 -48
  9. package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +4 -4
  10. package/dist_ts/proxies/smart-proxy/nftables-manager.js +6 -6
  11. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +4 -7
  12. package/dist_ts/proxies/smart-proxy/port-manager.js +6 -9
  13. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +4 -15
  14. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +128 -128
  15. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +3 -3
  16. package/dist_ts/proxies/smart-proxy/security-manager.js +9 -9
  17. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +20 -13
  18. package/dist_ts/proxies/smart-proxy/smart-proxy.js +16 -13
  19. package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +36 -0
  20. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +117 -0
  21. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +4 -3
  22. package/dist_ts/proxies/smart-proxy/timeout-manager.js +16 -16
  23. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +3 -3
  24. package/dist_ts/proxies/smart-proxy/tls-manager.js +12 -12
  25. package/package.json +8 -17
  26. package/readme.hints.md +0 -897
  27. package/readme.md +960 -54
  28. package/readme.plan.md +301 -562
  29. package/ts/proxies/smart-proxy/connection-manager.ts +23 -21
  30. package/ts/proxies/smart-proxy/http-proxy-bridge.ts +9 -8
  31. package/ts/proxies/smart-proxy/metrics-collector.ts +277 -189
  32. package/ts/proxies/smart-proxy/models/interfaces.ts +7 -0
  33. package/ts/proxies/smart-proxy/models/metrics-types.ts +93 -41
  34. package/ts/proxies/smart-proxy/nftables-manager.ts +5 -5
  35. package/ts/proxies/smart-proxy/port-manager.ts +6 -14
  36. package/ts/proxies/smart-proxy/route-connection-handler.ts +136 -136
  37. package/ts/proxies/smart-proxy/security-manager.ts +8 -8
  38. package/ts/proxies/smart-proxy/smart-proxy.ts +26 -35
  39. package/ts/proxies/smart-proxy/throughput-tracker.ts +144 -0
  40. package/ts/proxies/smart-proxy/timeout-manager.ts +16 -15
  41. package/ts/proxies/smart-proxy/tls-manager.ts +11 -11
  42. package/readme.connections.md +0 -724
  43. package/readme.delete.md +0 -187
  44. package/readme.memory-leaks-fixed.md +0 -45
  45. package/readme.metrics.md +0 -591
  46. package/readme.monitoring.md +0 -202
  47. package/readme.proxy-chain-summary.md +0 -112
  48. package/readme.proxy-protocol-example.md +0 -462
  49. package/readme.proxy-protocol.md +0 -415
  50. package/readme.routing.md +0 -341
  51. package/readme.websocket-keepalive-config.md +0 -140
  52. package/readme.websocket-keepalive-fix.md +0 -63
@@ -4,23 +4,16 @@ import { logger } from '../../core/utils/logger.js';
4
4
  // Route checking functions have been removed
5
5
  import type { IRouteConfig, IRouteAction } from './models/route-types.js';
6
6
  import type { IRouteContext } from '../../core/models/route-context.js';
7
- import { ConnectionManager } from './connection-manager.js';
8
- import { SecurityManager } from './security-manager.js';
9
- import { TlsManager } from './tls-manager.js';
10
- import { HttpProxyBridge } from './http-proxy-bridge.js';
11
- import { TimeoutManager } from './timeout-manager.js';
12
- import { SharedRouteManager as RouteManager } from '../../core/routing/route-manager.js';
13
7
  import { cleanupSocket, setupSocketHandlers, createSocketWithErrorHandler, setupBidirectionalForwarding } from '../../core/utils/socket-utils.js';
14
8
  import { WrappedSocket } from '../../core/models/wrapped-socket.js';
15
9
  import { getUnderlyingSocket } from '../../core/models/socket-types.js';
16
10
  import { ProxyProtocolParser } from '../../core/utils/proxy-protocol.js';
11
+ import type { SmartProxy } from './smart-proxy.js';
17
12
 
18
13
  /**
19
14
  * Handles new connection processing and setup logic with support for route-based configuration
20
15
  */
21
16
  export class RouteConnectionHandler {
22
- private settings: ISmartProxyOptions;
23
-
24
17
  // Note: Route context caching was considered but not implemented
25
18
  // as route contexts are lightweight and should be created fresh
26
19
  // for each connection to ensure accurate context data
@@ -29,16 +22,8 @@ export class RouteConnectionHandler {
29
22
  public newConnectionSubject = new plugins.smartrx.rxjs.Subject<IConnectionRecord>();
30
23
 
31
24
  constructor(
32
- settings: ISmartProxyOptions,
33
- private connectionManager: ConnectionManager,
34
- private securityManager: SecurityManager,
35
- private tlsManager: TlsManager,
36
- private httpProxyBridge: HttpProxyBridge,
37
- private timeoutManager: TimeoutManager,
38
- private routeManager: RouteManager
39
- ) {
40
- this.settings = settings;
41
- }
25
+ private smartProxy: SmartProxy
26
+ ) {}
42
27
 
43
28
 
44
29
  /**
@@ -93,7 +78,7 @@ export class RouteConnectionHandler {
93
78
  const wrappedSocket = new WrappedSocket(socket);
94
79
 
95
80
  // If this is from a trusted proxy, log it
96
- if (this.settings.proxyIPs?.includes(remoteIP)) {
81
+ if (this.smartProxy.settings.proxyIPs?.includes(remoteIP)) {
97
82
  logger.log('debug', `Connection from trusted proxy ${remoteIP}, PROXY protocol parsing will be enabled`, {
98
83
  remoteIP,
99
84
  component: 'route-handler'
@@ -102,7 +87,7 @@ export class RouteConnectionHandler {
102
87
 
103
88
  // Validate IP against rate limits and connection limits
104
89
  // Note: For wrapped sockets, this will use the underlying socket IP until PROXY protocol is parsed
105
- const ipValidation = this.securityManager.validateIP(wrappedSocket.remoteAddress || '');
90
+ const ipValidation = this.smartProxy.securityManager.validateIP(wrappedSocket.remoteAddress || '');
106
91
  if (!ipValidation.allowed) {
107
92
  logger.log('warn', `Connection rejected`, { remoteIP: wrappedSocket.remoteAddress, reason: ipValidation.reason, component: 'route-handler' });
108
93
  cleanupSocket(wrappedSocket.socket, `rejected-${ipValidation.reason}`, { immediate: true });
@@ -110,7 +95,7 @@ export class RouteConnectionHandler {
110
95
  }
111
96
 
112
97
  // Create a new connection record with the wrapped socket
113
- const record = this.connectionManager.createConnection(wrappedSocket);
98
+ const record = this.smartProxy.connectionManager.createConnection(wrappedSocket);
114
99
  if (!record) {
115
100
  // Connection was rejected due to limit - socket already destroyed by connection manager
116
101
  return;
@@ -122,15 +107,15 @@ export class RouteConnectionHandler {
122
107
 
123
108
  // Apply socket optimizations (apply to underlying socket)
124
109
  const underlyingSocket = wrappedSocket.socket;
125
- underlyingSocket.setNoDelay(this.settings.noDelay);
110
+ underlyingSocket.setNoDelay(this.smartProxy.settings.noDelay);
126
111
 
127
112
  // Apply keep-alive settings if enabled
128
- if (this.settings.keepAlive) {
129
- underlyingSocket.setKeepAlive(true, this.settings.keepAliveInitialDelay);
113
+ if (this.smartProxy.settings.keepAlive) {
114
+ underlyingSocket.setKeepAlive(true, this.smartProxy.settings.keepAliveInitialDelay);
130
115
  record.hasKeepAlive = true;
131
116
 
132
117
  // Apply enhanced TCP keep-alive options if enabled
133
- if (this.settings.enableKeepAliveProbes) {
118
+ if (this.smartProxy.settings.enableKeepAliveProbes) {
134
119
  try {
135
120
  // These are platform-specific and may not be available
136
121
  if ('setKeepAliveProbes' in underlyingSocket) {
@@ -141,34 +126,34 @@ export class RouteConnectionHandler {
141
126
  }
142
127
  } catch (err) {
143
128
  // Ignore errors - these are optional enhancements
144
- if (this.settings.enableDetailedLogging) {
129
+ if (this.smartProxy.settings.enableDetailedLogging) {
145
130
  logger.log('warn', `Enhanced TCP keep-alive settings not supported`, { connectionId, error: err, component: 'route-handler' });
146
131
  }
147
132
  }
148
133
  }
149
134
  }
150
135
 
151
- if (this.settings.enableDetailedLogging) {
136
+ if (this.smartProxy.settings.enableDetailedLogging) {
152
137
  logger.log('info',
153
138
  `New connection from ${remoteIP} on port ${localPort}. ` +
154
139
  `Keep-Alive: ${record.hasKeepAlive ? 'Enabled' : 'Disabled'}. ` +
155
- `Active connections: ${this.connectionManager.getConnectionCount()}`,
140
+ `Active connections: ${this.smartProxy.connectionManager.getConnectionCount()}`,
156
141
  {
157
142
  connectionId,
158
143
  remoteIP,
159
144
  localPort,
160
145
  keepAlive: record.hasKeepAlive ? 'Enabled' : 'Disabled',
161
- activeConnections: this.connectionManager.getConnectionCount(),
146
+ activeConnections: this.smartProxy.connectionManager.getConnectionCount(),
162
147
  component: 'route-handler'
163
148
  }
164
149
  );
165
150
  } else {
166
151
  logger.log('info',
167
- `New connection from ${remoteIP} on port ${localPort}. Active connections: ${this.connectionManager.getConnectionCount()}`,
152
+ `New connection from ${remoteIP} on port ${localPort}. Active connections: ${this.smartProxy.connectionManager.getConnectionCount()}`,
168
153
  {
169
154
  remoteIP,
170
155
  localPort,
171
- activeConnections: this.connectionManager.getConnectionCount(),
156
+ activeConnections: this.smartProxy.connectionManager.getConnectionCount(),
172
157
  component: 'route-handler'
173
158
  }
174
159
  );
@@ -187,10 +172,10 @@ export class RouteConnectionHandler {
187
172
  let initialDataReceived = false;
188
173
 
189
174
  // Check if any routes on this port require TLS handling
190
- const allRoutes = this.routeManager.getRoutes();
175
+ const allRoutes = this.smartProxy.routeManager.getRoutes();
191
176
  const needsTlsHandling = allRoutes.some(route => {
192
177
  // Check if route matches this port
193
- const matchesPort = this.routeManager.getRoutesForPort(localPort).includes(route);
178
+ const matchesPort = this.smartProxy.routeManager.getRoutesForPort(localPort).includes(route);
194
179
 
195
180
  return matchesPort &&
196
181
  route.action.type === 'forward' &&
@@ -229,7 +214,7 @@ export class RouteConnectionHandler {
229
214
  }
230
215
 
231
216
  // Always cleanup the connection record
232
- this.connectionManager.cleanupConnection(record, reason);
217
+ this.smartProxy.connectionManager.cleanupConnection(record, reason);
233
218
  },
234
219
  undefined, // Use default timeout handler
235
220
  'immediate-route-client'
@@ -244,9 +229,9 @@ export class RouteConnectionHandler {
244
229
  // Set an initial timeout for handshake data
245
230
  let initialTimeout: NodeJS.Timeout | null = setTimeout(() => {
246
231
  if (!initialDataReceived) {
247
- logger.log('warn', `No initial data received from ${record.remoteIP} after ${this.settings.initialDataTimeout}ms for connection ${connectionId}`, {
232
+ logger.log('warn', `No initial data received from ${record.remoteIP} after ${this.smartProxy.settings.initialDataTimeout}ms for connection ${connectionId}`, {
248
233
  connectionId,
249
- timeout: this.settings.initialDataTimeout,
234
+ timeout: this.smartProxy.settings.initialDataTimeout,
250
235
  remoteIP: record.remoteIP,
251
236
  component: 'route-handler'
252
237
  });
@@ -260,14 +245,14 @@ export class RouteConnectionHandler {
260
245
  });
261
246
  if (record.incomingTerminationReason === null) {
262
247
  record.incomingTerminationReason = 'initial_timeout';
263
- this.connectionManager.incrementTerminationStat('incoming', 'initial_timeout');
248
+ this.smartProxy.connectionManager.incrementTerminationStat('incoming', 'initial_timeout');
264
249
  }
265
250
  socket.end();
266
- this.connectionManager.cleanupConnection(record, 'initial_timeout');
251
+ this.smartProxy.connectionManager.cleanupConnection(record, 'initial_timeout');
267
252
  }
268
253
  }, 30000);
269
254
  }
270
- }, this.settings.initialDataTimeout!);
255
+ }, this.smartProxy.settings.initialDataTimeout!);
271
256
 
272
257
  // Make sure timeout doesn't keep the process alive
273
258
  if (initialTimeout.unref) {
@@ -275,7 +260,7 @@ export class RouteConnectionHandler {
275
260
  }
276
261
 
277
262
  // Set up error handler
278
- socket.on('error', this.connectionManager.handleError('incoming', record));
263
+ socket.on('error', this.smartProxy.connectionManager.handleError('incoming', record));
279
264
 
280
265
  // Add close/end handlers to catch immediate disconnections
281
266
  socket.once('close', () => {
@@ -289,7 +274,7 @@ export class RouteConnectionHandler {
289
274
  clearTimeout(initialTimeout);
290
275
  initialTimeout = null;
291
276
  }
292
- this.connectionManager.cleanupConnection(record, 'closed_before_data');
277
+ this.smartProxy.connectionManager.cleanupConnection(record, 'closed_before_data');
293
278
  }
294
279
  });
295
280
 
@@ -311,7 +296,7 @@ export class RouteConnectionHandler {
311
296
  // Handler for processing initial data (after potential PROXY protocol)
312
297
  const processInitialData = (chunk: Buffer) => {
313
298
  // Block non-TLS connections on port 443
314
- if (!this.tlsManager.isTlsHandshake(chunk) && localPort === 443) {
299
+ if (!this.smartProxy.tlsManager.isTlsHandshake(chunk) && localPort === 443) {
315
300
  logger.log('warn', `Non-TLS connection ${connectionId} detected on port 443. Terminating connection - only TLS traffic is allowed on standard HTTPS port.`, {
316
301
  connectionId,
317
302
  message: 'Terminating connection - only TLS traffic is allowed on standard HTTPS port.',
@@ -319,20 +304,20 @@ export class RouteConnectionHandler {
319
304
  });
320
305
  if (record.incomingTerminationReason === null) {
321
306
  record.incomingTerminationReason = 'non_tls_blocked';
322
- this.connectionManager.incrementTerminationStat('incoming', 'non_tls_blocked');
307
+ this.smartProxy.connectionManager.incrementTerminationStat('incoming', 'non_tls_blocked');
323
308
  }
324
309
  socket.end();
325
- this.connectionManager.cleanupConnection(record, 'non_tls_blocked');
310
+ this.smartProxy.connectionManager.cleanupConnection(record, 'non_tls_blocked');
326
311
  return;
327
312
  }
328
313
 
329
314
  // Check if this looks like a TLS handshake
330
315
  let serverName = '';
331
- if (this.tlsManager.isTlsHandshake(chunk)) {
316
+ if (this.smartProxy.tlsManager.isTlsHandshake(chunk)) {
332
317
  record.isTLS = true;
333
318
 
334
319
  // Check for ClientHello to extract SNI
335
- if (this.tlsManager.isClientHello(chunk)) {
320
+ if (this.smartProxy.tlsManager.isClientHello(chunk)) {
336
321
  // Create connection info for SNI extraction
337
322
  const connInfo = {
338
323
  sourceIp: record.remoteIP,
@@ -342,20 +327,20 @@ export class RouteConnectionHandler {
342
327
  };
343
328
 
344
329
  // Extract SNI
345
- serverName = this.tlsManager.extractSNI(chunk, connInfo) || '';
330
+ serverName = this.smartProxy.tlsManager.extractSNI(chunk, connInfo) || '';
346
331
 
347
332
  // Lock the connection to the negotiated SNI
348
333
  record.lockedDomain = serverName;
349
334
 
350
335
  // Check if we should reject connections without SNI
351
- if (!serverName && this.settings.allowSessionTicket === false) {
336
+ if (!serverName && this.smartProxy.settings.allowSessionTicket === false) {
352
337
  logger.log('warn', `No SNI detected in TLS ClientHello for connection ${connectionId}; sending TLS alert`, {
353
338
  connectionId,
354
339
  component: 'route-handler'
355
340
  });
356
341
  if (record.incomingTerminationReason === null) {
357
342
  record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
358
- this.connectionManager.incrementTerminationStat(
343
+ this.smartProxy.connectionManager.incrementTerminationStat(
359
344
  'incoming',
360
345
  'session_ticket_blocked_no_sni'
361
346
  );
@@ -369,11 +354,11 @@ export class RouteConnectionHandler {
369
354
  } catch {
370
355
  socket.end();
371
356
  }
372
- this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
357
+ this.smartProxy.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
373
358
  return;
374
359
  }
375
360
 
376
- if (this.settings.enableDetailedLogging) {
361
+ if (this.smartProxy.settings.enableDetailedLogging) {
377
362
  logger.log('info', `TLS connection with SNI`, {
378
363
  connectionId,
379
364
  serverName: serverName || '(empty)',
@@ -399,7 +384,7 @@ export class RouteConnectionHandler {
399
384
  record.hasReceivedInitialData = true;
400
385
 
401
386
  // Check if this is from a trusted proxy and might have PROXY protocol
402
- if (this.settings.proxyIPs?.includes(socket.remoteAddress || '') && this.settings.acceptProxyProtocol !== false) {
387
+ if (this.smartProxy.settings.proxyIPs?.includes(socket.remoteAddress || '') && this.smartProxy.settings.acceptProxyProtocol !== false) {
403
388
  // Check if this starts with PROXY protocol
404
389
  if (chunk.toString('ascii', 0, Math.min(6, chunk.length)).startsWith('PROXY ')) {
405
390
  try {
@@ -463,7 +448,7 @@ export class RouteConnectionHandler {
463
448
  const remoteIP = record.remoteIP;
464
449
 
465
450
  // Check if this is an HTTP proxy port
466
- const isHttpProxyPort = this.settings.useHttpProxy?.includes(localPort);
451
+ const isHttpProxyPort = this.smartProxy.settings.useHttpProxy?.includes(localPort);
467
452
 
468
453
  // For HTTP proxy ports without TLS, skip domain check since domain info comes from HTTP headers
469
454
  const skipDomainCheck = isHttpProxyPort && !record.isTLS;
@@ -482,7 +467,7 @@ export class RouteConnectionHandler {
482
467
  };
483
468
 
484
469
  // Find matching route
485
- const routeMatch = this.routeManager.findMatchingRoute(routeContext);
470
+ const routeMatch = this.smartProxy.routeManager.findMatchingRoute(routeContext);
486
471
 
487
472
  if (!routeMatch) {
488
473
  logger.log('warn', `No route found for ${serverName || 'connection'} on port ${localPort} (connection: ${connectionId})`, {
@@ -499,10 +484,10 @@ export class RouteConnectionHandler {
499
484
  });
500
485
 
501
486
  // Check default security settings
502
- const defaultSecuritySettings = this.settings.defaults?.security;
487
+ const defaultSecuritySettings = this.smartProxy.settings.defaults?.security;
503
488
  if (defaultSecuritySettings) {
504
489
  if (defaultSecuritySettings.ipAllowList && defaultSecuritySettings.ipAllowList.length > 0) {
505
- const isAllowed = this.securityManager.isIPAuthorized(
490
+ const isAllowed = this.smartProxy.securityManager.isIPAuthorized(
506
491
  remoteIP,
507
492
  defaultSecuritySettings.ipAllowList,
508
493
  defaultSecuritySettings.ipBlockList || []
@@ -515,17 +500,17 @@ export class RouteConnectionHandler {
515
500
  component: 'route-handler'
516
501
  });
517
502
  socket.end();
518
- this.connectionManager.cleanupConnection(record, 'ip_blocked');
503
+ this.smartProxy.connectionManager.cleanupConnection(record, 'ip_blocked');
519
504
  return;
520
505
  }
521
506
  }
522
507
  }
523
508
 
524
509
  // Setup direct connection with default settings
525
- if (this.settings.defaults?.target) {
510
+ if (this.smartProxy.settings.defaults?.target) {
526
511
  // Use defaults from configuration
527
- const targetHost = this.settings.defaults.target.host;
528
- const targetPort = this.settings.defaults.target.port;
512
+ const targetHost = this.smartProxy.settings.defaults.target.host;
513
+ const targetPort = this.smartProxy.settings.defaults.target.port;
529
514
 
530
515
  return this.setupDirectConnection(
531
516
  socket,
@@ -543,7 +528,7 @@ export class RouteConnectionHandler {
543
528
  component: 'route-handler'
544
529
  });
545
530
  socket.end();
546
- this.connectionManager.cleanupConnection(record, 'no_default_target');
531
+ this.smartProxy.connectionManager.cleanupConnection(record, 'no_default_target');
547
532
  return;
548
533
  }
549
534
  }
@@ -551,7 +536,7 @@ export class RouteConnectionHandler {
551
536
  // A matching route was found
552
537
  const route = routeMatch.route;
553
538
 
554
- if (this.settings.enableDetailedLogging) {
539
+ if (this.smartProxy.settings.enableDetailedLogging) {
555
540
  logger.log('info', `Route matched`, {
556
541
  connectionId,
557
542
  routeName: route.name || 'unnamed',
@@ -565,7 +550,7 @@ export class RouteConnectionHandler {
565
550
  if (route.security) {
566
551
  // Check IP allow/block lists
567
552
  if (route.security.ipAllowList || route.security.ipBlockList) {
568
- const isIPAllowed = this.securityManager.isIPAuthorized(
553
+ const isIPAllowed = this.smartProxy.securityManager.isIPAuthorized(
569
554
  remoteIP,
570
555
  route.security.ipAllowList || [],
571
556
  route.security.ipBlockList || []
@@ -579,7 +564,7 @@ export class RouteConnectionHandler {
579
564
  component: 'route-handler'
580
565
  });
581
566
  socket.end();
582
- this.connectionManager.cleanupConnection(record, 'route_ip_blocked');
567
+ this.smartProxy.connectionManager.cleanupConnection(record, 'route_ip_blocked');
583
568
  return;
584
569
  }
585
570
  }
@@ -588,7 +573,7 @@ export class RouteConnectionHandler {
588
573
  if (route.security.maxConnections !== undefined) {
589
574
  // TODO: Implement per-route connection tracking
590
575
  // For now, log that this feature is not yet implemented
591
- if (this.settings.enableDetailedLogging) {
576
+ if (this.smartProxy.settings.enableDetailedLogging) {
592
577
  logger.log('warn', `Route ${route.name} has maxConnections=${route.security.maxConnections} configured but per-route connection limits are not yet implemented`, {
593
578
  connectionId,
594
579
  routeName: route.name,
@@ -633,7 +618,7 @@ export class RouteConnectionHandler {
633
618
  component: 'route-handler'
634
619
  });
635
620
  socket.end();
636
- this.connectionManager.cleanupConnection(record, 'unknown_action');
621
+ this.smartProxy.connectionManager.cleanupConnection(record, 'unknown_action');
637
622
  }
638
623
  }
639
624
 
@@ -658,7 +643,7 @@ export class RouteConnectionHandler {
658
643
  // The application should NOT interfere with these connections
659
644
 
660
645
  // Log the connection for monitoring purposes
661
- if (this.settings.enableDetailedLogging) {
646
+ if (this.smartProxy.settings.enableDetailedLogging) {
662
647
  logger.log('info', `NFTables forwarding (kernel-level)`, {
663
648
  connectionId: record.id,
664
649
  source: `${record.remoteIP}:${socket.remotePort}`,
@@ -680,7 +665,7 @@ export class RouteConnectionHandler {
680
665
  // Additional NFTables-specific logging if configured
681
666
  if (action.nftables) {
682
667
  const nftConfig = action.nftables;
683
- if (this.settings.enableDetailedLogging) {
668
+ if (this.smartProxy.settings.enableDetailedLogging) {
684
669
  logger.log('info', `NFTables config`, {
685
670
  connectionId: record.id,
686
671
  protocol: nftConfig.protocol || 'tcp',
@@ -701,7 +686,7 @@ export class RouteConnectionHandler {
701
686
 
702
687
  // Set up cleanup when the socket eventually closes
703
688
  socket.once('close', () => {
704
- this.connectionManager.cleanupConnection(record, 'nftables_closed');
689
+ this.smartProxy.connectionManager.cleanupConnection(record, 'nftables_closed');
705
690
  });
706
691
 
707
692
  return;
@@ -714,7 +699,7 @@ export class RouteConnectionHandler {
714
699
  component: 'route-handler'
715
700
  });
716
701
  socket.end();
717
- this.connectionManager.cleanupConnection(record, 'missing_target');
702
+ this.smartProxy.connectionManager.cleanupConnection(record, 'missing_target');
718
703
  return;
719
704
  }
720
705
 
@@ -738,7 +723,7 @@ export class RouteConnectionHandler {
738
723
  if (typeof action.target.host === 'function') {
739
724
  try {
740
725
  targetHost = action.target.host(routeContext);
741
- if (this.settings.enableDetailedLogging) {
726
+ if (this.smartProxy.settings.enableDetailedLogging) {
742
727
  logger.log('info', `Dynamic host resolved to ${Array.isArray(targetHost) ? targetHost.join(', ') : targetHost} for connection ${connectionId}`, {
743
728
  connectionId,
744
729
  targetHost: Array.isArray(targetHost) ? targetHost.join(', ') : targetHost,
@@ -752,7 +737,7 @@ export class RouteConnectionHandler {
752
737
  component: 'route-handler'
753
738
  });
754
739
  socket.end();
755
- this.connectionManager.cleanupConnection(record, 'host_mapping_error');
740
+ this.smartProxy.connectionManager.cleanupConnection(record, 'host_mapping_error');
756
741
  return;
757
742
  }
758
743
  } else {
@@ -769,7 +754,7 @@ export class RouteConnectionHandler {
769
754
  if (typeof action.target.port === 'function') {
770
755
  try {
771
756
  targetPort = action.target.port(routeContext);
772
- if (this.settings.enableDetailedLogging) {
757
+ if (this.smartProxy.settings.enableDetailedLogging) {
773
758
  logger.log('info', `Dynamic port mapping from ${record.localPort} to ${targetPort} for connection ${connectionId}`, {
774
759
  connectionId,
775
760
  sourcePort: record.localPort,
@@ -786,7 +771,7 @@ export class RouteConnectionHandler {
786
771
  component: 'route-handler'
787
772
  });
788
773
  socket.end();
789
- this.connectionManager.cleanupConnection(record, 'port_mapping_error');
774
+ this.smartProxy.connectionManager.cleanupConnection(record, 'port_mapping_error');
790
775
  return;
791
776
  }
792
777
  } else if (action.target.port === 'preserve') {
@@ -805,7 +790,7 @@ export class RouteConnectionHandler {
805
790
  switch (action.tls.mode) {
806
791
  case 'passthrough':
807
792
  // For TLS passthrough, just forward directly
808
- if (this.settings.enableDetailedLogging) {
793
+ if (this.smartProxy.settings.enableDetailedLogging) {
809
794
  logger.log('info', `Using TLS passthrough to ${selectedHost}:${targetPort} for connection ${connectionId}`, {
810
795
  connectionId,
811
796
  targetHost: selectedHost,
@@ -827,8 +812,8 @@ export class RouteConnectionHandler {
827
812
  case 'terminate':
828
813
  case 'terminate-and-reencrypt':
829
814
  // For TLS termination, use HttpProxy
830
- if (this.httpProxyBridge.getHttpProxy()) {
831
- if (this.settings.enableDetailedLogging) {
815
+ if (this.smartProxy.httpProxyBridge.getHttpProxy()) {
816
+ if (this.smartProxy.settings.enableDetailedLogging) {
832
817
  logger.log('info', `Using HttpProxy for TLS termination to ${Array.isArray(action.target.host) ? action.target.host.join(', ') : action.target.host} for connection ${connectionId}`, {
833
818
  connectionId,
834
819
  targetHost: action.target.host,
@@ -838,13 +823,13 @@ export class RouteConnectionHandler {
838
823
 
839
824
  // If we have an initial chunk with TLS data, start processing it
840
825
  if (initialChunk && record.isTLS) {
841
- this.httpProxyBridge.forwardToHttpProxy(
826
+ this.smartProxy.httpProxyBridge.forwardToHttpProxy(
842
827
  connectionId,
843
828
  socket,
844
829
  record,
845
830
  initialChunk,
846
- this.settings.httpProxyPort || 8443,
847
- (reason) => this.connectionManager.cleanupConnection(record, reason)
831
+ this.smartProxy.settings.httpProxyPort || 8443,
832
+ (reason) => this.smartProxy.connectionManager.cleanupConnection(record, reason)
848
833
  );
849
834
  return;
850
835
  }
@@ -855,7 +840,7 @@ export class RouteConnectionHandler {
855
840
  component: 'route-handler'
856
841
  });
857
842
  socket.end();
858
- this.connectionManager.cleanupConnection(record, 'tls_error');
843
+ this.smartProxy.connectionManager.cleanupConnection(record, 'tls_error');
859
844
  return;
860
845
  } else {
861
846
  logger.log('error', `HttpProxy not available for TLS termination for connection ${connectionId}`, {
@@ -863,29 +848,29 @@ export class RouteConnectionHandler {
863
848
  component: 'route-handler'
864
849
  });
865
850
  socket.end();
866
- this.connectionManager.cleanupConnection(record, 'no_http_proxy');
851
+ this.smartProxy.connectionManager.cleanupConnection(record, 'no_http_proxy');
867
852
  return;
868
853
  }
869
854
  }
870
855
  } else {
871
856
  // No TLS settings - check if this port should use HttpProxy
872
- const isHttpProxyPort = this.settings.useHttpProxy?.includes(record.localPort);
857
+ const isHttpProxyPort = this.smartProxy.settings.useHttpProxy?.includes(record.localPort);
873
858
 
874
859
  // Debug logging
875
- if (this.settings.enableDetailedLogging) {
876
- logger.log('debug', `Checking HttpProxy forwarding: port=${record.localPort}, useHttpProxy=${JSON.stringify(this.settings.useHttpProxy)}, isHttpProxyPort=${isHttpProxyPort}, hasHttpProxy=${!!this.httpProxyBridge.getHttpProxy()}`, {
860
+ if (this.smartProxy.settings.enableDetailedLogging) {
861
+ logger.log('debug', `Checking HttpProxy forwarding: port=${record.localPort}, useHttpProxy=${JSON.stringify(this.smartProxy.settings.useHttpProxy)}, isHttpProxyPort=${isHttpProxyPort}, hasHttpProxy=${!!this.smartProxy.httpProxyBridge.getHttpProxy()}`, {
877
862
  connectionId,
878
863
  localPort: record.localPort,
879
- useHttpProxy: this.settings.useHttpProxy,
864
+ useHttpProxy: this.smartProxy.settings.useHttpProxy,
880
865
  isHttpProxyPort,
881
- hasHttpProxy: !!this.httpProxyBridge.getHttpProxy(),
866
+ hasHttpProxy: !!this.smartProxy.httpProxyBridge.getHttpProxy(),
882
867
  component: 'route-handler'
883
868
  });
884
869
  }
885
870
 
886
- if (isHttpProxyPort && this.httpProxyBridge.getHttpProxy()) {
871
+ if (isHttpProxyPort && this.smartProxy.httpProxyBridge.getHttpProxy()) {
887
872
  // Forward non-TLS connections to HttpProxy if configured
888
- if (this.settings.enableDetailedLogging) {
873
+ if (this.smartProxy.settings.enableDetailedLogging) {
889
874
  logger.log('info', `Using HttpProxy for non-TLS connection ${connectionId} on port ${record.localPort}`, {
890
875
  connectionId,
891
876
  port: record.localPort,
@@ -893,18 +878,18 @@ export class RouteConnectionHandler {
893
878
  });
894
879
  }
895
880
 
896
- this.httpProxyBridge.forwardToHttpProxy(
881
+ this.smartProxy.httpProxyBridge.forwardToHttpProxy(
897
882
  connectionId,
898
883
  socket,
899
884
  record,
900
885
  initialChunk,
901
- this.settings.httpProxyPort || 8443,
902
- (reason) => this.connectionManager.cleanupConnection(record, reason)
886
+ this.smartProxy.settings.httpProxyPort || 8443,
887
+ (reason) => this.smartProxy.connectionManager.cleanupConnection(record, reason)
903
888
  );
904
889
  return;
905
890
  } else {
906
891
  // Basic forwarding
907
- if (this.settings.enableDetailedLogging) {
892
+ if (this.smartProxy.settings.enableDetailedLogging) {
908
893
  logger.log('info', `Using basic forwarding to ${Array.isArray(action.target.host) ? action.target.host.join(', ') : action.target.host}:${action.target.port} for connection ${connectionId}`, {
909
894
  connectionId,
910
895
  targetHost: action.target.host,
@@ -977,7 +962,7 @@ export class RouteConnectionHandler {
977
962
  component: 'route-handler'
978
963
  });
979
964
  socket.destroy();
980
- this.connectionManager.cleanupConnection(record, 'missing_handler');
965
+ this.smartProxy.connectionManager.cleanupConnection(record, 'missing_handler');
981
966
  return;
982
967
  }
983
968
 
@@ -1052,7 +1037,7 @@ export class RouteConnectionHandler {
1052
1037
  if (!socket.destroyed) {
1053
1038
  socket.destroy();
1054
1039
  }
1055
- this.connectionManager.cleanupConnection(record, 'handler_error');
1040
+ this.smartProxy.connectionManager.cleanupConnection(record, 'handler_error');
1056
1041
  });
1057
1042
  } else {
1058
1043
  // For sync handlers, emit on next tick
@@ -1074,7 +1059,7 @@ export class RouteConnectionHandler {
1074
1059
  if (!socket.destroyed) {
1075
1060
  socket.destroy();
1076
1061
  }
1077
- this.connectionManager.cleanupConnection(record, 'handler_error');
1062
+ this.smartProxy.connectionManager.cleanupConnection(record, 'handler_error');
1078
1063
  }
1079
1064
  }
1080
1065
 
@@ -1095,19 +1080,19 @@ export class RouteConnectionHandler {
1095
1080
 
1096
1081
  // Determine target host and port if not provided
1097
1082
  const finalTargetHost =
1098
- targetHost || record.targetHost || this.settings.defaults?.target?.host || 'localhost';
1083
+ targetHost || record.targetHost || this.smartProxy.settings.defaults?.target?.host || 'localhost';
1099
1084
 
1100
1085
  // Determine target port
1101
1086
  const finalTargetPort =
1102
1087
  targetPort ||
1103
1088
  record.targetPort ||
1104
- (overridePort !== undefined ? overridePort : this.settings.defaults?.target?.port || 443);
1089
+ (overridePort !== undefined ? overridePort : this.smartProxy.settings.defaults?.target?.port || 443);
1105
1090
 
1106
1091
  // Update record with final target information
1107
1092
  record.targetHost = finalTargetHost;
1108
1093
  record.targetPort = finalTargetPort;
1109
1094
 
1110
- if (this.settings.enableDetailedLogging) {
1095
+ if (this.smartProxy.settings.enableDetailedLogging) {
1111
1096
  logger.log('info', `Setting up direct connection ${connectionId} to ${finalTargetHost}:${finalTargetPort}`, {
1112
1097
  connectionId,
1113
1098
  targetHost: finalTargetHost,
@@ -1123,7 +1108,7 @@ export class RouteConnectionHandler {
1123
1108
  };
1124
1109
 
1125
1110
  // Preserve source IP if configured
1126
- if (this.settings.defaults?.preserveSourceIP || this.settings.preserveSourceIP) {
1111
+ if (this.smartProxy.settings.defaults?.preserveSourceIP || this.smartProxy.settings.preserveSourceIP) {
1127
1112
  connectionOptions.localAddress = record.remoteIP.replace('::ffff:', '');
1128
1113
  }
1129
1114
 
@@ -1132,13 +1117,18 @@ export class RouteConnectionHandler {
1132
1117
  record.bytesReceived += initialChunk.length;
1133
1118
  record.pendingData.push(Buffer.from(initialChunk));
1134
1119
  record.pendingDataSize = initialChunk.length;
1120
+
1121
+ // Record bytes for metrics
1122
+ if (this.smartProxy.metricsCollector) {
1123
+ this.smartProxy.metricsCollector.recordBytes(record.id, initialChunk.length, 0);
1124
+ }
1135
1125
  }
1136
1126
 
1137
1127
  // Create the target socket with immediate error handling
1138
1128
  const targetSocket = createSocketWithErrorHandler({
1139
1129
  port: finalTargetPort,
1140
1130
  host: finalTargetHost,
1141
- timeout: this.settings.connectionTimeout || 30000, // Connection timeout (default: 30s)
1131
+ timeout: this.smartProxy.settings.connectionTimeout || 30000, // Connection timeout (default: 30s)
1142
1132
  onError: (error) => {
1143
1133
  // Connection failed - clean up everything immediately
1144
1134
  // Check if connection record is still valid (client might have disconnected)
@@ -1188,10 +1178,10 @@ export class RouteConnectionHandler {
1188
1178
  }
1189
1179
 
1190
1180
  // Clean up the connection record - this is critical!
1191
- this.connectionManager.cleanupConnection(record, `connection_failed_${(error as any).code || 'unknown'}`);
1181
+ this.smartProxy.connectionManager.cleanupConnection(record, `connection_failed_${(error as any).code || 'unknown'}`);
1192
1182
  },
1193
1183
  onConnect: async () => {
1194
- if (this.settings.enableDetailedLogging) {
1184
+ if (this.smartProxy.settings.enableDetailedLogging) {
1195
1185
  logger.log('info', `Connection ${connectionId} established to target ${finalTargetHost}:${finalTargetPort}`, {
1196
1186
  connectionId,
1197
1187
  targetHost: finalTargetHost,
@@ -1204,11 +1194,11 @@ export class RouteConnectionHandler {
1204
1194
  targetSocket.removeAllListeners('error');
1205
1195
 
1206
1196
  // Add the normal error handler for established connections
1207
- targetSocket.on('error', this.connectionManager.handleError('outgoing', record));
1197
+ targetSocket.on('error', this.smartProxy.connectionManager.handleError('outgoing', record));
1208
1198
 
1209
1199
  // Check if we should send PROXY protocol header
1210
1200
  const shouldSendProxyProtocol = record.routeConfig?.action?.sendProxyProtocol ||
1211
- this.settings.sendProxyProtocol;
1201
+ this.smartProxy.settings.sendProxyProtocol;
1212
1202
 
1213
1203
  if (shouldSendProxyProtocol) {
1214
1204
  try {
@@ -1260,7 +1250,7 @@ export class RouteConnectionHandler {
1260
1250
  if (record.pendingData.length > 0) {
1261
1251
  const combinedData = Buffer.concat(record.pendingData);
1262
1252
 
1263
- if (this.settings.enableDetailedLogging) {
1253
+ if (this.smartProxy.settings.enableDetailedLogging) {
1264
1254
  console.log(
1265
1255
  `[${connectionId}] Forwarding ${combinedData.length} bytes of initial data to target`
1266
1256
  );
@@ -1274,7 +1264,7 @@ export class RouteConnectionHandler {
1274
1264
  error: err.message,
1275
1265
  component: 'route-handler'
1276
1266
  });
1277
- return this.connectionManager.cleanupConnection(record, 'write_error');
1267
+ return this.smartProxy.connectionManager.cleanupConnection(record, 'write_error');
1278
1268
  }
1279
1269
  });
1280
1270
 
@@ -1290,22 +1280,32 @@ export class RouteConnectionHandler {
1290
1280
  setupBidirectionalForwarding(incomingSocket, targetSocket, {
1291
1281
  onClientData: (chunk) => {
1292
1282
  record.bytesReceived += chunk.length;
1293
- this.timeoutManager.updateActivity(record);
1283
+ this.smartProxy.timeoutManager.updateActivity(record);
1284
+
1285
+ // Record bytes for metrics
1286
+ if (this.smartProxy.metricsCollector) {
1287
+ this.smartProxy.metricsCollector.recordBytes(record.id, chunk.length, 0);
1288
+ }
1294
1289
  },
1295
1290
  onServerData: (chunk) => {
1296
1291
  record.bytesSent += chunk.length;
1297
- this.timeoutManager.updateActivity(record);
1292
+ this.smartProxy.timeoutManager.updateActivity(record);
1293
+
1294
+ // Record bytes for metrics
1295
+ if (this.smartProxy.metricsCollector) {
1296
+ this.smartProxy.metricsCollector.recordBytes(record.id, 0, chunk.length);
1297
+ }
1298
1298
  },
1299
1299
  onCleanup: (reason) => {
1300
- this.connectionManager.cleanupConnection(record, reason);
1300
+ this.smartProxy.connectionManager.cleanupConnection(record, reason);
1301
1301
  },
1302
1302
  enableHalfOpen: false // Default: close both when one closes (required for proxy chains)
1303
1303
  });
1304
1304
 
1305
1305
  // Apply timeouts if keep-alive is enabled
1306
1306
  if (record.hasKeepAlive) {
1307
- socket.setTimeout(this.settings.socketTimeout || 3600000);
1308
- targetSocket.setTimeout(this.settings.socketTimeout || 3600000);
1307
+ socket.setTimeout(this.smartProxy.settings.socketTimeout || 3600000);
1308
+ targetSocket.setTimeout(this.smartProxy.settings.socketTimeout || 3600000);
1309
1309
  }
1310
1310
 
1311
1311
  // Log successful connection
@@ -1333,11 +1333,11 @@ export class RouteConnectionHandler {
1333
1333
  };
1334
1334
 
1335
1335
  // Create a renegotiation handler function
1336
- const renegotiationHandler = this.tlsManager.createRenegotiationHandler(
1336
+ const renegotiationHandler = this.smartProxy.tlsManager.createRenegotiationHandler(
1337
1337
  connectionId,
1338
1338
  serverName,
1339
1339
  connInfo,
1340
- (_connectionId, reason) => this.connectionManager.cleanupConnection(record, reason)
1340
+ (_connectionId, reason) => this.smartProxy.connectionManager.cleanupConnection(record, reason)
1341
1341
  );
1342
1342
 
1343
1343
  // Store the handler in the connection record so we can remove it during cleanup
@@ -1346,7 +1346,7 @@ export class RouteConnectionHandler {
1346
1346
  // Add the handler to the socket
1347
1347
  socket.on('data', renegotiationHandler);
1348
1348
 
1349
- if (this.settings.enableDetailedLogging) {
1349
+ if (this.smartProxy.settings.enableDetailedLogging) {
1350
1350
  logger.log('info', `TLS renegotiation handler installed for connection ${connectionId} with SNI ${serverName}`, {
1351
1351
  connectionId,
1352
1352
  serverName,
@@ -1356,13 +1356,13 @@ export class RouteConnectionHandler {
1356
1356
  }
1357
1357
 
1358
1358
  // Set connection timeout
1359
- record.cleanupTimer = this.timeoutManager.setupConnectionTimeout(record, (record, reason) => {
1359
+ record.cleanupTimer = this.smartProxy.timeoutManager.setupConnectionTimeout(record, (record, reason) => {
1360
1360
  logger.log('warn', `Connection ${connectionId} from ${record.remoteIP} exceeded max lifetime, forcing cleanup`, {
1361
1361
  connectionId,
1362
1362
  remoteIP: record.remoteIP,
1363
1363
  component: 'route-handler'
1364
1364
  });
1365
- this.connectionManager.cleanupConnection(record, reason);
1365
+ this.smartProxy.connectionManager.cleanupConnection(record, reason);
1366
1366
  });
1367
1367
 
1368
1368
  // Mark TLS handshake as complete for TLS connections
@@ -1377,14 +1377,14 @@ export class RouteConnectionHandler {
1377
1377
  record.outgoingStartTime = Date.now();
1378
1378
 
1379
1379
  // Apply socket optimizations
1380
- targetSocket.setNoDelay(this.settings.noDelay);
1380
+ targetSocket.setNoDelay(this.smartProxy.settings.noDelay);
1381
1381
 
1382
1382
  // Apply keep-alive settings if enabled
1383
- if (this.settings.keepAlive) {
1384
- targetSocket.setKeepAlive(true, this.settings.keepAliveInitialDelay);
1383
+ if (this.smartProxy.settings.keepAlive) {
1384
+ targetSocket.setKeepAlive(true, this.smartProxy.settings.keepAliveInitialDelay);
1385
1385
 
1386
1386
  // Apply enhanced TCP keep-alive options if enabled
1387
- if (this.settings.enableKeepAliveProbes) {
1387
+ if (this.smartProxy.settings.enableKeepAliveProbes) {
1388
1388
  try {
1389
1389
  if ('setKeepAliveProbes' in targetSocket) {
1390
1390
  (targetSocket as any).setKeepAliveProbes(10);
@@ -1394,7 +1394,7 @@ export class RouteConnectionHandler {
1394
1394
  }
1395
1395
  } catch (err) {
1396
1396
  // Ignore errors - these are optional enhancements
1397
- if (this.settings.enableDetailedLogging) {
1397
+ if (this.smartProxy.settings.enableDetailedLogging) {
1398
1398
  logger.log('warn', `Enhanced TCP keep-alive not supported for outgoing socket on connection ${connectionId}: ${err}`, {
1399
1399
  connectionId,
1400
1400
  error: err,
@@ -1406,16 +1406,16 @@ export class RouteConnectionHandler {
1406
1406
  }
1407
1407
 
1408
1408
  // Setup error handlers for incoming socket
1409
- socket.on('error', this.connectionManager.handleError('incoming', record));
1409
+ socket.on('error', this.smartProxy.connectionManager.handleError('incoming', record));
1410
1410
 
1411
1411
  // Handle timeouts with keep-alive awareness
1412
1412
  socket.on('timeout', () => {
1413
1413
  // For keep-alive connections, just log a warning instead of closing
1414
1414
  if (record.hasKeepAlive) {
1415
- logger.log('warn', `Timeout event on incoming keep-alive connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.settings.socketTimeout || 3600000)}. Connection preserved.`, {
1415
+ logger.log('warn', `Timeout event on incoming keep-alive connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000)}. Connection preserved.`, {
1416
1416
  connectionId,
1417
1417
  remoteIP: record.remoteIP,
1418
- timeout: plugins.prettyMs(this.settings.socketTimeout || 3600000),
1418
+ timeout: plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000),
1419
1419
  status: 'Connection preserved',
1420
1420
  component: 'route-handler'
1421
1421
  });
@@ -1423,26 +1423,26 @@ export class RouteConnectionHandler {
1423
1423
  }
1424
1424
 
1425
1425
  // For non-keep-alive connections, proceed with normal cleanup
1426
- logger.log('warn', `Timeout on incoming side for connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.settings.socketTimeout || 3600000)}`, {
1426
+ logger.log('warn', `Timeout on incoming side for connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000)}`, {
1427
1427
  connectionId,
1428
1428
  remoteIP: record.remoteIP,
1429
- timeout: plugins.prettyMs(this.settings.socketTimeout || 3600000),
1429
+ timeout: plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000),
1430
1430
  component: 'route-handler'
1431
1431
  });
1432
1432
  if (record.incomingTerminationReason === null) {
1433
1433
  record.incomingTerminationReason = 'timeout';
1434
- this.connectionManager.incrementTerminationStat('incoming', 'timeout');
1434
+ this.smartProxy.connectionManager.incrementTerminationStat('incoming', 'timeout');
1435
1435
  }
1436
- this.connectionManager.cleanupConnection(record, 'timeout_incoming');
1436
+ this.smartProxy.connectionManager.cleanupConnection(record, 'timeout_incoming');
1437
1437
  });
1438
1438
 
1439
1439
  targetSocket.on('timeout', () => {
1440
1440
  // For keep-alive connections, just log a warning instead of closing
1441
1441
  if (record.hasKeepAlive) {
1442
- logger.log('warn', `Timeout event on outgoing keep-alive connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.settings.socketTimeout || 3600000)}. Connection preserved.`, {
1442
+ logger.log('warn', `Timeout event on outgoing keep-alive connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000)}. Connection preserved.`, {
1443
1443
  connectionId,
1444
1444
  remoteIP: record.remoteIP,
1445
- timeout: plugins.prettyMs(this.settings.socketTimeout || 3600000),
1445
+ timeout: plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000),
1446
1446
  status: 'Connection preserved',
1447
1447
  component: 'route-handler'
1448
1448
  });
@@ -1450,20 +1450,20 @@ export class RouteConnectionHandler {
1450
1450
  }
1451
1451
 
1452
1452
  // For non-keep-alive connections, proceed with normal cleanup
1453
- logger.log('warn', `Timeout on outgoing side for connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.settings.socketTimeout || 3600000)}`, {
1453
+ logger.log('warn', `Timeout on outgoing side for connection ${connectionId} from ${record.remoteIP} after ${plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000)}`, {
1454
1454
  connectionId,
1455
1455
  remoteIP: record.remoteIP,
1456
- timeout: plugins.prettyMs(this.settings.socketTimeout || 3600000),
1456
+ timeout: plugins.prettyMs(this.smartProxy.settings.socketTimeout || 3600000),
1457
1457
  component: 'route-handler'
1458
1458
  });
1459
1459
  if (record.outgoingTerminationReason === null) {
1460
1460
  record.outgoingTerminationReason = 'timeout';
1461
- this.connectionManager.incrementTerminationStat('outgoing', 'timeout');
1461
+ this.smartProxy.connectionManager.incrementTerminationStat('outgoing', 'timeout');
1462
1462
  }
1463
- this.connectionManager.cleanupConnection(record, 'timeout_outgoing');
1463
+ this.smartProxy.connectionManager.cleanupConnection(record, 'timeout_outgoing');
1464
1464
  });
1465
1465
 
1466
1466
  // Apply socket timeouts
1467
- this.timeoutManager.applySocketTimeouts(record);
1467
+ this.smartProxy.timeoutManager.applySocketTimeouts(record);
1468
1468
  }
1469
1469
  }