@push.rocks/smartproxy 15.0.2 → 16.0.3

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 (160) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/certificate/index.d.ts +10 -4
  3. package/dist_ts/certificate/index.js +5 -7
  4. package/dist_ts/certificate/models/certificate-types.d.ts +35 -15
  5. package/dist_ts/certificate/providers/cert-provisioner.d.ts +41 -15
  6. package/dist_ts/certificate/providers/cert-provisioner.js +201 -41
  7. package/dist_ts/core/models/index.d.ts +2 -0
  8. package/dist_ts/core/models/index.js +3 -1
  9. package/dist_ts/core/models/route-context.d.ts +62 -0
  10. package/dist_ts/core/models/route-context.js +43 -0
  11. package/dist_ts/core/models/socket-augmentation.d.ts +12 -0
  12. package/dist_ts/core/models/socket-augmentation.js +18 -0
  13. package/dist_ts/core/utils/event-system.d.ts +200 -0
  14. package/dist_ts/core/utils/event-system.js +224 -0
  15. package/dist_ts/core/utils/index.d.ts +7 -0
  16. package/dist_ts/core/utils/index.js +8 -1
  17. package/dist_ts/core/utils/route-manager.d.ts +118 -0
  18. package/dist_ts/core/utils/route-manager.js +383 -0
  19. package/dist_ts/core/utils/route-utils.d.ts +94 -0
  20. package/dist_ts/core/utils/route-utils.js +264 -0
  21. package/dist_ts/core/utils/security-utils.d.ts +111 -0
  22. package/dist_ts/core/utils/security-utils.js +212 -0
  23. package/dist_ts/core/utils/shared-security-manager.d.ts +110 -0
  24. package/dist_ts/core/utils/shared-security-manager.js +252 -0
  25. package/dist_ts/core/utils/template-utils.d.ts +37 -0
  26. package/dist_ts/core/utils/template-utils.js +104 -0
  27. package/dist_ts/core/utils/websocket-utils.d.ts +23 -0
  28. package/dist_ts/core/utils/websocket-utils.js +86 -0
  29. package/dist_ts/forwarding/config/forwarding-types.d.ts +40 -76
  30. package/dist_ts/forwarding/config/forwarding-types.js +19 -18
  31. package/dist_ts/forwarding/config/index.d.ts +4 -2
  32. package/dist_ts/forwarding/config/index.js +5 -3
  33. package/dist_ts/forwarding/handlers/base-handler.js +3 -1
  34. package/dist_ts/forwarding/index.d.ts +5 -6
  35. package/dist_ts/forwarding/index.js +3 -3
  36. package/dist_ts/http/models/http-types.js +1 -1
  37. package/dist_ts/http/port80/acme-interfaces.d.ts +30 -0
  38. package/dist_ts/http/port80/acme-interfaces.js +46 -1
  39. package/dist_ts/http/port80/port80-handler.d.ts +17 -2
  40. package/dist_ts/http/port80/port80-handler.js +49 -11
  41. package/dist_ts/http/router/index.d.ts +5 -1
  42. package/dist_ts/http/router/index.js +4 -2
  43. package/dist_ts/http/router/route-router.d.ts +108 -0
  44. package/dist_ts/http/router/route-router.js +393 -0
  45. package/dist_ts/index.d.ts +8 -2
  46. package/dist_ts/index.js +10 -3
  47. package/dist_ts/proxies/index.d.ts +7 -2
  48. package/dist_ts/proxies/index.js +10 -4
  49. package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +21 -0
  50. package/dist_ts/proxies/network-proxy/certificate-manager.js +92 -1
  51. package/dist_ts/proxies/network-proxy/context-creator.d.ts +34 -0
  52. package/dist_ts/proxies/network-proxy/context-creator.js +108 -0
  53. package/dist_ts/proxies/network-proxy/function-cache.d.ts +90 -0
  54. package/dist_ts/proxies/network-proxy/function-cache.js +198 -0
  55. package/dist_ts/proxies/network-proxy/http-request-handler.d.ts +40 -0
  56. package/dist_ts/proxies/network-proxy/http-request-handler.js +256 -0
  57. package/dist_ts/proxies/network-proxy/http2-request-handler.d.ts +24 -0
  58. package/dist_ts/proxies/network-proxy/http2-request-handler.js +201 -0
  59. package/dist_ts/proxies/network-proxy/models/types.d.ts +73 -1
  60. package/dist_ts/proxies/network-proxy/models/types.js +242 -1
  61. package/dist_ts/proxies/network-proxy/network-proxy.d.ts +23 -20
  62. package/dist_ts/proxies/network-proxy/network-proxy.js +147 -60
  63. package/dist_ts/proxies/network-proxy/request-handler.d.ts +38 -5
  64. package/dist_ts/proxies/network-proxy/request-handler.js +584 -198
  65. package/dist_ts/proxies/network-proxy/security-manager.d.ts +65 -0
  66. package/dist_ts/proxies/network-proxy/security-manager.js +255 -0
  67. package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +13 -2
  68. package/dist_ts/proxies/network-proxy/websocket-handler.js +238 -20
  69. package/dist_ts/proxies/smart-proxy/index.d.ts +1 -1
  70. package/dist_ts/proxies/smart-proxy/index.js +3 -3
  71. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -66
  72. package/dist_ts/proxies/smart-proxy/models/interfaces.js +5 -4
  73. package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +173 -6
  74. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +20 -7
  75. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +49 -108
  76. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +81 -0
  77. package/dist_ts/proxies/smart-proxy/port-manager.js +166 -0
  78. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +7 -5
  79. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +155 -160
  80. package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +9 -0
  81. package/dist_ts/proxies/smart-proxy/route-helpers/index.js +11 -0
  82. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +5 -125
  83. package/dist_ts/proxies/smart-proxy/route-helpers.js +8 -195
  84. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +14 -11
  85. package/dist_ts/proxies/smart-proxy/route-manager.js +81 -124
  86. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +101 -12
  87. package/dist_ts/proxies/smart-proxy/smart-proxy.js +178 -306
  88. package/dist_ts/proxies/smart-proxy/timeout-manager.js +3 -3
  89. package/dist_ts/proxies/smart-proxy/utils/index.d.ts +12 -0
  90. package/dist_ts/proxies/smart-proxy/utils/index.js +19 -0
  91. package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +240 -0
  92. package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +451 -0
  93. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.d.ts +51 -0
  94. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.js +124 -0
  95. package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +131 -0
  96. package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +217 -0
  97. package/dist_ts/proxies/smart-proxy/utils/route-utils.d.ts +79 -0
  98. package/dist_ts/proxies/smart-proxy/utils/route-utils.js +266 -0
  99. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +73 -0
  100. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +264 -0
  101. package/package.json +1 -1
  102. package/readme.md +241 -125
  103. package/readme.plan.md +73 -286
  104. package/ts/00_commitinfo_data.ts +1 -1
  105. package/ts/certificate/index.ts +17 -9
  106. package/ts/certificate/models/certificate-types.ts +37 -16
  107. package/ts/certificate/providers/cert-provisioner.ts +247 -54
  108. package/ts/core/models/index.ts +2 -0
  109. package/ts/core/models/route-context.ts +113 -0
  110. package/ts/core/models/socket-augmentation.ts +33 -0
  111. package/ts/core/utils/event-system.ts +376 -0
  112. package/ts/core/utils/index.ts +7 -0
  113. package/ts/core/utils/route-manager.ts +489 -0
  114. package/ts/core/utils/route-utils.ts +312 -0
  115. package/ts/core/utils/security-utils.ts +309 -0
  116. package/ts/core/utils/shared-security-manager.ts +333 -0
  117. package/ts/core/utils/template-utils.ts +124 -0
  118. package/ts/core/utils/websocket-utils.ts +81 -0
  119. package/ts/forwarding/config/forwarding-types.ts +79 -107
  120. package/ts/forwarding/config/index.ts +4 -2
  121. package/ts/forwarding/handlers/base-handler.ts +4 -2
  122. package/ts/forwarding/index.ts +3 -2
  123. package/ts/http/models/http-types.ts +0 -1
  124. package/ts/http/port80/acme-interfaces.ts +84 -0
  125. package/ts/http/port80/port80-handler.ts +61 -15
  126. package/ts/http/router/index.ts +8 -1
  127. package/ts/http/router/route-router.ts +482 -0
  128. package/ts/index.ts +14 -2
  129. package/ts/proxies/index.ts +12 -3
  130. package/ts/proxies/network-proxy/certificate-manager.ts +114 -10
  131. package/ts/proxies/network-proxy/context-creator.ts +145 -0
  132. package/ts/proxies/network-proxy/function-cache.ts +259 -0
  133. package/ts/proxies/network-proxy/http-request-handler.ts +330 -0
  134. package/ts/proxies/network-proxy/http2-request-handler.ts +255 -0
  135. package/ts/proxies/network-proxy/models/types.ts +312 -1
  136. package/ts/proxies/network-proxy/network-proxy.ts +195 -86
  137. package/ts/proxies/network-proxy/request-handler.ts +698 -246
  138. package/ts/proxies/network-proxy/security-manager.ts +298 -0
  139. package/ts/proxies/network-proxy/websocket-handler.ts +276 -33
  140. package/ts/proxies/smart-proxy/index.ts +2 -12
  141. package/ts/proxies/smart-proxy/models/interfaces.ts +13 -67
  142. package/ts/proxies/smart-proxy/models/route-types.ts +223 -25
  143. package/ts/proxies/smart-proxy/network-proxy-bridge.ts +57 -123
  144. package/ts/proxies/smart-proxy/port-manager.ts +195 -0
  145. package/ts/proxies/smart-proxy/route-connection-handler.ts +191 -225
  146. package/ts/proxies/smart-proxy/route-manager.ts +101 -144
  147. package/ts/proxies/smart-proxy/smart-proxy.ts +206 -377
  148. package/ts/proxies/smart-proxy/timeout-manager.ts +2 -2
  149. package/ts/proxies/smart-proxy/utils/index.ts +40 -0
  150. package/ts/proxies/smart-proxy/utils/route-helpers.ts +621 -0
  151. package/ts/proxies/smart-proxy/utils/route-migration-utils.ts +165 -0
  152. package/ts/proxies/smart-proxy/utils/route-patterns.ts +309 -0
  153. package/ts/proxies/smart-proxy/utils/route-utils.ts +330 -0
  154. package/ts/proxies/smart-proxy/utils/route-validators.ts +288 -0
  155. package/ts/forwarding/config/domain-config.ts +0 -28
  156. package/ts/forwarding/config/domain-manager.ts +0 -283
  157. package/ts/proxies/smart-proxy/connection-handler.ts +0 -1240
  158. package/ts/proxies/smart-proxy/domain-config-manager.ts +0 -441
  159. package/ts/proxies/smart-proxy/port-range-manager.ts +0 -211
  160. package/ts/proxies/smart-proxy/route-helpers.ts +0 -344
@@ -1,26 +1,23 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import type {
3
3
  IConnectionRecord,
4
- IDomainConfig,
5
4
  ISmartProxyOptions
6
5
  } from './models/interfaces.js';
7
6
  import {
8
- isRoutedOptions,
9
- isLegacyOptions
7
+ isRoutedOptions
10
8
  } from './models/interfaces.js';
11
9
  import type {
12
10
  IRouteConfig,
13
- IRouteAction
11
+ IRouteAction,
12
+ IRouteContext
14
13
  } from './models/route-types.js';
15
14
  import { ConnectionManager } from './connection-manager.js';
16
15
  import { SecurityManager } from './security-manager.js';
17
- import { DomainConfigManager } from './domain-config-manager.js';
18
16
  import { TlsManager } from './tls-manager.js';
19
17
  import { NetworkProxyBridge } from './network-proxy-bridge.js';
20
18
  import { TimeoutManager } from './timeout-manager.js';
21
19
  import { RouteManager } from './route-manager.js';
22
20
  import type { ForwardingHandler } from '../../forwarding/handlers/base-handler.js';
23
- import type { TForwardingType } from '../../forwarding/config/forwarding-types.js';
24
21
 
25
22
  /**
26
23
  * Handles new connection processing and setup logic with support for route-based configuration
@@ -28,11 +25,13 @@ import type { TForwardingType } from '../../forwarding/config/forwarding-types.j
28
25
  export class RouteConnectionHandler {
29
26
  private settings: ISmartProxyOptions;
30
27
 
28
+ // Cache for route contexts to avoid recreation
29
+ private routeContextCache: Map<string, IRouteContext> = new Map();
30
+
31
31
  constructor(
32
32
  settings: ISmartProxyOptions,
33
33
  private connectionManager: ConnectionManager,
34
34
  private securityManager: SecurityManager,
35
- private domainConfigManager: DomainConfigManager,
36
35
  private tlsManager: TlsManager,
37
36
  private networkProxyBridge: NetworkProxyBridge,
38
37
  private timeoutManager: TimeoutManager,
@@ -41,6 +40,47 @@ export class RouteConnectionHandler {
41
40
  this.settings = settings;
42
41
  }
43
42
 
43
+ /**
44
+ * Create a route context object for port and host mapping functions
45
+ */
46
+ private createRouteContext(options: {
47
+ connectionId: string;
48
+ port: number;
49
+ domain?: string;
50
+ clientIp: string;
51
+ serverIp: string;
52
+ isTls: boolean;
53
+ tlsVersion?: string;
54
+ routeName?: string;
55
+ routeId?: string;
56
+ path?: string;
57
+ query?: string;
58
+ headers?: Record<string, string>;
59
+ }): IRouteContext {
60
+ return {
61
+ // Connection information
62
+ port: options.port,
63
+ domain: options.domain,
64
+ clientIp: options.clientIp,
65
+ serverIp: options.serverIp,
66
+ path: options.path,
67
+ query: options.query,
68
+ headers: options.headers,
69
+
70
+ // TLS information
71
+ isTls: options.isTls,
72
+ tlsVersion: options.tlsVersion,
73
+
74
+ // Route information
75
+ routeName: options.routeName,
76
+ routeId: options.routeId,
77
+
78
+ // Additional properties
79
+ timestamp: Date.now(),
80
+ connectionId: options.connectionId
81
+ };
82
+ }
83
+
44
84
  /**
45
85
  * Handle a new incoming connection
46
86
  */
@@ -244,37 +284,20 @@ export class RouteConnectionHandler {
244
284
 
245
285
  if (!routeMatch) {
246
286
  console.log(`[${connectionId}] No route found for ${serverName || 'connection'} on port ${localPort}`);
247
-
248
- // Fall back to legacy matching if we're using a hybrid configuration
249
- const domainConfig = serverName
250
- ? this.domainConfigManager.findDomainConfig(serverName)
251
- : this.domainConfigManager.findDomainConfigForPort(localPort);
252
287
 
253
- if (domainConfig) {
254
- if (this.settings.enableDetailedLogging) {
255
- console.log(`[${connectionId}] Using legacy domain configuration for ${serverName || 'port ' + localPort}`);
256
- }
257
-
258
- // Associate this domain config with the connection
259
- record.domainConfig = domainConfig;
260
-
261
- // Handle the connection using the legacy setup
262
- return this.handleLegacyConnection(socket, record, serverName, domainConfig, initialChunk);
263
- }
264
-
265
- // No matching route or domain config, use default/fallback handling
288
+ // No matching route, use default/fallback handling
266
289
  console.log(`[${connectionId}] Using default route handling for connection`);
267
-
290
+
268
291
  // Check default security settings
269
292
  const defaultSecuritySettings = this.settings.defaults?.security;
270
293
  if (defaultSecuritySettings) {
271
- if (defaultSecuritySettings.allowedIPs && defaultSecuritySettings.allowedIPs.length > 0) {
294
+ if (defaultSecuritySettings.allowedIps && defaultSecuritySettings.allowedIps.length > 0) {
272
295
  const isAllowed = this.securityManager.isIPAuthorized(
273
296
  remoteIP,
274
- defaultSecuritySettings.allowedIPs,
275
- defaultSecuritySettings.blockedIPs || []
297
+ defaultSecuritySettings.allowedIps,
298
+ defaultSecuritySettings.blockedIps || []
276
299
  );
277
-
300
+
278
301
  if (!isAllowed) {
279
302
  console.log(`[${connectionId}] IP ${remoteIP} not in default allowed list`);
280
303
  socket.end();
@@ -282,34 +305,24 @@ export class RouteConnectionHandler {
282
305
  return;
283
306
  }
284
307
  }
285
- } else if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
286
- // Legacy default IP restrictions
287
- const isAllowed = this.securityManager.isIPAuthorized(
288
- remoteIP,
289
- this.settings.defaultAllowedIPs,
290
- this.settings.defaultBlockedIPs || []
291
- );
292
-
293
- if (!isAllowed) {
294
- console.log(`[${connectionId}] IP ${remoteIP} not in default allowed list`);
295
- socket.end();
296
- this.connectionManager.cleanupConnection(record, 'ip_blocked');
297
- return;
298
- }
299
308
  }
300
309
 
301
310
  // Setup direct connection with default settings
302
- let targetHost: string;
303
- let targetPort: number;
311
+ if (this.settings.defaults?.target) {
312
+ // Use defaults from configuration
313
+ const targetHost = this.settings.defaults.target.host;
314
+ const targetPort = this.settings.defaults.target.port;
304
315
 
305
- if (isRoutedOptions(this.settings) && this.settings.defaults?.target) {
306
- // Use defaults from routed configuration
307
- targetHost = this.settings.defaults.target.host;
308
- targetPort = this.settings.defaults.target.port;
309
- } else if (this.settings.targetIP && this.settings.toPort) {
310
- // Fall back to legacy settings
311
- targetHost = this.settings.targetIP;
312
- targetPort = this.settings.toPort;
316
+ return this.setupDirectConnection(
317
+ socket,
318
+ record,
319
+ undefined,
320
+ serverName,
321
+ initialChunk,
322
+ undefined,
323
+ targetHost,
324
+ targetPort
325
+ );
313
326
  } else {
314
327
  // No default target available, terminate the connection
315
328
  console.log(`[${connectionId}] No default target configured. Closing connection.`);
@@ -317,17 +330,6 @@ export class RouteConnectionHandler {
317
330
  this.connectionManager.cleanupConnection(record, 'no_default_target');
318
331
  return;
319
332
  }
320
-
321
- return this.setupDirectConnection(
322
- socket,
323
- record,
324
- undefined,
325
- serverName,
326
- initialChunk,
327
- undefined,
328
- targetHost,
329
- targetPort
330
- );
331
333
  }
332
334
 
333
335
  // A matching route was found
@@ -368,7 +370,7 @@ export class RouteConnectionHandler {
368
370
  ): void {
369
371
  const connectionId = record.id;
370
372
  const action = route.action;
371
-
373
+
372
374
  // We should have a target configuration for forwarding
373
375
  if (!action.target) {
374
376
  console.log(`[${connectionId}] Forward action missing target configuration`);
@@ -376,24 +378,82 @@ export class RouteConnectionHandler {
376
378
  this.connectionManager.cleanupConnection(record, 'missing_target');
377
379
  return;
378
380
  }
379
-
381
+
382
+ // Create the routing context for this connection
383
+ const routeContext = this.createRouteContext({
384
+ connectionId: record.id,
385
+ port: record.localPort,
386
+ domain: record.lockedDomain,
387
+ clientIp: record.remoteIP,
388
+ serverIp: socket.localAddress || '',
389
+ isTls: record.isTLS || false,
390
+ tlsVersion: record.tlsVersion,
391
+ routeName: route.name,
392
+ routeId: route.id
393
+ });
394
+
395
+ // Cache the context for potential reuse
396
+ this.routeContextCache.set(connectionId, routeContext);
397
+
398
+ // Determine host using function or static value
399
+ let targetHost: string | string[];
400
+ if (typeof action.target.host === 'function') {
401
+ try {
402
+ targetHost = action.target.host(routeContext);
403
+ if (this.settings.enableDetailedLogging) {
404
+ console.log(`[${connectionId}] Dynamic host resolved to: ${Array.isArray(targetHost) ? targetHost.join(', ') : targetHost}`);
405
+ }
406
+ } catch (err) {
407
+ console.log(`[${connectionId}] Error in host mapping function: ${err}`);
408
+ socket.end();
409
+ this.connectionManager.cleanupConnection(record, 'host_mapping_error');
410
+ return;
411
+ }
412
+ } else {
413
+ targetHost = action.target.host;
414
+ }
415
+
416
+ // If an array of hosts, select one randomly for load balancing
417
+ const selectedHost = Array.isArray(targetHost)
418
+ ? targetHost[Math.floor(Math.random() * targetHost.length)]
419
+ : targetHost;
420
+
421
+ // Determine port using function or static value
422
+ let targetPort: number;
423
+ if (typeof action.target.port === 'function') {
424
+ try {
425
+ targetPort = action.target.port(routeContext);
426
+ if (this.settings.enableDetailedLogging) {
427
+ console.log(`[${connectionId}] Dynamic port mapping: ${record.localPort} -> ${targetPort}`);
428
+ }
429
+ // Store the resolved target port in the context for potential future use
430
+ routeContext.targetPort = targetPort;
431
+ } catch (err) {
432
+ console.log(`[${connectionId}] Error in port mapping function: ${err}`);
433
+ socket.end();
434
+ this.connectionManager.cleanupConnection(record, 'port_mapping_error');
435
+ return;
436
+ }
437
+ } else if (action.target.preservePort) {
438
+ // Use incoming port if preservePort is true
439
+ targetPort = record.localPort;
440
+ } else {
441
+ // Use static port from configuration
442
+ targetPort = action.target.port;
443
+ }
444
+
445
+ // Store the resolved host in the context
446
+ routeContext.targetHost = selectedHost;
447
+
380
448
  // Determine if this needs TLS handling
381
449
  if (action.tls) {
382
450
  switch (action.tls.mode) {
383
451
  case 'passthrough':
384
452
  // For TLS passthrough, just forward directly
385
453
  if (this.settings.enableDetailedLogging) {
386
- console.log(`[${connectionId}] Using TLS passthrough to ${action.target.host}`);
454
+ console.log(`[${connectionId}] Using TLS passthrough to ${selectedHost}:${targetPort}`);
387
455
  }
388
456
 
389
- // Allow for array of hosts
390
- const targetHost = Array.isArray(action.target.host)
391
- ? action.target.host[Math.floor(Math.random() * action.target.host.length)]
392
- : action.target.host;
393
-
394
- // Determine target port - either target port or preserve incoming port
395
- const targetPort = action.target.preservePort ? record.localPort : action.target.port;
396
-
397
457
  return this.setupDirectConnection(
398
458
  socket,
399
459
  record,
@@ -401,7 +461,7 @@ export class RouteConnectionHandler {
401
461
  record.lockedDomain,
402
462
  initialChunk,
403
463
  undefined,
404
- targetHost,
464
+ selectedHost,
405
465
  targetPort
406
466
  );
407
467
 
@@ -445,14 +505,36 @@ export class RouteConnectionHandler {
445
505
  console.log(`[${connectionId}] Using basic forwarding to ${action.target.host}:${action.target.port}`);
446
506
  }
447
507
 
448
- // Allow for array of hosts
449
- const targetHost = Array.isArray(action.target.host)
450
- ? action.target.host[Math.floor(Math.random() * action.target.host.length)]
451
- : action.target.host;
452
-
453
- // Determine target port - either target port or preserve incoming port
454
- const targetPort = action.target.preservePort ? record.localPort : action.target.port;
455
-
508
+ // Get the appropriate host value
509
+ let targetHost: string;
510
+
511
+ if (typeof action.target.host === 'function') {
512
+ // For function-based host, use the same routeContext created earlier
513
+ const hostResult = action.target.host(routeContext);
514
+ targetHost = Array.isArray(hostResult)
515
+ ? hostResult[Math.floor(Math.random() * hostResult.length)]
516
+ : hostResult;
517
+ } else {
518
+ // For static host value
519
+ targetHost = Array.isArray(action.target.host)
520
+ ? action.target.host[Math.floor(Math.random() * action.target.host.length)]
521
+ : action.target.host;
522
+ }
523
+
524
+ // Determine port - either function-based, static, or preserve incoming port
525
+ let targetPort: number;
526
+ if (typeof action.target.port === 'function') {
527
+ targetPort = action.target.port(routeContext);
528
+ } else if (action.target.preservePort) {
529
+ targetPort = record.localPort;
530
+ } else {
531
+ targetPort = action.target.port;
532
+ }
533
+
534
+ // Update the connection record and context with resolved values
535
+ record.targetHost = targetHost;
536
+ record.targetPort = targetPort;
537
+
456
538
  return this.setupDirectConnection(
457
539
  socket,
458
540
  record,
@@ -575,114 +657,8 @@ export class RouteConnectionHandler {
575
657
  }
576
658
 
577
659
  /**
578
- * Handle a connection using legacy domain configuration
660
+ * Legacy connection handling has been removed in favor of pure route-based approach
579
661
  */
580
- private handleLegacyConnection(
581
- socket: plugins.net.Socket,
582
- record: IConnectionRecord,
583
- serverName: string,
584
- domainConfig: IDomainConfig,
585
- initialChunk?: Buffer
586
- ): void {
587
- const connectionId = record.id;
588
-
589
- // Get the forwarding type for this domain
590
- const forwardingType = this.domainConfigManager.getForwardingType(domainConfig);
591
-
592
- // IP validation
593
- const ipRules = this.domainConfigManager.getEffectiveIPRules(domainConfig);
594
-
595
- if (!this.securityManager.isIPAuthorized(record.remoteIP, ipRules.allowedIPs, ipRules.blockedIPs)) {
596
- console.log(
597
- `[${connectionId}] Connection rejected: IP ${record.remoteIP} not allowed for domain ${domainConfig.domains.join(', ')}`
598
- );
599
- socket.end();
600
- this.connectionManager.initiateCleanupOnce(record, 'ip_blocked');
601
- return;
602
- }
603
-
604
- // Handle based on forwarding type
605
- switch (forwardingType) {
606
- case 'http-only':
607
- // For HTTP-only configs with TLS traffic
608
- if (record.isTLS) {
609
- console.log(`[${connectionId}] Received TLS connection for HTTP-only domain ${serverName}`);
610
- socket.end();
611
- this.connectionManager.initiateCleanupOnce(record, 'wrong_protocol');
612
- return;
613
- }
614
- break;
615
-
616
- case 'https-passthrough':
617
- // For TLS passthrough with TLS traffic
618
- if (record.isTLS) {
619
- try {
620
- const handler = this.domainConfigManager.getForwardingHandler(domainConfig);
621
-
622
- if (this.settings.enableDetailedLogging) {
623
- console.log(`[${connectionId}] Using forwarding handler for SNI passthrough to ${serverName}`);
624
- }
625
-
626
- // Handle the connection using the handler
627
- return handler.handleConnection(socket);
628
- } catch (err) {
629
- console.log(`[${connectionId}] Error using forwarding handler: ${err}`);
630
- }
631
- }
632
- break;
633
-
634
- case 'https-terminate-to-http':
635
- case 'https-terminate-to-https':
636
- // For TLS termination with TLS traffic
637
- if (record.isTLS) {
638
- const networkProxyPort = this.domainConfigManager.getNetworkProxyPort(domainConfig);
639
-
640
- if (this.settings.enableDetailedLogging) {
641
- console.log(`[${connectionId}] Using TLS termination (${forwardingType}) for ${serverName} on port ${networkProxyPort}`);
642
- }
643
-
644
- // Forward to NetworkProxy with domain-specific port
645
- return this.networkProxyBridge.forwardToNetworkProxy(
646
- connectionId,
647
- socket,
648
- record,
649
- initialChunk!,
650
- networkProxyPort,
651
- (reason) => this.connectionManager.initiateCleanupOnce(record, reason)
652
- );
653
- }
654
- break;
655
- }
656
-
657
- // If we're still here, use the forwarding handler if available
658
- try {
659
- const handler = this.domainConfigManager.getForwardingHandler(domainConfig);
660
-
661
- if (this.settings.enableDetailedLogging) {
662
- console.log(`[${connectionId}] Using general forwarding handler for domain ${serverName || 'unknown'}`);
663
- }
664
-
665
- // Handle the connection using the handler
666
- return handler.handleConnection(socket);
667
- } catch (err) {
668
- console.log(`[${connectionId}] Error using forwarding handler: ${err}`);
669
- }
670
-
671
- // Fallback: set up direct connection
672
- const targetIp = this.domainConfigManager.getTargetIP(domainConfig);
673
- const targetPort = this.domainConfigManager.getTargetPort(domainConfig, this.settings.toPort);
674
-
675
- return this.setupDirectConnection(
676
- socket,
677
- record,
678
- domainConfig,
679
- serverName,
680
- initialChunk,
681
- undefined,
682
- targetIp,
683
- targetPort
684
- );
685
- }
686
662
 
687
663
  /**
688
664
  * Sets up a direct connection to the target
@@ -690,7 +666,7 @@ export class RouteConnectionHandler {
690
666
  private setupDirectConnection(
691
667
  socket: plugins.net.Socket,
692
668
  record: IConnectionRecord,
693
- domainConfig?: IDomainConfig,
669
+ _unused?: any, // kept for backward compatibility
694
670
  serverName?: string,
695
671
  initialChunk?: Buffer,
696
672
  overridePort?: number,
@@ -698,22 +674,25 @@ export class RouteConnectionHandler {
698
674
  targetPort?: number
699
675
  ): void {
700
676
  const connectionId = record.id;
701
-
677
+
702
678
  // Determine target host and port if not provided
703
- const finalTargetHost = targetHost || (domainConfig
704
- ? this.domainConfigManager.getTargetIP(domainConfig)
705
- : this.settings.defaults?.target?.host
706
- ? this.settings.defaults.target.host
707
- : this.settings.targetIP!);
679
+ const finalTargetHost = targetHost ||
680
+ record.targetHost ||
681
+ (this.settings.defaults?.target?.host || 'localhost');
708
682
 
709
- // Determine target port - first try explicit port, then forwarding config, then fallback
710
- const finalTargetPort = targetPort || (overridePort !== undefined
711
- ? overridePort
712
- : domainConfig
713
- ? this.domainConfigManager.getTargetPort(domainConfig, this.settings.toPort)
714
- : this.settings.defaults?.target?.port
715
- ? this.settings.defaults.target.port
716
- : this.settings.toPort);
683
+ // Determine target port
684
+ const finalTargetPort = targetPort ||
685
+ record.targetPort ||
686
+ (overridePort !== undefined ? overridePort :
687
+ (this.settings.defaults?.target?.port || 443));
688
+
689
+ // Update record with final target information
690
+ record.targetHost = finalTargetHost;
691
+ record.targetPort = finalTargetPort;
692
+
693
+ if (this.settings.enableDetailedLogging) {
694
+ console.log(`[${connectionId}] Setting up direct connection to ${finalTargetHost}:${finalTargetPort}`);
695
+ }
717
696
 
718
697
  // Setup connection options
719
698
  const connectionOptions: plugins.net.NetConnectOpts = {
@@ -897,20 +876,7 @@ export class RouteConnectionHandler {
897
876
  this.connectionManager.incrementTerminationStat('outgoing', 'connection_failed');
898
877
  }
899
878
 
900
- // If we have a forwarding handler for this domain, let it handle the error
901
- if (domainConfig) {
902
- try {
903
- const forwardingHandler = this.domainConfigManager.getForwardingHandler(domainConfig);
904
- forwardingHandler.emit('connection_error', {
905
- socket,
906
- error: err,
907
- connectionId
908
- });
909
- } catch (handlerErr) {
910
- // If getting the handler fails, just log and continue with normal cleanup
911
- console.log(`Error getting forwarding handler for error handling: ${handlerErr}`);
912
- }
913
- }
879
+ // Route-based configuration doesn't use domain handlers
914
880
 
915
881
  // Clean up the connection
916
882
  this.connectionManager.initiateCleanupOnce(record, `connection_failed_${code}`);
@@ -1043,8 +1009,8 @@ export class RouteConnectionHandler {
1043
1009
  `${
1044
1010
  serverName
1045
1011
  ? ` (SNI: ${serverName})`
1046
- : domainConfig
1047
- ? ` (Port-based for domain: ${domainConfig.domains.join(', ')})`
1012
+ : record.lockedDomain
1013
+ ? ` (Domain: ${record.lockedDomain})`
1048
1014
  : ''
1049
1015
  }` +
1050
1016
  ` TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${
@@ -1057,8 +1023,8 @@ export class RouteConnectionHandler {
1057
1023
  `${
1058
1024
  serverName
1059
1025
  ? ` (SNI: ${serverName})`
1060
- : domainConfig
1061
- ? ` (Port-based for domain: ${domainConfig.domains.join(', ')})`
1026
+ : record.lockedDomain
1027
+ ? ` (Domain: ${record.lockedDomain})`
1062
1028
  : ''
1063
1029
  }`
1064
1030
  );