ddan-js 2.6.27 → 2.6.29

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,
@@ -87,6 +91,8 @@ exports.default = {
87
91
  rule: rule_1.default,
88
92
  regex: regex_1.default,
89
93
  convert: convert_1.default,
94
+ KValue: kvalue_1.default,
95
+ Mapping: mapping_1.default,
90
96
  Event: event_1.default,
91
97
  Http: http_1.default,
92
98
  Store: store_1.default,
@@ -98,5 +104,5 @@ exports.default = {
98
104
  tracker: tracker_1.default,
99
105
  logger: logger_1.default,
100
106
  fetch: fetch_1.default,
101
- rsa: rsa_1.default
107
+ rsa: rsa_1.default,
102
108
  };
@@ -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;
@@ -112,6 +117,7 @@ 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)) {
@@ -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,11 @@ 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.connectionPool.delete(destKey);
206
219
  });
207
220
  return upstreamSocket;
208
221
  }
@@ -226,9 +239,11 @@ class Socks5 {
226
239
  };
227
240
  try {
228
241
  const { socket: upstreamSocket } = await socks_1.SocksClient.createConnection(options);
229
- this.connectionPool[destKey] = upstreamSocket;
242
+ // this.connectionPool[destKey] = upstreamSocket
243
+ this.connectionPool.set(destKey, upstreamSocket);
230
244
  upstreamSocket.on('close', () => {
231
- delete this.connectionPool[destKey];
245
+ // delete this.connectionPool[destKey]
246
+ this.connectionPool.delete(destKey);
232
247
  });
233
248
  return upstreamSocket;
234
249
  }
@@ -246,6 +261,12 @@ class Socks5 {
246
261
  const localSocket = net_1.default.createConnection(destination.port, destination.addr, () => {
247
262
  resolve(localSocket);
248
263
  });
264
+ // this.connectionPool[destKey] = localSocket
265
+ this.connectionPool.set(destKey, localSocket);
266
+ localSocket.on('close', () => {
267
+ // delete this.connectionPool[destKey]
268
+ this.connectionPool.delete(destKey);
269
+ });
249
270
  localSocket.on('error', (err) => {
250
271
  reject(err);
251
272
  });
@@ -255,8 +276,11 @@ class Socks5 {
255
276
  clientSocket.write(new Uint8Array([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
256
277
  clientSocket.pipe(targetSocket);
257
278
  targetSocket.pipe(clientSocket);
279
+ this.__debug &&
280
+ console.log(`[socks] setupDataForwarding ${targetSocket.localAddress}:${targetSocket.localPort}`);
258
281
  clientSocket.on('close', () => {
259
- this.__debug && console.error('[socks] client socket close', targetSocket?.remoteAddress || "");
282
+ this.__debug &&
283
+ console.error('[socks] client socket close', targetSocket?.remoteAddress || '');
260
284
  targetSocket.end();
261
285
  });
262
286
  targetSocket.on('close', () => {
@@ -295,14 +319,22 @@ class Socks5 {
295
319
  }
296
320
  });
297
321
  // 销毁客户端 socket
298
- this.clientSockets.forEach((socket) => socket.destroy());
322
+ this.clientSockets.forEach((socket) => socket?.destroy());
299
323
  // 销毁所有连接池中的 socket
300
- Object.values(this.connectionPool).forEach((socket) => socket.destroy());
324
+ // Object.values(this.connectionPool).forEach((socket) => socket?.destroy())
325
+ Array.from(this.connectionPool.values).forEach((kv) => kv?.value?.destroy());
301
326
  this.server = null;
302
327
  }
303
328
  catch (error) {
304
329
  this.__debug && console.error('[socks] close errot:', error);
305
330
  }
306
331
  }
332
+ showPool() {
333
+ Array.from(this.connectionPool.values).forEach((kv) => {
334
+ if (kv && kv.value) {
335
+ console.log(`[socks] ${kv.value.remoteAddress} ${kv.value.localAddress}:${kv.value.localPort}`);
336
+ }
337
+ });
338
+ }
307
339
  }
308
340
  exports.Socks5 = Socks5;
@@ -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;
@@ -517,7 +519,7 @@ declare const dNode: {
517
519
  brotliCompress: typeof import("./modules/node/brotli").brotliCompress;
518
520
  brotliDecompress: typeof import("./modules/node/brotli").brotliDecompress;
519
521
  };
520
- export { dUtil, dHook, dWeb, dMini, dCdn, dStore, dJoker, dTracker, dLogger, dNode };
522
+ export { dUtil, dHook, dWeb, dMini, dCdn, dStore, dJoker, dTracker, dLogger, dNode, KValue, Mapping };
521
523
  declare const _default: {
522
524
  gbk: {
523
525
  gbkLength: (str: string) => number;
@@ -851,6 +853,8 @@ declare const _default: {
851
853
  toUtf8Bytes: (content: string) => Uint8Array;
852
854
  fromUtf8Bytes: (utf8Bytes: Uint8Array) => string;
853
855
  };
856
+ KValue: typeof KValue;
857
+ Mapping: typeof Mapping;
854
858
  Event: typeof Event;
855
859
  Http: typeof Http;
856
860
  Store: typeof Store;
@@ -35,5 +35,6 @@ export declare class Socks5 {
35
35
  private setupDataForwarding;
36
36
  private isAllowedDomain;
37
37
  close(): void;
38
+ showPool(): void;
38
39
  }
39
40
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ddan-js",
3
- "version": "2.6.27",
3
+ "version": "2.6.29",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "ddan-js",