@push.rocks/smartproxy 20.0.1 → 21.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +26 -0
- package/dist_ts/core/utils/proxy-protocol.d.ts +5 -17
- package/dist_ts/core/utils/proxy-protocol.js +13 -97
- package/dist_ts/core/utils/websocket-utils.d.ts +6 -7
- package/dist_ts/core/utils/websocket-utils.js +10 -66
- package/dist_ts/detection/detectors/http-detector-v2.d.ts +33 -0
- package/dist_ts/detection/detectors/http-detector-v2.js +87 -0
- package/dist_ts/detection/detectors/http-detector.d.ts +33 -0
- package/dist_ts/detection/detectors/http-detector.js +89 -0
- package/dist_ts/detection/detectors/quick-detector.d.ts +28 -0
- package/dist_ts/detection/detectors/quick-detector.js +131 -0
- package/dist_ts/detection/detectors/routing-extractor.d.ts +28 -0
- package/dist_ts/detection/detectors/routing-extractor.js +122 -0
- package/dist_ts/detection/detectors/tls-detector-v2.d.ts +33 -0
- package/dist_ts/detection/detectors/tls-detector-v2.js +80 -0
- package/dist_ts/detection/detectors/tls-detector.d.ts +33 -0
- package/dist_ts/detection/detectors/tls-detector.js +106 -0
- package/dist_ts/detection/index.d.ts +17 -0
- package/dist_ts/detection/index.js +22 -0
- package/dist_ts/detection/models/detection-types.d.ts +87 -0
- package/dist_ts/detection/models/detection-types.js +5 -0
- package/dist_ts/detection/models/interfaces.d.ts +97 -0
- package/dist_ts/detection/models/interfaces.js +5 -0
- package/dist_ts/detection/protocol-detector-v2.d.ts +46 -0
- package/dist_ts/detection/protocol-detector-v2.js +116 -0
- package/dist_ts/detection/protocol-detector.d.ts +74 -0
- package/dist_ts/detection/protocol-detector.js +173 -0
- package/dist_ts/detection/utils/buffer-utils.d.ts +61 -0
- package/dist_ts/detection/utils/buffer-utils.js +127 -0
- package/dist_ts/detection/utils/fragment-manager.d.ts +31 -0
- package/dist_ts/detection/utils/fragment-manager.js +53 -0
- package/dist_ts/detection/utils/parser-utils.d.ts +42 -0
- package/dist_ts/detection/utils/parser-utils.js +63 -0
- package/dist_ts/index.d.ts +2 -1
- package/dist_ts/index.js +3 -2
- package/dist_ts/protocols/common/fragment-handler.d.ts +73 -0
- package/dist_ts/protocols/common/fragment-handler.js +117 -0
- package/dist_ts/protocols/common/index.d.ts +7 -0
- package/dist_ts/protocols/common/index.js +8 -0
- package/dist_ts/protocols/common/types.d.ts +68 -0
- package/dist_ts/protocols/common/types.js +7 -0
- package/dist_ts/protocols/http/constants.d.ts +119 -0
- package/dist_ts/protocols/http/constants.js +200 -0
- package/dist_ts/protocols/http/index.d.ts +7 -0
- package/dist_ts/protocols/http/index.js +8 -0
- package/dist_ts/protocols/http/parser.d.ts +58 -0
- package/dist_ts/protocols/http/parser.js +184 -0
- package/dist_ts/protocols/http/types.d.ts +62 -0
- package/dist_ts/protocols/http/types.js +5 -0
- package/dist_ts/protocols/index.d.ts +11 -0
- package/dist_ts/protocols/index.js +12 -0
- package/dist_ts/protocols/proxy/index.d.ts +6 -0
- package/dist_ts/protocols/proxy/index.js +7 -0
- package/dist_ts/protocols/proxy/parser.d.ts +44 -0
- package/dist_ts/protocols/proxy/parser.js +153 -0
- package/dist_ts/protocols/proxy/types.d.ts +47 -0
- package/dist_ts/protocols/proxy/types.js +6 -0
- package/dist_ts/protocols/tls/alerts/index.d.ts +4 -0
- package/dist_ts/protocols/tls/alerts/index.js +5 -0
- package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +150 -0
- package/dist_ts/protocols/tls/alerts/tls-alert.js +226 -0
- package/dist_ts/protocols/tls/constants.d.ts +122 -0
- package/dist_ts/protocols/tls/constants.js +135 -0
- package/dist_ts/protocols/tls/index.d.ts +12 -0
- package/dist_ts/protocols/tls/index.js +27 -0
- package/dist_ts/protocols/tls/parser.d.ts +53 -0
- package/dist_ts/protocols/tls/parser.js +294 -0
- package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +100 -0
- package/dist_ts/protocols/tls/sni/client-hello-parser.js +463 -0
- package/dist_ts/protocols/tls/sni/index.d.ts +5 -0
- package/dist_ts/protocols/tls/sni/index.js +6 -0
- package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +58 -0
- package/dist_ts/protocols/tls/sni/sni-extraction.js +275 -0
- package/dist_ts/protocols/tls/types.d.ts +65 -0
- package/dist_ts/protocols/tls/types.js +5 -0
- package/dist_ts/protocols/tls/utils/index.d.ts +4 -0
- package/dist_ts/protocols/tls/utils/index.js +5 -0
- package/dist_ts/protocols/tls/utils/tls-utils.d.ts +158 -0
- package/dist_ts/protocols/tls/utils/tls-utils.js +187 -0
- package/dist_ts/protocols/websocket/constants.d.ts +55 -0
- package/dist_ts/protocols/websocket/constants.js +58 -0
- package/dist_ts/protocols/websocket/index.d.ts +7 -0
- package/dist_ts/protocols/websocket/index.js +8 -0
- package/dist_ts/protocols/websocket/types.d.ts +47 -0
- package/dist_ts/protocols/websocket/types.js +5 -0
- package/dist_ts/protocols/websocket/utils.d.ts +25 -0
- package/dist_ts/protocols/websocket/utils.js +103 -0
- package/dist_ts/proxies/http-proxy/models/http-types.d.ts +25 -27
- package/dist_ts/proxies/http-proxy/models/http-types.js +24 -44
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -0
- package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +81 -61
- package/dist_ts/proxies/smart-proxy/tls-manager.js +2 -1
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +1 -2
- package/dist_ts/proxies/smart-proxy/utils/index.js +3 -4
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +112 -8
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +231 -76
- package/dist_ts/tls/index.d.ts +5 -7
- package/dist_ts/tls/index.js +8 -11
- package/dist_ts/tls/sni/client-hello-parser.js +3 -2
- package/dist_ts/tls/sni/sni-handler.js +4 -4
- package/dist_ts/tls/utils/tls-utils.d.ts +1 -110
- package/dist_ts/tls/utils/tls-utils.js +4 -116
- package/package.json +17 -8
- package/readme.md +471 -2345
- package/readme.plan.md +0 -0
- package/ts/core/utils/proxy-protocol.ts +14 -131
- package/ts/core/utils/websocket-utils.ts +12 -60
- package/ts/detection/detectors/http-detector.ts +114 -0
- package/ts/detection/detectors/quick-detector.ts +148 -0
- package/ts/detection/detectors/routing-extractor.ts +147 -0
- package/ts/detection/detectors/tls-detector.ts +120 -0
- package/ts/detection/index.ts +25 -0
- package/ts/detection/models/detection-types.ts +102 -0
- package/ts/detection/models/interfaces.ts +115 -0
- package/ts/detection/protocol-detector.ts +230 -0
- package/ts/detection/utils/buffer-utils.ts +141 -0
- package/ts/detection/utils/fragment-manager.ts +64 -0
- package/ts/detection/utils/parser-utils.ts +77 -0
- package/ts/index.ts +3 -2
- package/ts/protocols/common/fragment-handler.ts +163 -0
- package/ts/protocols/common/index.ts +8 -0
- package/ts/protocols/common/types.ts +76 -0
- package/ts/protocols/http/constants.ts +219 -0
- package/ts/protocols/http/index.ts +8 -0
- package/ts/protocols/http/parser.ts +219 -0
- package/ts/protocols/http/types.ts +70 -0
- package/ts/protocols/index.ts +12 -0
- package/ts/protocols/proxy/index.ts +7 -0
- package/ts/protocols/proxy/parser.ts +183 -0
- package/ts/protocols/proxy/types.ts +53 -0
- package/ts/{tls → protocols/tls}/alerts/tls-alert.ts +1 -1
- package/ts/protocols/tls/index.ts +37 -0
- package/ts/protocols/tls/sni/index.ts +6 -0
- package/ts/{tls → protocols/tls}/utils/tls-utils.ts +1 -1
- package/ts/protocols/websocket/constants.ts +60 -0
- package/ts/protocols/websocket/index.ts +8 -0
- package/ts/protocols/websocket/types.ts +53 -0
- package/ts/protocols/websocket/utils.ts +98 -0
- package/ts/proxies/http-proxy/models/http-types.ts +29 -46
- package/ts/proxies/smart-proxy/models/interfaces.ts +7 -1
- package/ts/proxies/smart-proxy/models/route-types.ts +0 -1
- package/ts/proxies/smart-proxy/route-connection-handler.ts +91 -68
- package/ts/proxies/smart-proxy/tls-manager.ts +1 -0
- package/ts/proxies/smart-proxy/utils/index.ts +2 -13
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +323 -86
- package/ts/tls/index.ts +8 -12
- package/ts/tls/sni/sni-handler.ts +3 -3
- package/ts/forwarding/config/forwarding-types.ts +0 -76
- package/ts/forwarding/config/index.ts +0 -26
- package/ts/forwarding/factory/forwarding-factory.ts +0 -189
- package/ts/forwarding/factory/index.ts +0 -5
- package/ts/forwarding/handlers/base-handler.ts +0 -155
- package/ts/forwarding/handlers/http-handler.ts +0 -163
- package/ts/forwarding/handlers/https-passthrough-handler.ts +0 -185
- package/ts/forwarding/handlers/https-terminate-to-http-handler.ts +0 -312
- package/ts/forwarding/handlers/https-terminate-to-https-handler.ts +0 -297
- package/ts/forwarding/handlers/index.ts +0 -9
- package/ts/forwarding/index.ts +0 -35
- package/ts/proxies/smart-proxy/utils/route-patterns.ts +0 -403
- /package/ts/{tls → protocols/tls}/alerts/index.ts +0 -0
- /package/ts/{tls → protocols/tls}/sni/client-hello-parser.ts +0 -0
- /package/ts/{tls → protocols/tls}/sni/sni-extraction.ts +0 -0
- /package/ts/{tls → protocols/tls}/utils/index.ts +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Buffer manipulation utilities for protocol detection
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Import from protocols
|
|
6
|
+
import { HttpParser } from '../../protocols/http/index.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* BufferAccumulator class for handling fragmented data
|
|
10
|
+
*/
|
|
11
|
+
export class BufferAccumulator {
|
|
12
|
+
private chunks: Buffer[] = [];
|
|
13
|
+
private totalLength = 0;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Append data to the accumulator
|
|
17
|
+
*/
|
|
18
|
+
append(data: Buffer): void {
|
|
19
|
+
this.chunks.push(data);
|
|
20
|
+
this.totalLength += data.length;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get the accumulated buffer
|
|
25
|
+
*/
|
|
26
|
+
getBuffer(): Buffer {
|
|
27
|
+
if (this.chunks.length === 0) {
|
|
28
|
+
return Buffer.alloc(0);
|
|
29
|
+
}
|
|
30
|
+
if (this.chunks.length === 1) {
|
|
31
|
+
return this.chunks[0];
|
|
32
|
+
}
|
|
33
|
+
return Buffer.concat(this.chunks, this.totalLength);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get current buffer length
|
|
38
|
+
*/
|
|
39
|
+
length(): number {
|
|
40
|
+
return this.totalLength;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Clear all accumulated data
|
|
45
|
+
*/
|
|
46
|
+
clear(): void {
|
|
47
|
+
this.chunks = [];
|
|
48
|
+
this.totalLength = 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if accumulator has minimum bytes
|
|
53
|
+
*/
|
|
54
|
+
hasMinimumBytes(minBytes: number): boolean {
|
|
55
|
+
return this.totalLength >= minBytes;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Read a big-endian 16-bit integer from buffer
|
|
61
|
+
*/
|
|
62
|
+
export function readUInt16BE(buffer: Buffer, offset: number): number {
|
|
63
|
+
if (offset + 2 > buffer.length) {
|
|
64
|
+
throw new Error('Buffer too short for UInt16BE read');
|
|
65
|
+
}
|
|
66
|
+
return (buffer[offset] << 8) | buffer[offset + 1];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Read a big-endian 24-bit integer from buffer
|
|
71
|
+
*/
|
|
72
|
+
export function readUInt24BE(buffer: Buffer, offset: number): number {
|
|
73
|
+
if (offset + 3 > buffer.length) {
|
|
74
|
+
throw new Error('Buffer too short for UInt24BE read');
|
|
75
|
+
}
|
|
76
|
+
return (buffer[offset] << 16) | (buffer[offset + 1] << 8) | buffer[offset + 2];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Find a byte sequence in a buffer
|
|
81
|
+
*/
|
|
82
|
+
export function findSequence(buffer: Buffer, sequence: Buffer, startOffset = 0): number {
|
|
83
|
+
if (sequence.length === 0) {
|
|
84
|
+
return startOffset;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const searchLength = buffer.length - sequence.length + 1;
|
|
88
|
+
for (let i = startOffset; i < searchLength; i++) {
|
|
89
|
+
let found = true;
|
|
90
|
+
for (let j = 0; j < sequence.length; j++) {
|
|
91
|
+
if (buffer[i + j] !== sequence[j]) {
|
|
92
|
+
found = false;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (found) {
|
|
97
|
+
return i;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return -1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Extract a line from buffer (up to CRLF or LF)
|
|
105
|
+
*/
|
|
106
|
+
export function extractLine(buffer: Buffer, startOffset = 0): { line: string; nextOffset: number } | null {
|
|
107
|
+
// Delegate to protocol parser
|
|
108
|
+
return HttpParser.extractLine(buffer, startOffset);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Check if buffer starts with a string (case-insensitive)
|
|
113
|
+
*/
|
|
114
|
+
export function startsWithString(buffer: Buffer, str: string, offset = 0): boolean {
|
|
115
|
+
if (offset + str.length > buffer.length) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const bufferStr = buffer.slice(offset, offset + str.length).toString('utf8');
|
|
120
|
+
return bufferStr.toLowerCase() === str.toLowerCase();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Safe buffer slice that doesn't throw on out-of-bounds
|
|
125
|
+
*/
|
|
126
|
+
export function safeSlice(buffer: Buffer, start: number, end?: number): Buffer {
|
|
127
|
+
const safeStart = Math.max(0, Math.min(start, buffer.length));
|
|
128
|
+
const safeEnd = end === undefined
|
|
129
|
+
? buffer.length
|
|
130
|
+
: Math.max(safeStart, Math.min(end, buffer.length));
|
|
131
|
+
|
|
132
|
+
return buffer.slice(safeStart, safeEnd);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Check if buffer contains printable ASCII
|
|
137
|
+
*/
|
|
138
|
+
export function isPrintableAscii(buffer: Buffer, length?: number): boolean {
|
|
139
|
+
// Delegate to protocol parser
|
|
140
|
+
return HttpParser.isPrintableAscii(buffer, length);
|
|
141
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fragment Manager for Detection Module
|
|
3
|
+
*
|
|
4
|
+
* Manages fragmented protocol data using the shared fragment handler
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { FragmentHandler, type IFragmentOptions } from '../../protocols/common/fragment-handler.js';
|
|
8
|
+
import type { IConnectionContext } from '../../protocols/common/types.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detection-specific fragment manager
|
|
12
|
+
*/
|
|
13
|
+
export class DetectionFragmentManager {
|
|
14
|
+
private tlsFragments: FragmentHandler;
|
|
15
|
+
private httpFragments: FragmentHandler;
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
// Configure fragment handlers with appropriate limits
|
|
19
|
+
const tlsOptions: IFragmentOptions = {
|
|
20
|
+
maxBufferSize: 16384, // TLS record max size
|
|
21
|
+
timeout: 5000,
|
|
22
|
+
cleanupInterval: 30000
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const httpOptions: IFragmentOptions = {
|
|
26
|
+
maxBufferSize: 8192, // HTTP header reasonable limit
|
|
27
|
+
timeout: 5000,
|
|
28
|
+
cleanupInterval: 30000
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
this.tlsFragments = new FragmentHandler(tlsOptions);
|
|
32
|
+
this.httpFragments = new FragmentHandler(httpOptions);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get fragment handler for protocol type
|
|
37
|
+
*/
|
|
38
|
+
getHandler(protocol: 'tls' | 'http'): FragmentHandler {
|
|
39
|
+
return protocol === 'tls' ? this.tlsFragments : this.httpFragments;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Create connection ID from context
|
|
44
|
+
*/
|
|
45
|
+
static createConnectionId(context: IConnectionContext): string {
|
|
46
|
+
return context.id || `${context.sourceIp}:${context.sourcePort}-${context.destIp}:${context.destPort}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Clean up all handlers
|
|
51
|
+
*/
|
|
52
|
+
cleanup(): void {
|
|
53
|
+
this.tlsFragments.cleanup();
|
|
54
|
+
this.httpFragments.cleanup();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Destroy all handlers
|
|
59
|
+
*/
|
|
60
|
+
destroy(): void {
|
|
61
|
+
this.tlsFragments.destroy();
|
|
62
|
+
this.httpFragments.destroy();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser utilities for protocol detection
|
|
3
|
+
* Now delegates to protocol modules for actual parsing
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { THttpMethod, TTlsVersion } from '../models/detection-types.js';
|
|
7
|
+
import { HttpParser, HTTP_METHODS, HTTP_VERSIONS } from '../../protocols/http/index.js';
|
|
8
|
+
import { tlsVersionToString as protocolTlsVersionToString } from '../../protocols/tls/index.js';
|
|
9
|
+
|
|
10
|
+
// Re-export constants for backward compatibility
|
|
11
|
+
export { HTTP_METHODS, HTTP_VERSIONS };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse HTTP request line
|
|
15
|
+
*/
|
|
16
|
+
export function parseHttpRequestLine(line: string): {
|
|
17
|
+
method: THttpMethod;
|
|
18
|
+
path: string;
|
|
19
|
+
version: string;
|
|
20
|
+
} | null {
|
|
21
|
+
// Delegate to protocol parser
|
|
22
|
+
const result = HttpParser.parseRequestLine(line);
|
|
23
|
+
return result ? {
|
|
24
|
+
method: result.method as THttpMethod,
|
|
25
|
+
path: result.path,
|
|
26
|
+
version: result.version
|
|
27
|
+
} : null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Parse HTTP header line
|
|
32
|
+
*/
|
|
33
|
+
export function parseHttpHeader(line: string): { name: string; value: string } | null {
|
|
34
|
+
// Delegate to protocol parser
|
|
35
|
+
return HttpParser.parseHeaderLine(line);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Parse HTTP headers from lines
|
|
40
|
+
*/
|
|
41
|
+
export function parseHttpHeaders(lines: string[]): Record<string, string> {
|
|
42
|
+
// Delegate to protocol parser
|
|
43
|
+
return HttpParser.parseHeaders(lines);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convert TLS version bytes to version string
|
|
48
|
+
*/
|
|
49
|
+
export function tlsVersionToString(major: number, minor: number): TTlsVersion | null {
|
|
50
|
+
// Delegate to protocol parser
|
|
51
|
+
return protocolTlsVersionToString(major, minor) as TTlsVersion;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Extract domain from Host header value
|
|
56
|
+
*/
|
|
57
|
+
export function extractDomainFromHost(hostHeader: string): string {
|
|
58
|
+
// Delegate to protocol parser
|
|
59
|
+
return HttpParser.extractDomainFromHost(hostHeader);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Validate domain name
|
|
64
|
+
*/
|
|
65
|
+
export function isValidDomain(domain: string): boolean {
|
|
66
|
+
// Delegate to protocol parser
|
|
67
|
+
return HttpParser.isValidDomain(domain);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if string is a valid HTTP method
|
|
72
|
+
*/
|
|
73
|
+
export function isHttpMethod(str: string): str is THttpMethod {
|
|
74
|
+
// Delegate to protocol parser
|
|
75
|
+
return HttpParser.isHttpMethod(str) && (str as THttpMethod) !== undefined;
|
|
76
|
+
}
|
|
77
|
+
|
package/ts/index.ts
CHANGED
|
@@ -32,7 +32,8 @@ export * from './core/models/common-types.js';
|
|
|
32
32
|
export type { IAcmeOptions } from './proxies/smart-proxy/models/interfaces.js';
|
|
33
33
|
|
|
34
34
|
// Modular exports for new architecture
|
|
35
|
-
export * as forwarding from './forwarding/index.js';
|
|
36
35
|
// Certificate module has been removed - use SmartCertManager instead
|
|
37
36
|
export * as tls from './tls/index.js';
|
|
38
|
-
export * as routing from './routing/index.js';
|
|
37
|
+
export * as routing from './routing/index.js';
|
|
38
|
+
export * as detection from './detection/index.js';
|
|
39
|
+
export * as protocols from './protocols/index.js';
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Fragment Handler for Protocol Detection
|
|
3
|
+
*
|
|
4
|
+
* Provides unified fragment buffering and reassembly for protocols
|
|
5
|
+
* that may span multiple TCP packets.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Buffer } from 'buffer';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fragment tracking information
|
|
12
|
+
*/
|
|
13
|
+
export interface IFragmentInfo {
|
|
14
|
+
buffer: Buffer;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
connectionId: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Options for fragment handling
|
|
21
|
+
*/
|
|
22
|
+
export interface IFragmentOptions {
|
|
23
|
+
maxBufferSize?: number;
|
|
24
|
+
timeout?: number;
|
|
25
|
+
cleanupInterval?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Result of fragment processing
|
|
30
|
+
*/
|
|
31
|
+
export interface IFragmentResult {
|
|
32
|
+
isComplete: boolean;
|
|
33
|
+
buffer?: Buffer;
|
|
34
|
+
needsMoreData: boolean;
|
|
35
|
+
error?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Shared fragment handler for protocol detection
|
|
40
|
+
*/
|
|
41
|
+
export class FragmentHandler {
|
|
42
|
+
private fragments = new Map<string, IFragmentInfo>();
|
|
43
|
+
private cleanupTimer?: NodeJS.Timeout;
|
|
44
|
+
|
|
45
|
+
constructor(private options: IFragmentOptions = {}) {
|
|
46
|
+
// Start cleanup timer if not already running
|
|
47
|
+
if (options.cleanupInterval && !this.cleanupTimer) {
|
|
48
|
+
this.cleanupTimer = setInterval(
|
|
49
|
+
() => this.cleanup(),
|
|
50
|
+
options.cleanupInterval
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Add a fragment for a connection
|
|
57
|
+
*/
|
|
58
|
+
addFragment(connectionId: string, fragment: Buffer): IFragmentResult {
|
|
59
|
+
const existing = this.fragments.get(connectionId);
|
|
60
|
+
|
|
61
|
+
if (existing) {
|
|
62
|
+
// Append to existing buffer
|
|
63
|
+
const newBuffer = Buffer.concat([existing.buffer, fragment]);
|
|
64
|
+
|
|
65
|
+
// Check size limit
|
|
66
|
+
const maxSize = this.options.maxBufferSize || 65536;
|
|
67
|
+
if (newBuffer.length > maxSize) {
|
|
68
|
+
this.fragments.delete(connectionId);
|
|
69
|
+
return {
|
|
70
|
+
isComplete: false,
|
|
71
|
+
needsMoreData: false,
|
|
72
|
+
error: 'Buffer size exceeded maximum allowed'
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Update fragment info
|
|
77
|
+
this.fragments.set(connectionId, {
|
|
78
|
+
buffer: newBuffer,
|
|
79
|
+
timestamp: Date.now(),
|
|
80
|
+
connectionId
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
isComplete: false,
|
|
85
|
+
buffer: newBuffer,
|
|
86
|
+
needsMoreData: true
|
|
87
|
+
};
|
|
88
|
+
} else {
|
|
89
|
+
// New fragment
|
|
90
|
+
this.fragments.set(connectionId, {
|
|
91
|
+
buffer: fragment,
|
|
92
|
+
timestamp: Date.now(),
|
|
93
|
+
connectionId
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
isComplete: false,
|
|
98
|
+
buffer: fragment,
|
|
99
|
+
needsMoreData: true
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get the current buffer for a connection
|
|
106
|
+
*/
|
|
107
|
+
getBuffer(connectionId: string): Buffer | undefined {
|
|
108
|
+
return this.fragments.get(connectionId)?.buffer;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Mark a connection as complete and clean up
|
|
113
|
+
*/
|
|
114
|
+
complete(connectionId: string): void {
|
|
115
|
+
this.fragments.delete(connectionId);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Check if we're tracking a connection
|
|
120
|
+
*/
|
|
121
|
+
hasConnection(connectionId: string): boolean {
|
|
122
|
+
return this.fragments.has(connectionId);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Clean up expired fragments
|
|
127
|
+
*/
|
|
128
|
+
cleanup(): void {
|
|
129
|
+
const now = Date.now();
|
|
130
|
+
const timeout = this.options.timeout || 5000;
|
|
131
|
+
|
|
132
|
+
for (const [connectionId, info] of this.fragments.entries()) {
|
|
133
|
+
if (now - info.timestamp > timeout) {
|
|
134
|
+
this.fragments.delete(connectionId);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Clear all fragments
|
|
141
|
+
*/
|
|
142
|
+
clear(): void {
|
|
143
|
+
this.fragments.clear();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Destroy the handler and clean up resources
|
|
148
|
+
*/
|
|
149
|
+
destroy(): void {
|
|
150
|
+
if (this.cleanupTimer) {
|
|
151
|
+
clearInterval(this.cleanupTimer);
|
|
152
|
+
this.cleanupTimer = undefined;
|
|
153
|
+
}
|
|
154
|
+
this.clear();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get the number of tracked connections
|
|
159
|
+
*/
|
|
160
|
+
get size(): number {
|
|
161
|
+
return this.fragments.size;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Protocol Types
|
|
3
|
+
*
|
|
4
|
+
* Shared types used across different protocol implementations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Supported protocol types
|
|
9
|
+
*/
|
|
10
|
+
export type TProtocolType = 'tls' | 'http' | 'https' | 'websocket' | 'unknown';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Protocol detection result
|
|
14
|
+
*/
|
|
15
|
+
export interface IProtocolDetectionResult {
|
|
16
|
+
protocol: TProtocolType;
|
|
17
|
+
confidence: number; // 0-100
|
|
18
|
+
requiresMoreData?: boolean;
|
|
19
|
+
metadata?: {
|
|
20
|
+
version?: string;
|
|
21
|
+
method?: string;
|
|
22
|
+
[key: string]: any;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Routing information extracted from protocols
|
|
28
|
+
*/
|
|
29
|
+
export interface IRoutingInfo {
|
|
30
|
+
domain?: string;
|
|
31
|
+
port?: number;
|
|
32
|
+
path?: string;
|
|
33
|
+
protocol: TProtocolType;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Connection context for protocol operations
|
|
38
|
+
*/
|
|
39
|
+
export interface IConnectionContext {
|
|
40
|
+
id: string;
|
|
41
|
+
sourceIp?: string;
|
|
42
|
+
sourcePort?: number;
|
|
43
|
+
destIp?: string;
|
|
44
|
+
destPort?: number;
|
|
45
|
+
timestamp?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Protocol detection options
|
|
50
|
+
*/
|
|
51
|
+
export interface IProtocolDetectionOptions {
|
|
52
|
+
quickMode?: boolean; // Only do minimal detection
|
|
53
|
+
extractRouting?: boolean; // Extract routing information
|
|
54
|
+
maxWaitTime?: number; // Max time to wait for complete data
|
|
55
|
+
maxBufferSize?: number; // Max buffer size for fragmented data
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Base interface for protocol detectors
|
|
60
|
+
*/
|
|
61
|
+
export interface IProtocolDetector {
|
|
62
|
+
/**
|
|
63
|
+
* Check if this detector can handle the data
|
|
64
|
+
*/
|
|
65
|
+
canHandle(data: Buffer): boolean;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Perform quick detection (first few bytes only)
|
|
69
|
+
*/
|
|
70
|
+
quickDetect(data: Buffer): IProtocolDetectionResult;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Extract routing information if possible
|
|
74
|
+
*/
|
|
75
|
+
extractRouting?(data: Buffer, context?: IConnectionContext): IRoutingInfo | null;
|
|
76
|
+
}
|