@push.rocks/smartproxy 22.4.2 → 22.6.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.
Files changed (72) hide show
  1. package/changelog.md +28 -0
  2. package/dist_rust/rustproxy +0 -0
  3. package/dist_ts/00_commitinfo_data.js +1 -1
  4. package/dist_ts/index.d.ts +1 -5
  5. package/dist_ts/index.js +3 -9
  6. package/dist_ts/protocols/common/fragment-handler.js +5 -1
  7. package/dist_ts/proxies/index.d.ts +1 -5
  8. package/dist_ts/proxies/index.js +2 -6
  9. package/dist_ts/proxies/smart-proxy/index.d.ts +5 -10
  10. package/dist_ts/proxies/smart-proxy/index.js +7 -13
  11. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -2
  12. package/dist_ts/proxies/smart-proxy/route-preprocessor.d.ts +37 -0
  13. package/dist_ts/proxies/smart-proxy/route-preprocessor.js +103 -0
  14. package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +23 -0
  15. package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +104 -0
  16. package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.d.ts +74 -0
  17. package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.js +146 -0
  18. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +49 -0
  19. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +259 -0
  20. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +39 -157
  21. package/dist_ts/proxies/smart-proxy/smart-proxy.js +224 -621
  22. package/dist_ts/proxies/smart-proxy/socket-handler-server.d.ts +45 -0
  23. package/dist_ts/proxies/smart-proxy/socket-handler-server.js +253 -0
  24. package/dist_ts/routing/index.d.ts +1 -1
  25. package/dist_ts/routing/index.js +3 -3
  26. package/dist_ts/routing/models/http-types.d.ts +119 -4
  27. package/dist_ts/routing/models/http-types.js +93 -5
  28. package/package.json +1 -1
  29. package/readme.md +470 -219
  30. package/ts/00_commitinfo_data.ts +1 -1
  31. package/ts/index.ts +4 -12
  32. package/ts/protocols/common/fragment-handler.ts +4 -0
  33. package/ts/proxies/index.ts +1 -9
  34. package/ts/proxies/smart-proxy/index.ts +6 -13
  35. package/ts/proxies/smart-proxy/models/interfaces.ts +6 -4
  36. package/ts/proxies/smart-proxy/route-preprocessor.ts +122 -0
  37. package/ts/proxies/smart-proxy/rust-binary-locator.ts +112 -0
  38. package/ts/proxies/smart-proxy/rust-metrics-adapter.ts +161 -0
  39. package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +310 -0
  40. package/ts/proxies/smart-proxy/smart-proxy.ts +282 -798
  41. package/ts/proxies/smart-proxy/socket-handler-server.ts +279 -0
  42. package/ts/routing/index.ts +2 -2
  43. package/ts/routing/models/http-types.ts +147 -4
  44. package/ts/proxies/http-proxy/connection-pool.ts +0 -228
  45. package/ts/proxies/http-proxy/context-creator.ts +0 -145
  46. package/ts/proxies/http-proxy/default-certificates.ts +0 -150
  47. package/ts/proxies/http-proxy/function-cache.ts +0 -279
  48. package/ts/proxies/http-proxy/handlers/index.ts +0 -5
  49. package/ts/proxies/http-proxy/http-proxy.ts +0 -669
  50. package/ts/proxies/http-proxy/http-request-handler.ts +0 -331
  51. package/ts/proxies/http-proxy/http2-request-handler.ts +0 -255
  52. package/ts/proxies/http-proxy/index.ts +0 -18
  53. package/ts/proxies/http-proxy/models/http-types.ts +0 -148
  54. package/ts/proxies/http-proxy/models/index.ts +0 -5
  55. package/ts/proxies/http-proxy/models/types.ts +0 -125
  56. package/ts/proxies/http-proxy/request-handler.ts +0 -878
  57. package/ts/proxies/http-proxy/security-manager.ts +0 -413
  58. package/ts/proxies/http-proxy/websocket-handler.ts +0 -581
  59. package/ts/proxies/smart-proxy/acme-state-manager.ts +0 -112
  60. package/ts/proxies/smart-proxy/cert-store.ts +0 -92
  61. package/ts/proxies/smart-proxy/certificate-manager.ts +0 -895
  62. package/ts/proxies/smart-proxy/connection-manager.ts +0 -809
  63. package/ts/proxies/smart-proxy/http-proxy-bridge.ts +0 -213
  64. package/ts/proxies/smart-proxy/metrics-collector.ts +0 -453
  65. package/ts/proxies/smart-proxy/nftables-manager.ts +0 -271
  66. package/ts/proxies/smart-proxy/port-manager.ts +0 -358
  67. package/ts/proxies/smart-proxy/route-connection-handler.ts +0 -1712
  68. package/ts/proxies/smart-proxy/route-orchestrator.ts +0 -297
  69. package/ts/proxies/smart-proxy/security-manager.ts +0 -269
  70. package/ts/proxies/smart-proxy/throughput-tracker.ts +0 -138
  71. package/ts/proxies/smart-proxy/timeout-manager.ts +0 -196
  72. package/ts/proxies/smart-proxy/tls-manager.ts +0 -171
@@ -1,196 +0,0 @@
1
- import type { IConnectionRecord } from './models/interfaces.js';
2
- import type { SmartProxy } from './smart-proxy.js';
3
-
4
- /**
5
- * Manages timeouts and inactivity tracking for connections
6
- */
7
- export class TimeoutManager {
8
- constructor(private smartProxy: SmartProxy) {}
9
-
10
- /**
11
- * Ensure timeout values don't exceed Node.js max safe integer
12
- */
13
- public ensureSafeTimeout(timeout: number): number {
14
- const MAX_SAFE_TIMEOUT = 2147483647; // Maximum safe value (2^31 - 1)
15
- return Math.min(Math.floor(timeout), MAX_SAFE_TIMEOUT);
16
- }
17
-
18
- /**
19
- * Generate a slightly randomized timeout to prevent thundering herd
20
- */
21
- public randomizeTimeout(baseTimeout: number, variationPercent: number = 5): number {
22
- const safeBaseTimeout = this.ensureSafeTimeout(baseTimeout);
23
- const variation = safeBaseTimeout * (variationPercent / 100);
24
- return this.ensureSafeTimeout(
25
- safeBaseTimeout + Math.floor(Math.random() * variation * 2) - variation
26
- );
27
- }
28
-
29
- /**
30
- * Update connection activity timestamp
31
- */
32
- public updateActivity(record: IConnectionRecord): void {
33
- record.lastActivity = Date.now();
34
-
35
- // Clear any inactivity warning
36
- if (record.inactivityWarningIssued) {
37
- record.inactivityWarningIssued = false;
38
- }
39
- }
40
-
41
- /**
42
- * Calculate effective inactivity timeout based on connection type
43
- */
44
- public getEffectiveInactivityTimeout(record: IConnectionRecord): number {
45
- let effectiveTimeout = this.smartProxy.settings.inactivityTimeout || 14400000; // 4 hours default
46
-
47
- // For immortal keep-alive connections, use an extremely long timeout
48
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
49
- return Number.MAX_SAFE_INTEGER;
50
- }
51
-
52
- // For extended keep-alive connections, apply multiplier
53
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'extended') {
54
- const multiplier = this.smartProxy.settings.keepAliveInactivityMultiplier || 6;
55
- effectiveTimeout = effectiveTimeout * multiplier;
56
- }
57
-
58
- return this.ensureSafeTimeout(effectiveTimeout);
59
- }
60
-
61
- /**
62
- * Calculate effective max lifetime based on connection type
63
- */
64
- public getEffectiveMaxLifetime(record: IConnectionRecord): number {
65
- // Use route-specific timeout if available from the routeConfig
66
- const baseTimeout = record.routeConfig?.action.advanced?.timeout ||
67
- this.smartProxy.settings.maxConnectionLifetime ||
68
- 86400000; // 24 hours default
69
-
70
- // For immortal keep-alive connections, use an extremely long lifetime
71
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
72
- return Number.MAX_SAFE_INTEGER;
73
- }
74
-
75
- // For extended keep-alive connections, use the extended lifetime setting
76
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'extended') {
77
- return this.ensureSafeTimeout(
78
- this.smartProxy.settings.extendedKeepAliveLifetime || 7 * 24 * 60 * 60 * 1000 // 7 days default
79
- );
80
- }
81
-
82
- // Apply randomization if enabled
83
- if (this.smartProxy.settings.enableRandomizedTimeouts) {
84
- return this.randomizeTimeout(baseTimeout);
85
- }
86
-
87
- return this.ensureSafeTimeout(baseTimeout);
88
- }
89
-
90
- /**
91
- * Setup connection timeout
92
- * @returns The cleanup timer
93
- */
94
- public setupConnectionTimeout(
95
- record: IConnectionRecord,
96
- onTimeout: (record: IConnectionRecord, reason: string) => void
97
- ): NodeJS.Timeout | null {
98
- // Clear any existing timer
99
- if (record.cleanupTimer) {
100
- clearTimeout(record.cleanupTimer);
101
- }
102
-
103
- // Skip timeout for immortal keep-alive connections
104
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
105
- return null;
106
- }
107
-
108
- // Calculate effective timeout
109
- const effectiveLifetime = this.getEffectiveMaxLifetime(record);
110
-
111
- // Set up the timeout
112
- const timer = setTimeout(() => {
113
- // Call the provided callback
114
- onTimeout(record, 'connection_timeout');
115
- }, effectiveLifetime);
116
-
117
- // Make sure timeout doesn't keep the process alive
118
- if (timer.unref) {
119
- timer.unref();
120
- }
121
-
122
- return timer;
123
- }
124
-
125
- /**
126
- * Check for inactivity on a connection
127
- * @returns Object with check results
128
- */
129
- public checkInactivity(record: IConnectionRecord): {
130
- isInactive: boolean;
131
- shouldWarn: boolean;
132
- inactivityTime: number;
133
- effectiveTimeout: number;
134
- } {
135
- // Skip for connections with inactivity check disabled
136
- if (this.smartProxy.settings.disableInactivityCheck) {
137
- return {
138
- isInactive: false,
139
- shouldWarn: false,
140
- inactivityTime: 0,
141
- effectiveTimeout: 0
142
- };
143
- }
144
-
145
- // Skip for immortal keep-alive connections
146
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
147
- return {
148
- isInactive: false,
149
- shouldWarn: false,
150
- inactivityTime: 0,
151
- effectiveTimeout: 0
152
- };
153
- }
154
-
155
- const now = Date.now();
156
- const inactivityTime = now - record.lastActivity;
157
- const effectiveTimeout = this.getEffectiveInactivityTimeout(record);
158
-
159
- // Check if inactive
160
- const isInactive = inactivityTime > effectiveTimeout;
161
-
162
- // For keep-alive connections, we should warn first
163
- const shouldWarn = record.hasKeepAlive &&
164
- isInactive &&
165
- !record.inactivityWarningIssued;
166
-
167
- return {
168
- isInactive,
169
- shouldWarn,
170
- inactivityTime,
171
- effectiveTimeout
172
- };
173
- }
174
-
175
- /**
176
- * Apply socket timeout settings
177
- */
178
- public applySocketTimeouts(record: IConnectionRecord): void {
179
- // Skip for immortal keep-alive connections
180
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
181
- // Disable timeouts completely for immortal connections
182
- record.incoming.setTimeout(0);
183
- if (record.outgoing) {
184
- record.outgoing.setTimeout(0);
185
- }
186
- return;
187
- }
188
-
189
- // Apply normal timeouts
190
- const timeout = this.ensureSafeTimeout(this.smartProxy.settings.socketTimeout || 3600000); // 1 hour default
191
- record.incoming.setTimeout(timeout);
192
- if (record.outgoing) {
193
- record.outgoing.setTimeout(timeout);
194
- }
195
- }
196
- }
@@ -1,171 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import { SniHandler } from '../../tls/sni/sni-handler.js';
3
- import { ProtocolDetector, TlsDetector } from '../../detection/index.js';
4
- import type { SmartProxy } from './smart-proxy.js';
5
-
6
- /**
7
- * Interface for connection information used for SNI extraction
8
- */
9
- interface IConnectionInfo {
10
- sourceIp: string;
11
- sourcePort: number;
12
- destIp: string;
13
- destPort: number;
14
- }
15
-
16
- /**
17
- * Manages TLS-related operations including SNI extraction and validation
18
- */
19
- export class TlsManager {
20
- constructor(private smartProxy: SmartProxy) {}
21
-
22
- /**
23
- * Check if a data chunk appears to be a TLS handshake
24
- */
25
- public isTlsHandshake(chunk: Buffer): boolean {
26
- return SniHandler.isTlsHandshake(chunk);
27
- }
28
-
29
- /**
30
- * Check if a data chunk appears to be a TLS ClientHello
31
- */
32
- public isClientHello(chunk: Buffer): boolean {
33
- return SniHandler.isClientHello(chunk);
34
- }
35
-
36
- /**
37
- * Extract Server Name Indication (SNI) from TLS handshake
38
- */
39
- public extractSNI(
40
- chunk: Buffer,
41
- connInfo: IConnectionInfo,
42
- previousDomain?: string
43
- ): string | undefined {
44
- // Use the SniHandler to process the TLS packet
45
- return SniHandler.processTlsPacket(
46
- chunk,
47
- connInfo,
48
- this.smartProxy.settings.enableTlsDebugLogging || false,
49
- previousDomain
50
- );
51
- }
52
-
53
- /**
54
- * Check for SNI mismatch during renegotiation
55
- */
56
- public checkRenegotiationSNI(
57
- chunk: Buffer,
58
- connInfo: IConnectionInfo,
59
- expectedDomain: string,
60
- connectionId: string
61
- ): { hasMismatch: boolean; extractedSNI?: string } {
62
- // Only process if this looks like a TLS ClientHello
63
- if (!this.isClientHello(chunk)) {
64
- return { hasMismatch: false };
65
- }
66
-
67
- try {
68
- // Extract SNI with renegotiation support
69
- const newSNI = SniHandler.extractSNIWithResumptionSupport(
70
- chunk,
71
- connInfo,
72
- this.smartProxy.settings.enableTlsDebugLogging || false
73
- );
74
-
75
- // Skip if no SNI was found
76
- if (!newSNI) return { hasMismatch: false };
77
-
78
- // Check for SNI mismatch
79
- if (newSNI !== expectedDomain) {
80
- if (this.smartProxy.settings.enableTlsDebugLogging) {
81
- console.log(
82
- `[${connectionId}] Renegotiation with different SNI: ${expectedDomain} -> ${newSNI}. ` +
83
- `Terminating connection - SNI domain switching is not allowed.`
84
- );
85
- }
86
- return { hasMismatch: true, extractedSNI: newSNI };
87
- } else if (this.smartProxy.settings.enableTlsDebugLogging) {
88
- console.log(
89
- `[${connectionId}] Renegotiation detected with same SNI: ${newSNI}. Allowing.`
90
- );
91
- }
92
- } catch (err) {
93
- console.log(
94
- `[${connectionId}] Error processing ClientHello: ${err}. Allowing connection to continue.`
95
- );
96
- }
97
-
98
- return { hasMismatch: false };
99
- }
100
-
101
- /**
102
- * Create a renegotiation handler function for a connection
103
- */
104
- public createRenegotiationHandler(
105
- connectionId: string,
106
- lockedDomain: string,
107
- connInfo: IConnectionInfo,
108
- onMismatch: (connectionId: string, reason: string) => void
109
- ): (chunk: Buffer) => void {
110
- return (chunk: Buffer) => {
111
- const result = this.checkRenegotiationSNI(chunk, connInfo, lockedDomain, connectionId);
112
- if (result.hasMismatch) {
113
- onMismatch(connectionId, 'sni_mismatch');
114
- }
115
- };
116
- }
117
-
118
- /**
119
- * Analyze TLS connection for browser fingerprinting
120
- * This helps identify browser vs non-browser connections
121
- */
122
- public analyzeClientHello(chunk: Buffer): {
123
- isBrowserConnection: boolean;
124
- isRenewal: boolean;
125
- hasSNI: boolean;
126
- } {
127
- // Default result
128
- const result = {
129
- isBrowserConnection: false,
130
- isRenewal: false,
131
- hasSNI: false
132
- };
133
-
134
- try {
135
- // Check if it's a ClientHello
136
- if (!this.isClientHello(chunk)) {
137
- return result;
138
- }
139
-
140
- // Check for session resumption
141
- const resumptionInfo = SniHandler.hasSessionResumption(
142
- chunk,
143
- this.smartProxy.settings.enableTlsDebugLogging || false
144
- );
145
-
146
- // Extract SNI
147
- const sni = SniHandler.extractSNI(
148
- chunk,
149
- this.smartProxy.settings.enableTlsDebugLogging || false
150
- );
151
-
152
- // Update result
153
- result.isRenewal = resumptionInfo.isResumption;
154
- result.hasSNI = !!sni;
155
-
156
- // Browsers typically:
157
- // 1. Send SNI extension
158
- // 2. Have a variety of extensions (ALPN, etc.)
159
- // 3. Use standard cipher suites
160
- // ...more complex heuristics could be implemented here
161
-
162
- // Simple heuristic: presence of SNI suggests browser
163
- result.isBrowserConnection = !!sni;
164
-
165
- return result;
166
- } catch (err) {
167
- console.log(`Error analyzing ClientHello: ${err}`);
168
- return result;
169
- }
170
- }
171
- }