ddan-js 2.6.28 → 2.6.30
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/bin/ddan-js.esm.js +1 -1
- package/bin/ddan-js.js +1 -1
- package/bin/lib/class/kvalue.js +26 -0
- package/bin/lib/class/mapping.js +77 -0
- package/bin/lib/index.js +10 -2
- package/bin/lib/modules/node/socks5.js +44 -23
- package/bin/types/class/kvalue.d.ts +10 -0
- package/bin/types/class/mapping.d.ts +12 -0
- package/bin/types/index.d.ts +15 -5
- package/bin/types/modules/node/socks5.d.ts +1 -1
- package/package.json +1 -1
package/bin/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dNode = exports.dLogger = exports.dTracker = exports.dJoker = exports.dStore = exports.dCdn = exports.dMini = exports.dWeb = exports.dHook = exports.dUtil = void 0;
|
|
3
|
+
exports.Mapping = exports.KValue = exports.dNode = exports.dLogger = exports.dTracker = exports.dJoker = exports.dStore = exports.dCdn = exports.dMini = exports.dWeb = exports.dHook = exports.dUtil = void 0;
|
|
4
4
|
const gbk_1 = require("./modules/gbk");
|
|
5
5
|
const time_1 = require("./modules/time");
|
|
6
6
|
const hook_1 = require("./modules/hook");
|
|
@@ -31,6 +31,10 @@ const tracker_1 = require("./class/tracker");
|
|
|
31
31
|
const rsa_1 = require("./modules/rsa");
|
|
32
32
|
const node_1 = require("./modules/node");
|
|
33
33
|
const browser_1 = require("./modules/browser");
|
|
34
|
+
const kvalue_1 = require("./class/kvalue");
|
|
35
|
+
exports.KValue = kvalue_1.default;
|
|
36
|
+
const mapping_1 = require("./class/mapping");
|
|
37
|
+
exports.Mapping = mapping_1.default;
|
|
34
38
|
const dUtil = {
|
|
35
39
|
gbk: gbk_1.default,
|
|
36
40
|
math: math_1.default,
|
|
@@ -46,10 +50,12 @@ const dUtil = {
|
|
|
46
50
|
Event: event_1.default,
|
|
47
51
|
};
|
|
48
52
|
exports.dUtil = dUtil;
|
|
53
|
+
const singleton = util_1.default.singleton;
|
|
49
54
|
const dHook = {
|
|
50
55
|
...convert_1.default,
|
|
51
56
|
...crypto_1.default,
|
|
52
57
|
...hook_1.default,
|
|
58
|
+
singleton
|
|
53
59
|
};
|
|
54
60
|
exports.dHook = dHook;
|
|
55
61
|
const dMini = { mini: mini_1.default, css: css_1.default, qs: qs_1.default, icon: icon_1.default, html: html_1.default };
|
|
@@ -87,6 +93,8 @@ exports.default = {
|
|
|
87
93
|
rule: rule_1.default,
|
|
88
94
|
regex: regex_1.default,
|
|
89
95
|
convert: convert_1.default,
|
|
96
|
+
KValue: kvalue_1.default,
|
|
97
|
+
Mapping: mapping_1.default,
|
|
90
98
|
Event: event_1.default,
|
|
91
99
|
Http: http_1.default,
|
|
92
100
|
Store: store_1.default,
|
|
@@ -98,5 +106,5 @@ exports.default = {
|
|
|
98
106
|
tracker: tracker_1.default,
|
|
99
107
|
logger: logger_1.default,
|
|
100
108
|
fetch: fetch_1.default,
|
|
101
|
-
rsa: rsa_1.default
|
|
109
|
+
rsa: rsa_1.default,
|
|
102
110
|
};
|
|
@@ -4,12 +4,16 @@ exports.Socks5 = void 0;
|
|
|
4
4
|
const net_1 = require("net");
|
|
5
5
|
const socks_1 = require("socks");
|
|
6
6
|
const uuid_1 = require("../crypto/uuid");
|
|
7
|
+
const mapping_1 = require("../../class/mapping");
|
|
8
|
+
// interface IConnectionPool {
|
|
9
|
+
// [key: string]: Socket // Key为目标地址:端口组合
|
|
10
|
+
// }
|
|
7
11
|
class Socks5 {
|
|
8
12
|
upstreamProxy;
|
|
9
13
|
server = null;
|
|
10
14
|
clientSockets = new Set();
|
|
11
15
|
allowedDomains;
|
|
12
|
-
connectionPool
|
|
16
|
+
connectionPool;
|
|
13
17
|
systemProxy = null;
|
|
14
18
|
useSystemProxy = false;
|
|
15
19
|
__debug = false;
|
|
@@ -20,6 +24,7 @@ class Socks5 {
|
|
|
20
24
|
this.allowedDomains = new Set(allowedDomains);
|
|
21
25
|
this.__debug = debug;
|
|
22
26
|
this.__uuid = (0, uuid_1.default)();
|
|
27
|
+
this.connectionPool = new mapping_1.default();
|
|
23
28
|
}
|
|
24
29
|
get id() {
|
|
25
30
|
return this.__uuid;
|
|
@@ -56,7 +61,7 @@ class Socks5 {
|
|
|
56
61
|
this.__port = port;
|
|
57
62
|
this.server = net_1.default.createServer((socket) => this.handleSocksConnection(socket));
|
|
58
63
|
this.server.listen(port, () => {
|
|
59
|
-
this.__debug && console.
|
|
64
|
+
this.__debug && console.info(`[socks] server is running on port ${port}`);
|
|
60
65
|
});
|
|
61
66
|
this.server.on('error', (err) => {
|
|
62
67
|
console.error('[socks] server error:', err);
|
|
@@ -112,22 +117,23 @@ class Socks5 {
|
|
|
112
117
|
clientSocket?.destroy();
|
|
113
118
|
});
|
|
114
119
|
try {
|
|
120
|
+
this.connectionPool.clean(100, (kv) => kv?.destroy());
|
|
115
121
|
await this.performHandshake(clientSocket);
|
|
116
122
|
const destination = await this.parseClientRequest(clientSocket);
|
|
117
123
|
if (this.isAllowedDomain(destination.addr)) {
|
|
118
124
|
// 走上游代理
|
|
119
125
|
const upstreamSocket = await this.connectToUpstreamProxy(destination);
|
|
120
|
-
this.__debug && console.
|
|
126
|
+
this.__debug && console.info(`[socks] handle connection upstream`, destination.addr);
|
|
121
127
|
this.setupDataForwarding(clientSocket, upstreamSocket);
|
|
122
128
|
}
|
|
123
129
|
else if (this.useSystemProxy && this.systemProxy) {
|
|
124
130
|
// 走系统代理
|
|
125
131
|
const systemSocket = await this.connectToSystemProxy(destination);
|
|
126
|
-
this.__debug && console.
|
|
132
|
+
this.__debug && console.info(`[socks] handle connection system`, destination.addr);
|
|
127
133
|
this.setupDataForwarding(clientSocket, systemSocket);
|
|
128
134
|
}
|
|
129
135
|
else {
|
|
130
|
-
this.__debug && console.
|
|
136
|
+
this.__debug && console.info(`[socks] handle connection local`, destination.addr);
|
|
131
137
|
// 本地连接
|
|
132
138
|
const localSocket = await this.connectToLocal(destination);
|
|
133
139
|
this.setupDataForwarding(clientSocket, localSocket);
|
|
@@ -178,10 +184,15 @@ class Socks5 {
|
|
|
178
184
|
getPoolConnection(key) {
|
|
179
185
|
if (!key)
|
|
180
186
|
return undefined;
|
|
187
|
+
const connection = this.connectionPool.get(key);
|
|
181
188
|
// 如果已有连接在池中,复用
|
|
182
189
|
if (this.connectionPool[key] && !this.connectionPool[key].destroyed) {
|
|
183
190
|
return this.connectionPool[key];
|
|
184
191
|
}
|
|
192
|
+
// 如果已有连接在池中,复用
|
|
193
|
+
if (connection && !connection.destroyed) {
|
|
194
|
+
return connection;
|
|
195
|
+
}
|
|
185
196
|
return undefined;
|
|
186
197
|
}
|
|
187
198
|
// 上游代理连接
|
|
@@ -200,9 +211,12 @@ class Socks5 {
|
|
|
200
211
|
};
|
|
201
212
|
try {
|
|
202
213
|
const { socket: upstreamSocket } = await socks_1.SocksClient.createConnection(options);
|
|
203
|
-
this.connectionPool[destKey] = upstreamSocket
|
|
214
|
+
// this.connectionPool[destKey] = upstreamSocket
|
|
215
|
+
this.connectionPool.set(destKey, upstreamSocket);
|
|
204
216
|
upstreamSocket.on('close', () => {
|
|
205
|
-
delete this.connectionPool[destKey]
|
|
217
|
+
// delete this.connectionPool[destKey]
|
|
218
|
+
this.__debug && console.info('[socks] connection pool delete', destKey);
|
|
219
|
+
this.connectionPool.delete(destKey);
|
|
206
220
|
});
|
|
207
221
|
return upstreamSocket;
|
|
208
222
|
}
|
|
@@ -210,7 +224,7 @@ class Socks5 {
|
|
|
210
224
|
throw new Error('Failed to connect to upstream proxy: ' + err);
|
|
211
225
|
}
|
|
212
226
|
}
|
|
213
|
-
//
|
|
227
|
+
// 系统代理连接
|
|
214
228
|
async connectToSystemProxy(destination) {
|
|
215
229
|
const destKey = `${destination.addr}:${destination.port}`;
|
|
216
230
|
const cacheConnection = this.getPoolConnection(destKey);
|
|
@@ -226,14 +240,17 @@ class Socks5 {
|
|
|
226
240
|
};
|
|
227
241
|
try {
|
|
228
242
|
const { socket: upstreamSocket } = await socks_1.SocksClient.createConnection(options);
|
|
229
|
-
this.connectionPool[destKey] = upstreamSocket
|
|
243
|
+
// this.connectionPool[destKey] = upstreamSocket
|
|
244
|
+
this.connectionPool.set(destKey, upstreamSocket);
|
|
230
245
|
upstreamSocket.on('close', () => {
|
|
231
|
-
delete this.connectionPool[destKey]
|
|
246
|
+
// delete this.connectionPool[destKey]
|
|
247
|
+
this.__debug && console.info('[socks] connection pool delete', destKey);
|
|
248
|
+
this.connectionPool.delete(destKey);
|
|
232
249
|
});
|
|
233
250
|
return upstreamSocket;
|
|
234
251
|
}
|
|
235
252
|
catch (err) {
|
|
236
|
-
throw new Error('Failed to connect to
|
|
253
|
+
throw new Error('Failed to connect to system proxy: ' + err);
|
|
237
254
|
}
|
|
238
255
|
}
|
|
239
256
|
// 本地连接
|
|
@@ -246,9 +263,12 @@ class Socks5 {
|
|
|
246
263
|
const localSocket = net_1.default.createConnection(destination.port, destination.addr, () => {
|
|
247
264
|
resolve(localSocket);
|
|
248
265
|
});
|
|
249
|
-
this.connectionPool[destKey] = localSocket
|
|
266
|
+
// this.connectionPool[destKey] = localSocket
|
|
267
|
+
this.connectionPool.set(destKey, localSocket);
|
|
250
268
|
localSocket.on('close', () => {
|
|
251
|
-
delete this.connectionPool[destKey]
|
|
269
|
+
// delete this.connectionPool[destKey]
|
|
270
|
+
this.__debug && console.info('[socks] connection pool delete', destKey);
|
|
271
|
+
this.connectionPool.delete(destKey);
|
|
252
272
|
});
|
|
253
273
|
localSocket.on('error', (err) => {
|
|
254
274
|
reject(err);
|
|
@@ -259,14 +279,14 @@ class Socks5 {
|
|
|
259
279
|
clientSocket.write(new Uint8Array([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
|
|
260
280
|
clientSocket.pipe(targetSocket);
|
|
261
281
|
targetSocket.pipe(clientSocket);
|
|
262
|
-
|
|
282
|
+
const localIpPort = `${targetSocket.localAddress}:${targetSocket.localPort}`;
|
|
283
|
+
this.__debug && console.info(`[socks] setupDataForwarding ${localIpPort}`);
|
|
263
284
|
clientSocket.on('close', () => {
|
|
264
|
-
this.__debug && console.
|
|
285
|
+
this.__debug && console.info('[socks] client socket close', localIpPort);
|
|
265
286
|
targetSocket.end();
|
|
266
287
|
});
|
|
267
288
|
targetSocket.on('close', () => {
|
|
268
|
-
this.__debug &&
|
|
269
|
-
console.error('[socks] target socket close', targetSocket?.remoteAddress || targetSocket?.localAddress || '');
|
|
289
|
+
this.__debug && console.info('[socks] target socket close', localIpPort);
|
|
270
290
|
clientSocket.end();
|
|
271
291
|
});
|
|
272
292
|
clientSocket.on('error', (err) => {
|
|
@@ -293,7 +313,7 @@ class Socks5 {
|
|
|
293
313
|
try {
|
|
294
314
|
if (!this.server)
|
|
295
315
|
return;
|
|
296
|
-
this.__debug && console.
|
|
316
|
+
this.__debug && console.info('[socks] closing SOCKS5 proxy server...');
|
|
297
317
|
this.server.close((err) => {
|
|
298
318
|
if (err) {
|
|
299
319
|
this.__debug && console.error('[socks] closing the server failed:', err);
|
|
@@ -302,17 +322,18 @@ class Socks5 {
|
|
|
302
322
|
// 销毁客户端 socket
|
|
303
323
|
this.clientSockets.forEach((socket) => socket?.destroy());
|
|
304
324
|
// 销毁所有连接池中的 socket
|
|
305
|
-
Object.values(this.connectionPool).forEach((socket) => socket?.destroy())
|
|
325
|
+
// Object.values(this.connectionPool).forEach((socket) => socket?.destroy())
|
|
326
|
+
Array.from(this.connectionPool.values).forEach((kv) => kv?.value?.destroy());
|
|
306
327
|
this.server = null;
|
|
307
328
|
}
|
|
308
329
|
catch (error) {
|
|
309
330
|
this.__debug && console.error('[socks] close errot:', error);
|
|
310
331
|
}
|
|
311
332
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (
|
|
315
|
-
console.
|
|
333
|
+
showPool() {
|
|
334
|
+
Array.from(this.connectionPool.values).forEach((kv) => {
|
|
335
|
+
if (kv && kv.value) {
|
|
336
|
+
console.info(`[socks] ${kv.value.remoteAddress} ${kv.value.localAddress}:${kv.value.localPort}`);
|
|
316
337
|
}
|
|
317
338
|
});
|
|
318
339
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import KValue from './kvalue';
|
|
2
|
+
export default class Mapping<T = any> {
|
|
3
|
+
_map: Map<string, KValue<T>>;
|
|
4
|
+
constructor();
|
|
5
|
+
get keys(): IterableIterator<string>;
|
|
6
|
+
get values(): IterableIterator<KValue<T>>;
|
|
7
|
+
get(key: string): T | undefined;
|
|
8
|
+
set(key: string, value?: T): void;
|
|
9
|
+
delete(key: string, cb?: (value?: T, key?: string) => void): void;
|
|
10
|
+
clear(): void;
|
|
11
|
+
clean(max?: number, cb?: (value?: T, key?: string) => void): void;
|
|
12
|
+
}
|
package/bin/types/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import Http from './modules/http';
|
|
|
3
3
|
import Event from './class/event';
|
|
4
4
|
import Store from './class/store';
|
|
5
5
|
import Persist from './class/persist';
|
|
6
|
+
import KValue from './class/kvalue';
|
|
7
|
+
import Mapping from './class/mapping';
|
|
6
8
|
declare const dUtil: {
|
|
7
9
|
Event: typeof Event;
|
|
8
10
|
includes: typeof import("./util/includes").default;
|
|
@@ -210,8 +212,14 @@ declare const dUtil: {
|
|
|
210
212
|
};
|
|
211
213
|
};
|
|
212
214
|
declare const dHook: {
|
|
215
|
+
singleton: <T>() => {
|
|
216
|
+
new (): {};
|
|
217
|
+
__instance__: any;
|
|
218
|
+
readonly Instance: T;
|
|
219
|
+
readonly I: T;
|
|
220
|
+
};
|
|
213
221
|
sleep: (ms?: number) => Promise<unknown>;
|
|
214
|
-
run: <
|
|
222
|
+
run: <T_1 = any>(task?: import("./typings").Ddan.PFunction<T_1> | undefined, wait?: number) => Promise<[any, undefined] | [null, T_1]>;
|
|
215
223
|
exec: (func: import("./typings").Ddan.Function, taskId?: string) => import("./typings").Ddan.PSafeResult<any>;
|
|
216
224
|
debounce: typeof import("./modules/hook/modules/debounce").default;
|
|
217
225
|
throttle: typeof import("./modules/hook/modules/throttle").default;
|
|
@@ -221,10 +229,10 @@ declare const dHook: {
|
|
|
221
229
|
pipe: (func: import("./typings").Ddan.Function, callback?: ((result: import("./typings").Ddan.SafeResult<any>) => void) | undefined) => import("./modules/hook/modules/pipeline").default;
|
|
222
230
|
pipeline: (max?: number) => import("./modules/hook/modules/pipeline").default;
|
|
223
231
|
safeTask: (func: import("./typings").Ddan.Function, callback?: ((result: import("./typings").Ddan.SafeResult<any>) => void) | undefined) => import("./modules/hook/modules/safeTask").default;
|
|
224
|
-
to: <
|
|
225
|
-
go: <
|
|
232
|
+
to: <T_2 = any, U extends object = any>(promise: Promise<T_2>, errorExt?: object | undefined) => Promise<[null, T_2] | [U, undefined]>;
|
|
233
|
+
go: <T_3 = any>(task?: import("./typings").Ddan.PFunction<T_3> | undefined) => Promise<[any, undefined] | [null, T_3]>;
|
|
226
234
|
delay: (ms?: number) => Promise<unknown>;
|
|
227
|
-
safeRun: <
|
|
235
|
+
safeRun: <T_4 = any>(func: any) => Promise<[any, undefined] | [null, T_4]>;
|
|
228
236
|
base64: {
|
|
229
237
|
encode: (input: string) => string;
|
|
230
238
|
decode: (base64Str: string) => string;
|
|
@@ -517,7 +525,7 @@ declare const dNode: {
|
|
|
517
525
|
brotliCompress: typeof import("./modules/node/brotli").brotliCompress;
|
|
518
526
|
brotliDecompress: typeof import("./modules/node/brotli").brotliDecompress;
|
|
519
527
|
};
|
|
520
|
-
export { dUtil, dHook, dWeb, dMini, dCdn, dStore, dJoker, dTracker, dLogger, dNode };
|
|
528
|
+
export { dUtil, dHook, dWeb, dMini, dCdn, dStore, dJoker, dTracker, dLogger, dNode, KValue, Mapping };
|
|
521
529
|
declare const _default: {
|
|
522
530
|
gbk: {
|
|
523
531
|
gbkLength: (str: string) => number;
|
|
@@ -851,6 +859,8 @@ declare const _default: {
|
|
|
851
859
|
toUtf8Bytes: (content: string) => Uint8Array;
|
|
852
860
|
fromUtf8Bytes: (utf8Bytes: Uint8Array) => string;
|
|
853
861
|
};
|
|
862
|
+
KValue: typeof KValue;
|
|
863
|
+
Mapping: typeof Mapping;
|
|
854
864
|
Event: typeof Event;
|
|
855
865
|
Http: typeof Http;
|
|
856
866
|
Store: typeof Store;
|