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/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.log(`[socks] server is running on port ${port}`);
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.log(`[socks] handle connection upstream`, destination.addr);
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.log(`[socks] handle connection system`, destination.addr);
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.log(`[socks] handle connection local`, destination.addr);
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 upstream proxy: ' + err);
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
- this.__debug && console.log(`[socks] setupDataForwarding ${targetSocket.localAddress}:${targetSocket.localPort}`);
282
+ const localIpPort = `${targetSocket.localAddress}:${targetSocket.localPort}`;
283
+ this.__debug && console.info(`[socks] setupDataForwarding ${localIpPort}`);
263
284
  clientSocket.on('close', () => {
264
- this.__debug && console.error('[socks] client socket close', targetSocket?.remoteAddress || "");
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.log('[socks] closing SOCKS5 proxy server...');
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
- showConnectionPool() {
313
- Object.values(this.connectionPool).forEach((socket) => {
314
- if (socket) {
315
- console.log(`[socks] ${socket.remoteAddress} ${socket.localAddress}:${socket.localPort}`);
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,10 @@
1
+ export default class KValue<T = any> {
2
+ timestamp: number;
3
+ _key: string;
4
+ _value: T | undefined;
5
+ constructor(key: string, value?: T);
6
+ get key(): string;
7
+ get value(): T | undefined;
8
+ set(value?: T): void;
9
+ updateAt(): void;
10
+ }
@@ -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
+ }
@@ -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: <T = any>(task?: import("./typings").Ddan.PFunction<T> | undefined, wait?: number) => Promise<[any, undefined] | [null, T]>;
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: <T_1 = any, U extends object = any>(promise: Promise<T_1>, errorExt?: object | undefined) => Promise<[null, T_1] | [U, undefined]>;
225
- go: <T_2 = any>(task?: import("./typings").Ddan.PFunction<T_2> | undefined) => Promise<[any, undefined] | [null, T_2]>;
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: <T_3 = any>(func: any) => Promise<[any, undefined] | [null, T_3]>;
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;
@@ -35,6 +35,6 @@ export declare class Socks5 {
35
35
  private setupDataForwarding;
36
36
  private isAllowedDomain;
37
37
  close(): void;
38
- showConnectionPool(): void;
38
+ showPool(): void;
39
39
  }
40
40
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ddan-js",
3
- "version": "2.6.28",
3
+ "version": "2.6.30",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "ddan-js",