js-tcp-tunnel 1.0.2 → 1.0.3
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/package.json +1 -1
- package/src/lib.js +21 -132
- package/src/lib.test.js +3 -2
- package/src/types.ts +114 -0
package/package.json
CHANGED
package/src/lib.js
CHANGED
|
@@ -3,10 +3,12 @@ import net from 'node:net'
|
|
|
3
3
|
import { Readable, Writable } from 'node:stream'
|
|
4
4
|
import http from 'node:http'
|
|
5
5
|
import https from 'node:https'
|
|
6
|
+
import { ReadableStream, TransformStream, WritableStream } from 'node:stream/web'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @import {WebSocketServer} from 'ws'
|
|
9
10
|
* @import Router from 'koa-router'
|
|
11
|
+
* @import {SocketChannel, TCP_TUNNEL_DATA, TUNNEL_TCP_CLIENT_HELPER, TUNNEL_TCP_DATA_CONNECT, TUNNEL_TCP_DATA_LISTEN, TUNNEL_TCP_DATA_PINGPONG, TUNNEL_TCP_SERVER_HELPER, TunnelTcpClientHelperParam, TunnelTcpServerHelperParam} from './types.js'
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
const DEBUG_TUNNEL_TCP = false
|
|
@@ -53,14 +55,6 @@ export function formatNumber(num) {
|
|
|
53
55
|
return Number(num.toFixed(2))
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
/**
|
|
57
|
-
* @typedef {{
|
|
58
|
-
* promise: Promise<any>;
|
|
59
|
-
* resolve: (value: any | null) => void;
|
|
60
|
-
* reject: (reason: any | null) => void;
|
|
61
|
-
* }} PromiseResolvers
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
58
|
export function Promise_withResolvers() {
|
|
65
59
|
/** @type{(value?:object)=>void} */
|
|
66
60
|
let resolve = null
|
|
@@ -303,17 +297,17 @@ let tcpTunnelDataSend = 0
|
|
|
303
297
|
*/
|
|
304
298
|
export function printTcpTunnelData(data) {
|
|
305
299
|
return `id: ${`${data.srcId}:${data.dstId}`.padEnd(10)} channel: ${`${data.srcChannel}:${data.dstChannel}`.padEnd(10)} ${{
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
300
|
+
[TUNNEL_TCP_TYPE_INIT]: 'TUNNEL_TCP_TYPE_INIT ',
|
|
301
|
+
[TUNNEL_TCP_TYPE_LISTEN]: 'TUNNEL_TCP_TYPE_LISTEN ',
|
|
302
|
+
[TUNNEL_TCP_TYPE_ONLISTEN]: 'TUNNEL_TCP_TYPE_ONLISTEN ',
|
|
303
|
+
[TUNNEL_TCP_TYPE_CONNECT]: 'TUNNEL_TCP_TYPE_CONNECT ',
|
|
304
|
+
[TUNNEL_TCP_TYPE_ONCONNECT]: 'TUNNEL_TCP_TYPE_ONCONNECT ',
|
|
305
|
+
[TUNNEL_TCP_TYPE_DATA]: 'TUNNEL_TCP_TYPE_DATA ',
|
|
306
|
+
[TUNNEL_TCP_TYPE_ERROR]: 'TUNNEL_TCP_TYPE_ERROR ',
|
|
307
|
+
[TUNNEL_TCP_TYPE_CLOSE]: 'TUNNEL_TCP_TYPE_CLOSE ',
|
|
308
|
+
[TUNNEL_TCP_TYPE_PING]: 'TUNNEL_TCP_TYPE_PING ',
|
|
309
|
+
[TUNNEL_TCP_TYPE_PONG]: 'TUNNEL_TCP_TYPE_PONG ',
|
|
310
|
+
[TUNNEL_TCP_TYPE_ACK]: 'TUNNEL_TCP_TYPE_ACK ',
|
|
317
311
|
}[data.type]} recv: ${(tcpTunnelDataRecv)} send: ${(tcpTunnelDataSend)} size:${data.buffer.length}`
|
|
318
312
|
}
|
|
319
313
|
|
|
@@ -428,83 +422,6 @@ export const TUNNEL_TCP_TYPE_PING = 0x4768e1ba
|
|
|
428
422
|
export const TUNNEL_TCP_TYPE_PONG = 0x106f43fb
|
|
429
423
|
export const TUNNEL_TCP_TYPE_ACK = 0xc5870539
|
|
430
424
|
|
|
431
|
-
/**
|
|
432
|
-
* @typedef {TUNNEL_TCP_TYPE_INIT
|
|
433
|
-
* |TUNNEL_TCP_TYPE_LISTEN
|
|
434
|
-
* |TUNNEL_TCP_TYPE_ONLISTEN
|
|
435
|
-
* |TUNNEL_TCP_TYPE_CONNECT
|
|
436
|
-
* |TUNNEL_TCP_TYPE_ONCONNECT
|
|
437
|
-
* |TUNNEL_TCP_TYPE_DATA
|
|
438
|
-
* |TUNNEL_TCP_TYPE_ERROR
|
|
439
|
-
* |TUNNEL_TCP_TYPE_CLOSE
|
|
440
|
-
* |TUNNEL_TCP_TYPE_PING
|
|
441
|
-
* |TUNNEL_TCP_TYPE_PONG
|
|
442
|
-
* |TUNNEL_TCP_TYPE_ACK} TUNNEL_TCP_TYPE
|
|
443
|
-
*/
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* @typedef {{
|
|
447
|
-
* type:TUNNEL_TCP_TYPE;
|
|
448
|
-
* srcId:number;
|
|
449
|
-
* dstId:number;
|
|
450
|
-
* srcChannel:number;
|
|
451
|
-
* dstChannel:number;
|
|
452
|
-
* buffer:Uint8Array;
|
|
453
|
-
* }} TCP_TUNNEL_DATA
|
|
454
|
-
*/
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
* @typedef {{
|
|
458
|
-
* key:string;
|
|
459
|
-
* }} TUNNEL_TCP_DATA_LISTEN
|
|
460
|
-
*/
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* @typedef {{
|
|
464
|
-
* key:string;
|
|
465
|
-
* }} TUNNEL_TCP_DATA_CONNECT
|
|
466
|
-
*/
|
|
467
|
-
|
|
468
|
-
/**
|
|
469
|
-
* @typedef {{
|
|
470
|
-
* time:number;
|
|
471
|
-
* }} TUNNEL_TCP_DATA_PINGPONG
|
|
472
|
-
*/
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* @typedef {{
|
|
476
|
-
* id:number;
|
|
477
|
-
* encodeWriter:WritableStreamDefaultWriter<Uint8Array>;
|
|
478
|
-
* }} TUNNEL_TCP_SERVER
|
|
479
|
-
*/
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* @typedef {{
|
|
483
|
-
* readable:ReadableStream<Uint8Array>;
|
|
484
|
-
* writable:WritableStream<Uint8Array>;
|
|
485
|
-
* reader:ReadableStreamDefaultReader<Uint8Array>;
|
|
486
|
-
* writer:WritableStreamDefaultWriter<Uint8Array>;
|
|
487
|
-
* dstId:number;
|
|
488
|
-
* }} TUNNEL_TCP_SERVER_HELPER
|
|
489
|
-
* @typedef {{
|
|
490
|
-
* readable:ReadableStream<Uint8Array>;
|
|
491
|
-
* writable:WritableStream<Uint8Array>;
|
|
492
|
-
* reader:ReadableStreamDefaultReader<Uint8Array>;
|
|
493
|
-
* writer:WritableStreamDefaultWriter<Uint8Array>;
|
|
494
|
-
* listen:(param:{
|
|
495
|
-
* clientKey?:string;
|
|
496
|
-
* tunnelKey:string;
|
|
497
|
-
* host?:string;
|
|
498
|
-
* port:number;
|
|
499
|
-
* })=>Promise<void>;
|
|
500
|
-
* connect:(param:{
|
|
501
|
-
* clientKey?:string;
|
|
502
|
-
* tunnelKey: string;
|
|
503
|
-
* port: number;
|
|
504
|
-
* })=>Promise<void>;
|
|
505
|
-
* }} TUNNEL_TCP_CLIENT_HELPER
|
|
506
|
-
*/
|
|
507
|
-
|
|
508
425
|
/**
|
|
509
426
|
* @param {TCP_TUNNEL_DATA} box
|
|
510
427
|
*/
|
|
@@ -647,7 +564,7 @@ export function pipeSocketDataWithChannel(channelMap, channelId, encodeWriter) {
|
|
|
647
564
|
sendPackSize++
|
|
648
565
|
},
|
|
649
566
|
async close() {
|
|
650
|
-
|
|
567
|
+
encodeWriter.write(buildTcpTunnelData({
|
|
651
568
|
type: TUNNEL_TCP_TYPE_CLOSE,
|
|
652
569
|
srcId: channel.srcId,
|
|
653
570
|
srcChannel: channel.srcChannel,
|
|
@@ -846,7 +763,7 @@ async function dispatchClientBufferData(param, setup, listenKeyParamMap, channel
|
|
|
846
763
|
let channel = channelMap.get(channelId)
|
|
847
764
|
if (channel) {
|
|
848
765
|
channelMap.delete(channelId)
|
|
849
|
-
channel.socket.
|
|
766
|
+
channel.socket.destroy()
|
|
850
767
|
}
|
|
851
768
|
}
|
|
852
769
|
if (data.type == TUNNEL_TCP_TYPE_ERROR) {
|
|
@@ -923,39 +840,6 @@ export async function closeRemoteChannel(encodeWriter, data) {
|
|
|
923
840
|
})).catch((err) => { console.error('closeRemoteChannel stream write error', err.message) })
|
|
924
841
|
}
|
|
925
842
|
|
|
926
|
-
/**
|
|
927
|
-
* @typedef {{
|
|
928
|
-
* writer:WritableStreamDefaultWriter<Uint8Array>;
|
|
929
|
-
* socket:net.Socket;
|
|
930
|
-
* srcId:number;
|
|
931
|
-
* dstId:number;
|
|
932
|
-
* srcChannel:number;
|
|
933
|
-
* dstChannel:number;
|
|
934
|
-
* notify:(size:number)=>void;
|
|
935
|
-
* recvPackSize:number;
|
|
936
|
-
* key_iv:[CryptoKey, Uint8Array];
|
|
937
|
-
* }} SocketChannel
|
|
938
|
-
*/
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
/**
|
|
942
|
-
* @typedef {{
|
|
943
|
-
* uniqueId:number;
|
|
944
|
-
* listenMap:Map<string,number>;
|
|
945
|
-
* dstMap:Map<number,TUNNEL_TCP_SERVER>;
|
|
946
|
-
* serverKey?:string;
|
|
947
|
-
* }} TunnelTcpServerHelperParam
|
|
948
|
-
*/
|
|
949
|
-
|
|
950
|
-
/**
|
|
951
|
-
* @typedef {{
|
|
952
|
-
* signal:AbortSignal;
|
|
953
|
-
* serverKey?:string;
|
|
954
|
-
* uniqueId:number;
|
|
955
|
-
* clientDataId:number;
|
|
956
|
-
* }} TunnelTcpClientHelperParam
|
|
957
|
-
*/
|
|
958
|
-
|
|
959
843
|
/**
|
|
960
844
|
* @param {TunnelTcpServerHelperParam} param
|
|
961
845
|
*/
|
|
@@ -1144,7 +1028,7 @@ export function createTunnelTcpClientHelper(param) {
|
|
|
1144
1028
|
}
|
|
1145
1029
|
|
|
1146
1030
|
/** @type{TUNNEL_TCP_CLIENT_HELPER} */
|
|
1147
|
-
let helper = { readable: encode.readable, writable: decode.writable, reader: null, writer: null, listen, connect }
|
|
1031
|
+
let helper = { readable: encode.readable, writable: decode.writable, reader: null, writer: null, listen, connect, param: outParam }
|
|
1148
1032
|
return helper
|
|
1149
1033
|
|
|
1150
1034
|
}
|
|
@@ -1521,6 +1405,11 @@ export function createTunnelTcpClientHttp(param) {
|
|
|
1521
1405
|
console.error('createConnectionHttpx res close ')
|
|
1522
1406
|
promise.resolve()
|
|
1523
1407
|
})
|
|
1408
|
+
setTimeout(() => {
|
|
1409
|
+
if (helper.param.clientDataId < 1) {
|
|
1410
|
+
res.destroy(new Error('init clientId failed!'))
|
|
1411
|
+
}
|
|
1412
|
+
}, 10_000).unref()
|
|
1524
1413
|
})
|
|
1525
1414
|
Readable.fromWeb(transform.readable).pipe(req)
|
|
1526
1415
|
req.flushHeaders()
|
package/src/lib.test.js
CHANGED
|
@@ -62,7 +62,7 @@ test('tunnel-tcp-socket-test', async () => {
|
|
|
62
62
|
console.error(err.message)
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
-
let rec =
|
|
65
|
+
let rec = ''
|
|
66
66
|
|
|
67
67
|
await new Promise((resolve) => {
|
|
68
68
|
socket.on('connect', async () => {
|
|
@@ -86,7 +86,8 @@ test('tunnel-tcp-socket-test', async () => {
|
|
|
86
86
|
socketServer.close()
|
|
87
87
|
})
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
let from = rec.length - 'qwertyuiop - 99'.length
|
|
90
|
+
strictEqual(rec.substring(from), 'qwertyuiop - 99')
|
|
90
91
|
|
|
91
92
|
})
|
|
92
93
|
console.info('over!')
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import net from 'node:net'
|
|
2
|
+
import { WritableStream } from "stream/web"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export type PromiseResolvers = {
|
|
6
|
+
promise: Promise<any>
|
|
7
|
+
resolve: (value: any | null) => void
|
|
8
|
+
reject: (reason: any | null) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type TUNNEL_TCP_TYPE_INIT = 0xa9b398d5 // 链接建立后返回id
|
|
12
|
+
export type TUNNEL_TCP_TYPE_LISTEN = 0xe41957d3
|
|
13
|
+
export type TUNNEL_TCP_TYPE_ONLISTEN = 0x20993e38
|
|
14
|
+
export type TUNNEL_TCP_TYPE_CONNECT = 0x11d949f8
|
|
15
|
+
export type TUNNEL_TCP_TYPE_ONCONNECT = 0x377b2181
|
|
16
|
+
export type TUNNEL_TCP_TYPE_DATA = 0x48678f39
|
|
17
|
+
export type TUNNEL_TCP_TYPE_ERROR = 0x8117f762
|
|
18
|
+
export type TUNNEL_TCP_TYPE_CLOSE = 0x72fd6470
|
|
19
|
+
export type TUNNEL_TCP_TYPE_PING = 0x4768e1ba
|
|
20
|
+
export type TUNNEL_TCP_TYPE_PONG = 0x106f43fb
|
|
21
|
+
export type TUNNEL_TCP_TYPE_ACK = 0xc5870539
|
|
22
|
+
|
|
23
|
+
export type TUNNEL_TCP_TYPE = TUNNEL_TCP_TYPE_INIT |
|
|
24
|
+
TUNNEL_TCP_TYPE_LISTEN |
|
|
25
|
+
TUNNEL_TCP_TYPE_ONLISTEN |
|
|
26
|
+
TUNNEL_TCP_TYPE_CONNECT |
|
|
27
|
+
TUNNEL_TCP_TYPE_ONCONNECT |
|
|
28
|
+
TUNNEL_TCP_TYPE_DATA |
|
|
29
|
+
TUNNEL_TCP_TYPE_ERROR |
|
|
30
|
+
TUNNEL_TCP_TYPE_CLOSE |
|
|
31
|
+
TUNNEL_TCP_TYPE_PING |
|
|
32
|
+
TUNNEL_TCP_TYPE_PONG |
|
|
33
|
+
TUNNEL_TCP_TYPE_ACK
|
|
34
|
+
|
|
35
|
+
export type TCP_TUNNEL_DATA = {
|
|
36
|
+
type: TUNNEL_TCP_TYPE
|
|
37
|
+
srcId: number
|
|
38
|
+
dstId: number
|
|
39
|
+
srcChannel: number
|
|
40
|
+
dstChannel: number
|
|
41
|
+
buffer: Uint8Array
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type TUNNEL_TCP_DATA_LISTEN = {
|
|
45
|
+
key: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type TUNNEL_TCP_DATA_CONNECT = {
|
|
49
|
+
key: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type TUNNEL_TCP_DATA_PINGPONG = {
|
|
53
|
+
time: number
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type TUNNEL_TCP_SERVER = {
|
|
57
|
+
id: number
|
|
58
|
+
encodeWriter: WritableStreamDefaultWriter<Uint8Array>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type TUNNEL_TCP_SERVER_HELPER = {
|
|
62
|
+
readable: ReadableStream<Uint8Array>
|
|
63
|
+
writable: WritableStream<Uint8Array>
|
|
64
|
+
reader: ReadableStreamDefaultReader<Uint8Array>
|
|
65
|
+
writer: WritableStreamDefaultWriter<Uint8Array>
|
|
66
|
+
dstId: number
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type TUNNEL_TCP_CLIENT_HELPER = {
|
|
70
|
+
readable: ReadableStream<Uint8Array>
|
|
71
|
+
writable: WritableStream<Uint8Array>
|
|
72
|
+
reader: ReadableStreamDefaultReader<Uint8Array>
|
|
73
|
+
writer: WritableStreamDefaultWriter<Uint8Array>
|
|
74
|
+
param: TunnelTcpClientHelperParam
|
|
75
|
+
listen: (param: {
|
|
76
|
+
clientKey?: string
|
|
77
|
+
tunnelKey: string
|
|
78
|
+
host?: string
|
|
79
|
+
port: number
|
|
80
|
+
}) => Promise<void>
|
|
81
|
+
connect: (param: {
|
|
82
|
+
clientKey?: string
|
|
83
|
+
tunnelKey: string
|
|
84
|
+
port: number
|
|
85
|
+
}) => Promise<void>
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export type SocketChannel = {
|
|
90
|
+
writer: WritableStreamDefaultWriter<Uint8Array>
|
|
91
|
+
socket: net.Socket
|
|
92
|
+
srcId: number
|
|
93
|
+
dstId: number
|
|
94
|
+
srcChannel: number
|
|
95
|
+
dstChannel: number
|
|
96
|
+
notify: (size: number) => void
|
|
97
|
+
recvPackSize: number
|
|
98
|
+
key_iv: [CryptoKey, Uint8Array]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
export type TunnelTcpServerHelperParam = {
|
|
103
|
+
uniqueId: number
|
|
104
|
+
listenMap: Map<string, number>
|
|
105
|
+
dstMap: Map<number, TUNNEL_TCP_SERVER>
|
|
106
|
+
serverKey?: string
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type TunnelTcpClientHelperParam = {
|
|
110
|
+
signal: AbortSignal
|
|
111
|
+
serverKey?: string
|
|
112
|
+
uniqueId: number
|
|
113
|
+
clientDataId: number
|
|
114
|
+
}
|