@feng3d/cts 0.0.9 → 0.0.11
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/README.md +12 -3
- package/dist/data-channel.d.ts +93 -0
- package/dist/data-channel.d.ts.map +1 -0
- package/dist/data-channel.js +211 -0
- package/dist/data-channel.js.map +1 -0
- package/dist/handlers/control-handler.d.ts +10 -122
- package/dist/handlers/control-handler.d.ts.map +1 -1
- package/dist/handlers/control-handler.js +14 -164
- package/dist/handlers/control-handler.js.map +1 -1
- package/dist/handlers/unified-proxy.d.ts +40 -157
- package/dist/handlers/unified-proxy.d.ts.map +1 -1
- package/dist/handlers/unified-proxy.js +221 -355
- package/dist/handlers/unified-proxy.js.map +1 -1
- package/dist/server.d.ts +24 -68
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +144 -251
- package/dist/server.js.map +1 -1
- package/dist/session-manager.d.ts +2 -2
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +1 -1
- package/dist/session-manager.js.map +1 -1
- package/package.json +3 -3
package/dist/server.js
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module server
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* 穿透服务端核心模块。
|
|
5
|
+
*
|
|
6
|
+
* 在控制端口上同时支持三种通道:
|
|
7
|
+
* - WebSocket 控制通道(认证、心跳、注册等控制消息)
|
|
8
|
+
* - TCP 二进制数据通道(HTTP/WS/TCP 原始数据传输)
|
|
9
|
+
* - UDP 数据通道(UDP 原始数据传输)
|
|
10
|
+
*
|
|
11
|
+
* 通过首字节检测区分 WebSocket 和 TCP 数据通道连接。
|
|
5
12
|
*/
|
|
6
13
|
import { WebSocketServer } from 'ws';
|
|
7
14
|
import { createServer as createHttpServer } from 'http';
|
|
8
15
|
import { createServer as createHttpsServer } from 'https';
|
|
9
|
-
import {
|
|
16
|
+
import { createServer as createTcpServer } from 'net';
|
|
17
|
+
import { createSocket as createUdpSocket } from 'dgram';
|
|
18
|
+
import { DEFAULT_CONFIG, logger, isDataChannelAuth } from '@feng3d/chuantou-shared';
|
|
10
19
|
import { SessionManager } from './session-manager.js';
|
|
11
20
|
import { ControlHandler } from './handlers/control-handler.js';
|
|
12
21
|
import { UnifiedProxyHandler } from './handlers/unified-proxy.js';
|
|
22
|
+
import { DataChannelManager } from './data-channel.js';
|
|
13
23
|
/** 状态页面 HTML 模板 */
|
|
14
24
|
const STATUS_HTML = `<!DOCTYPE html>
|
|
15
25
|
<html lang="zh-CN">
|
|
@@ -22,260 +32,125 @@ const STATUS_HTML = `<!DOCTYPE html>
|
|
|
22
32
|
body {
|
|
23
33
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
24
34
|
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
|
25
|
-
min-height: 100vh;
|
|
26
|
-
color: #e0e0e0;
|
|
27
|
-
padding: 20px;
|
|
28
|
-
}
|
|
29
|
-
.container {
|
|
30
|
-
max-width: 800px;
|
|
31
|
-
margin: 0 auto;
|
|
35
|
+
min-height: 100vh; color: #e0e0e0; padding: 20px;
|
|
32
36
|
}
|
|
37
|
+
.container { max-width: 800px; margin: 0 auto; }
|
|
33
38
|
.header {
|
|
34
|
-
text-align: center;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
background: rgba(255,255,255,0.05);
|
|
38
|
-
border-radius: 16px;
|
|
39
|
-
backdrop-filter: blur(10px);
|
|
40
|
-
border: 1px solid rgba(255,255,255,0.1);
|
|
39
|
+
text-align: center; margin-bottom: 30px; padding: 30px 20px;
|
|
40
|
+
background: rgba(255,255,255,0.05); border-radius: 16px;
|
|
41
|
+
backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.1);
|
|
41
42
|
}
|
|
42
43
|
.header h1 {
|
|
43
|
-
font-size: 28px;
|
|
44
|
-
margin-bottom: 8px;
|
|
44
|
+
font-size: 28px; margin-bottom: 8px;
|
|
45
45
|
background: linear-gradient(90deg, #00d9ff, #00ff88);
|
|
46
|
-
-webkit-background-clip: text;
|
|
47
|
-
-webkit-text-fill-color: transparent;
|
|
46
|
+
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
|
48
47
|
}
|
|
49
48
|
.header .status {
|
|
50
|
-
display: inline-flex;
|
|
51
|
-
|
|
52
|
-
gap: 8px;
|
|
53
|
-
padding: 6px 16px;
|
|
54
|
-
border-radius: 20px;
|
|
55
|
-
font-size: 14px;
|
|
56
|
-
font-weight: 500;
|
|
57
|
-
}
|
|
58
|
-
.status.running {
|
|
59
|
-
background: rgba(0, 255, 136, 0.15);
|
|
60
|
-
color: #00ff88;
|
|
49
|
+
display: inline-flex; align-items: center; gap: 8px;
|
|
50
|
+
padding: 6px 16px; border-radius: 20px; font-size: 14px; font-weight: 500;
|
|
61
51
|
}
|
|
52
|
+
.status.running { background: rgba(0, 255, 136, 0.15); color: #00ff88; }
|
|
62
53
|
.status.running::before {
|
|
63
|
-
content: "";
|
|
64
|
-
|
|
65
|
-
height: 8px;
|
|
66
|
-
border-radius: 50%;
|
|
67
|
-
background: #00ff88;
|
|
68
|
-
animation: pulse 1.5s infinite;
|
|
69
|
-
}
|
|
70
|
-
.status.stopped {
|
|
71
|
-
background: rgba(255, 77, 77, 0.15);
|
|
72
|
-
color: #ff4d4d;
|
|
73
|
-
}
|
|
74
|
-
@keyframes pulse {
|
|
75
|
-
0%, 100% { opacity: 1; }
|
|
76
|
-
50% { opacity: 0.4; }
|
|
54
|
+
content: ""; width: 8px; height: 8px; border-radius: 50%;
|
|
55
|
+
background: #00ff88; animation: pulse 1.5s infinite;
|
|
77
56
|
}
|
|
57
|
+
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
78
58
|
.grid {
|
|
79
|
-
display: grid;
|
|
80
|
-
|
|
81
|
-
gap: 16px;
|
|
82
|
-
margin-bottom: 20px;
|
|
59
|
+
display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
60
|
+
gap: 16px; margin-bottom: 20px;
|
|
83
61
|
}
|
|
84
62
|
.card {
|
|
85
|
-
background: rgba(255,255,255,0.05);
|
|
86
|
-
border-
|
|
87
|
-
padding: 20px;
|
|
88
|
-
border: 1px solid rgba(255,255,255,0.1);
|
|
89
|
-
backdrop-filter: blur(10px);
|
|
90
|
-
}
|
|
91
|
-
.card-label {
|
|
92
|
-
font-size: 12px;
|
|
93
|
-
color: #888;
|
|
94
|
-
margin-bottom: 6px;
|
|
95
|
-
text-transform: uppercase;
|
|
96
|
-
letter-spacing: 0.5px;
|
|
97
|
-
}
|
|
98
|
-
.card-value {
|
|
99
|
-
font-size: 24px;
|
|
100
|
-
font-weight: 600;
|
|
101
|
-
color: #fff;
|
|
102
|
-
}
|
|
103
|
-
.card-value .unit {
|
|
104
|
-
font-size: 14px;
|
|
105
|
-
color: #888;
|
|
106
|
-
font-weight: 400;
|
|
63
|
+
background: rgba(255,255,255,0.05); border-radius: 12px; padding: 20px;
|
|
64
|
+
border: 1px solid rgba(255,255,255,0.1); backdrop-filter: blur(10px);
|
|
107
65
|
}
|
|
66
|
+
.card-label { font-size: 12px; color: #888; margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
67
|
+
.card-value { font-size: 24px; font-weight: 600; color: #fff; }
|
|
68
|
+
.card-value .unit { font-size: 14px; color: #888; font-weight: 400; }
|
|
108
69
|
.sessions {
|
|
109
|
-
background: rgba(255,255,255,0.05);
|
|
110
|
-
border-
|
|
111
|
-
padding: 20px;
|
|
112
|
-
border: 1px solid rgba(255,255,255,0.1);
|
|
113
|
-
margin-top: 20px;
|
|
114
|
-
}
|
|
115
|
-
.sessions-title {
|
|
116
|
-
font-size: 14px;
|
|
117
|
-
color: #888;
|
|
118
|
-
margin-bottom: 16px;
|
|
119
|
-
text-transform: uppercase;
|
|
120
|
-
letter-spacing: 0.5px;
|
|
70
|
+
background: rgba(255,255,255,0.05); border-radius: 12px; padding: 20px;
|
|
71
|
+
border: 1px solid rgba(255,255,255,0.1); margin-top: 20px;
|
|
121
72
|
}
|
|
73
|
+
.sessions-title { font-size: 14px; color: #888; margin-bottom: 16px; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
122
74
|
.session-item {
|
|
123
|
-
display: flex;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
.session-item:last-child {
|
|
133
|
-
margin-bottom: 0;
|
|
134
|
-
}
|
|
135
|
-
.session-id {
|
|
136
|
-
font-family: monospace;
|
|
137
|
-
color: #00d9ff;
|
|
138
|
-
}
|
|
139
|
-
.session-time {
|
|
140
|
-
color: #888;
|
|
141
|
-
}
|
|
142
|
-
.empty-state {
|
|
143
|
-
text-align: center;
|
|
144
|
-
padding: 30px;
|
|
145
|
-
color: #666;
|
|
146
|
-
font-size: 14px;
|
|
147
|
-
}
|
|
148
|
-
.footer {
|
|
149
|
-
text-align: center;
|
|
150
|
-
margin-top: 30px;
|
|
151
|
-
padding: 20px;
|
|
152
|
-
color: #666;
|
|
153
|
-
font-size: 12px;
|
|
154
|
-
}
|
|
155
|
-
.last-update {
|
|
156
|
-
text-align: center;
|
|
157
|
-
color: #666;
|
|
158
|
-
font-size: 12px;
|
|
159
|
-
margin-top: 10px;
|
|
160
|
-
}
|
|
75
|
+
display: flex; justify-content: space-between; align-items: center;
|
|
76
|
+
padding: 12px 16px; background: rgba(0,0,0,0.2); border-radius: 8px; margin-bottom: 8px; font-size: 14px;
|
|
77
|
+
}
|
|
78
|
+
.session-item:last-child { margin-bottom: 0; }
|
|
79
|
+
.session-id { font-family: monospace; color: #00d9ff; }
|
|
80
|
+
.session-time { color: #888; }
|
|
81
|
+
.empty-state { text-align: center; padding: 30px; color: #666; font-size: 14px; }
|
|
82
|
+
.footer { text-align: center; margin-top: 30px; padding: 20px; color: #666; font-size: 12px; }
|
|
83
|
+
.last-update { text-align: center; color: #666; font-size: 12px; margin-top: 10px; }
|
|
161
84
|
</style>
|
|
162
85
|
</head>
|
|
163
86
|
<body>
|
|
164
87
|
<div class="container">
|
|
165
88
|
<div class="header">
|
|
166
|
-
<h1
|
|
89
|
+
<h1>feng3d-cts 穿透服务器</h1>
|
|
167
90
|
<div class="status running" id="status">运行中</div>
|
|
168
91
|
</div>
|
|
169
|
-
|
|
170
92
|
<div class="grid">
|
|
171
|
-
<div class="card">
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
</div>
|
|
175
|
-
<div class="card">
|
|
176
|
-
|
|
177
|
-
<div class="card-value"><span id="uptime">-</span><span class="unit"> 秒</span></div>
|
|
178
|
-
</div>
|
|
179
|
-
<div class="card">
|
|
180
|
-
<div class="card-label">客户端</div>
|
|
181
|
-
<div class="card-value"><span id="clients">0</span><span class="unit"> 个</span></div>
|
|
182
|
-
</div>
|
|
183
|
-
<div class="card">
|
|
184
|
-
<div class="card-label">端口</div>
|
|
185
|
-
<div class="card-value"><span id="ports">0</span><span class="unit"> 个</span></div>
|
|
186
|
-
</div>
|
|
187
|
-
<div class="card">
|
|
188
|
-
<div class="card-label">连接数</div>
|
|
189
|
-
<div class="card-value"><span id="connections">0</span><span class="unit"> 个</span></div>
|
|
190
|
-
</div>
|
|
191
|
-
<div class="card">
|
|
192
|
-
<div class="card-label">TLS</div>
|
|
193
|
-
<div class="card-value" id="tls">-</div>
|
|
194
|
-
</div>
|
|
93
|
+
<div class="card"><div class="card-label">监听地址</div><div class="card-value" id="host">-</div></div>
|
|
94
|
+
<div class="card"><div class="card-label">运行时长</div><div class="card-value"><span id="uptime">-</span><span class="unit"> 秒</span></div></div>
|
|
95
|
+
<div class="card"><div class="card-label">客户端</div><div class="card-value"><span id="clients">0</span><span class="unit"> 个</span></div></div>
|
|
96
|
+
<div class="card"><div class="card-label">端口</div><div class="card-value"><span id="ports">0</span><span class="unit"> 个</span></div></div>
|
|
97
|
+
<div class="card"><div class="card-label">连接数</div><div class="card-value"><span id="connections">0</span><span class="unit"> 个</span></div></div>
|
|
98
|
+
<div class="card"><div class="card-label">TLS</div><div class="card-value" id="tls">-</div></div>
|
|
195
99
|
</div>
|
|
196
|
-
|
|
197
100
|
<div class="sessions">
|
|
198
101
|
<div class="sessions-title">客户端会话</div>
|
|
199
102
|
<div id="sessions-list"></div>
|
|
200
103
|
</div>
|
|
201
|
-
|
|
202
104
|
<div class="last-update">最后更新: <span id="lastUpdate">-</span></div>
|
|
203
|
-
|
|
204
105
|
<div class="footer">
|
|
205
|
-
<a href="https://github.com/feng3d/chuantou" target="_blank" style="color: #00d9ff; text-decoration: none;">feng3d-cts</a>
|
|
206
|
-
— 内网穿透服务端
|
|
106
|
+
<a href="https://github.com/feng3d/chuantou" target="_blank" style="color: #00d9ff; text-decoration: none;">feng3d-cts</a> — 内网穿透服务端
|
|
207
107
|
</div>
|
|
208
108
|
</div>
|
|
209
|
-
|
|
210
109
|
<script>
|
|
211
110
|
function formatUptime(ms) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (hours > 0) return \`\${hours}小时 \${minutes % 60}分钟\`;
|
|
218
|
-
if (minutes > 0) return \`\${minutes}分钟 \${seconds % 60}秒\`;
|
|
219
|
-
return \`\${seconds}秒\`;
|
|
111
|
+
var s = Math.floor(ms/1000), m = Math.floor(s/60), h = Math.floor(m/60), d = Math.floor(h/24);
|
|
112
|
+
if (d > 0) return d+'天 '+(h%24)+'小时';
|
|
113
|
+
if (h > 0) return h+'小时 '+(m%60)+'分钟';
|
|
114
|
+
if (m > 0) return m+'分钟 '+(s%60)+'秒';
|
|
115
|
+
return s+'秒';
|
|
220
116
|
}
|
|
221
|
-
|
|
222
|
-
function formatTime(timestamp) {
|
|
223
|
-
return new Date(timestamp).toLocaleTimeString('zh-CN');
|
|
224
|
-
}
|
|
225
|
-
|
|
226
117
|
async function updateStatus() {
|
|
227
118
|
try {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
document.getElementById('host').textContent = data.host + ':' + data.controlPort;
|
|
119
|
+
var res = await fetch('/_chuantou/status');
|
|
120
|
+
var data = await res.json();
|
|
121
|
+
document.getElementById('host').textContent = data.host+':'+data.controlPort;
|
|
232
122
|
document.getElementById('uptime').textContent = formatUptime(data.uptime);
|
|
233
123
|
document.getElementById('clients').textContent = data.authenticatedClients;
|
|
234
124
|
document.getElementById('ports').textContent = data.totalPorts;
|
|
235
125
|
document.getElementById('connections').textContent = data.activeConnections;
|
|
236
126
|
document.getElementById('tls').textContent = data.tls ? '已启用' : '已禁用';
|
|
237
127
|
document.getElementById('lastUpdate').textContent = new Date().toLocaleTimeString('zh-CN');
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const sessions = await sessionsRes.json();
|
|
242
|
-
const listEl = document.getElementById('sessions-list');
|
|
128
|
+
var sessionsRes = await fetch('/_chuantou/sessions');
|
|
129
|
+
var sessions = await sessionsRes.json();
|
|
130
|
+
var listEl = document.getElementById('sessions-list');
|
|
243
131
|
if (sessions.length === 0) {
|
|
244
132
|
listEl.innerHTML = '<div class="empty-state">暂无客户端连接</div>';
|
|
245
133
|
} else {
|
|
246
|
-
listEl.innerHTML = sessions.map(s
|
|
247
|
-
<div class="session-item">
|
|
248
|
-
|
|
249
|
-
<span class="session-time">连接于 \${formatTime(s.connectedAt)}</span>
|
|
250
|
-
</div>
|
|
251
|
-
\`).join('');
|
|
134
|
+
listEl.innerHTML = sessions.map(function(s) {
|
|
135
|
+
return '<div class="session-item"><span class="session-id">'+s.clientId.slice(0,8)+'...</span><span class="session-time">连接于 '+new Date(s.connectedAt).toLocaleTimeString('zh-CN')+'</span></div>';
|
|
136
|
+
}).join('');
|
|
252
137
|
}
|
|
253
|
-
} catch (e) {
|
|
254
|
-
logger.error('获取状态失败:', e);
|
|
255
|
-
}
|
|
138
|
+
} catch (e) { console.error('获取状态失败:', e); }
|
|
256
139
|
}
|
|
257
|
-
|
|
258
140
|
updateStatus();
|
|
259
141
|
setInterval(updateStatus, 3000);
|
|
260
142
|
</script>
|
|
261
143
|
</body>
|
|
262
|
-
</html
|
|
263
|
-
`;
|
|
144
|
+
</html>`;
|
|
264
145
|
/**
|
|
265
146
|
* 转发服务器
|
|
266
147
|
*
|
|
267
|
-
*
|
|
268
|
-
* -
|
|
269
|
-
* -
|
|
270
|
-
* -
|
|
271
|
-
* - 提供服务器状态查询和管理端点
|
|
148
|
+
* 在控制端口上通过协议复用同时支持:
|
|
149
|
+
* - WebSocket 控制通道(HTTP 升级)
|
|
150
|
+
* - TCP 二进制数据通道(魔数 0xFD 0x01 开头)
|
|
151
|
+
* - UDP 数据通道(dgram,自然与 TCP 分离)
|
|
272
152
|
*/
|
|
273
153
|
export class ForwardServer {
|
|
274
|
-
/**
|
|
275
|
-
* 创建转发服务器实例
|
|
276
|
-
*
|
|
277
|
-
* @param options - 服务器配置选项,未提供的字段将使用默认值
|
|
278
|
-
*/
|
|
279
154
|
constructor(options = {}) {
|
|
280
155
|
this.config = {
|
|
281
156
|
host: options.host ?? '0.0.0.0',
|
|
@@ -286,19 +161,18 @@ export class ForwardServer {
|
|
|
286
161
|
tls: options.tls,
|
|
287
162
|
};
|
|
288
163
|
this.sessionManager = new SessionManager(this.config.heartbeatInterval, this.config.sessionTimeout);
|
|
289
|
-
this.
|
|
164
|
+
this.dataChannelManager = new DataChannelManager(this.sessionManager);
|
|
165
|
+
this.proxyHandler = new UnifiedProxyHandler(this.sessionManager, this.dataChannelManager);
|
|
290
166
|
this.controlHandler = new ControlHandler(this.sessionManager, this.config, this.proxyHandler);
|
|
291
167
|
this.controlServer = new WebSocketServer({ noServer: true });
|
|
292
168
|
}
|
|
293
169
|
/**
|
|
294
170
|
* 启动服务器
|
|
295
171
|
*
|
|
296
|
-
*
|
|
297
|
-
* 开始监听控制端口,并启动定时统计输出。
|
|
298
|
-
*
|
|
299
|
-
* @returns 服务器启动完成的 Promise
|
|
172
|
+
* 创建底层 TCP 服务器进行协议复用,同时创建 UDP socket。
|
|
300
173
|
*/
|
|
301
174
|
async start() {
|
|
175
|
+
// 创建 HTTP 服务器(不直接 listen,由 TCP 服务器转发连接)
|
|
302
176
|
const serverOptions = this.config.tls ? {
|
|
303
177
|
key: this.config.tls.key,
|
|
304
178
|
cert: this.config.tls.cert,
|
|
@@ -314,54 +188,88 @@ export class ForwardServer {
|
|
|
314
188
|
this.controlHandler.handleConnection(ws);
|
|
315
189
|
});
|
|
316
190
|
});
|
|
317
|
-
|
|
191
|
+
// 创建底层 TCP 服务器进行协议复用
|
|
192
|
+
this.tcpServer = createTcpServer({ pauseOnConnect: true });
|
|
193
|
+
this.tcpServer.on('connection', (socket) => {
|
|
194
|
+
socket.once('readable', () => {
|
|
195
|
+
const data = socket.read(Math.min(socket.readableLength || 1024, 1024));
|
|
196
|
+
if (!data) {
|
|
197
|
+
socket.once('data', (firstData) => {
|
|
198
|
+
this.routeConnection(socket, firstData);
|
|
199
|
+
});
|
|
200
|
+
socket.resume();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
this.routeConnection(socket, data);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
this.tcpServer.on('error', (error) => {
|
|
318
207
|
logger.error('服务器错误:', error);
|
|
319
208
|
});
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
209
|
+
// 创建 UDP socket
|
|
210
|
+
this.udpSocket = createUdpSocket('udp4');
|
|
211
|
+
this.dataChannelManager.setUdpSocket(this.udpSocket);
|
|
212
|
+
this.udpSocket.on('message', (msg, rinfo) => {
|
|
213
|
+
this.dataChannelManager.handleUdpMessage(msg, rinfo);
|
|
214
|
+
});
|
|
215
|
+
this.udpSocket.on('error', (error) => {
|
|
216
|
+
logger.error('控制端口 UDP 错误:', error);
|
|
217
|
+
});
|
|
218
|
+
// 启动监听
|
|
219
|
+
return new Promise((resolve, reject) => {
|
|
220
|
+
this.tcpServer.listen(this.config.controlPort, this.config.host, () => {
|
|
221
|
+
const actualPort = this.tcpServer.address().port;
|
|
222
|
+
this.udpSocket.bind(actualPort, this.config.host, () => {
|
|
223
|
+
const protocol = this.config.tls ? 'https/wss' : 'http/ws';
|
|
224
|
+
logger.log(`控制服务器正在监听 ${protocol}://${this.config.host}:${actualPort} (TCP + UDP)`);
|
|
225
|
+
this.startedAt = Date.now();
|
|
226
|
+
this.statsInterval = setInterval(() => {
|
|
227
|
+
const stats = this.sessionManager.getStats();
|
|
228
|
+
logger.log(`统计: ${stats.authenticatedClients} 个已认证客户端, ${stats.totalPorts} 个端口, ${stats.totalConnections} 个连接`);
|
|
229
|
+
}, 60000);
|
|
230
|
+
resolve();
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
this.tcpServer.on('error', reject);
|
|
234
|
+
this.udpSocket.on('error', reject);
|
|
323
235
|
});
|
|
324
|
-
this.startedAt = Date.now();
|
|
325
|
-
this.statsInterval = setInterval(() => {
|
|
326
|
-
const stats = this.sessionManager.getStats();
|
|
327
|
-
logger.log(`统计: ${stats.authenticatedClients} 个已认证客户端, ${stats.totalPorts} 个端口, ${stats.totalConnections} 个连接`);
|
|
328
|
-
}, 60000);
|
|
329
236
|
}
|
|
330
237
|
/**
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
* 提供以下管理端点:
|
|
334
|
-
* - `GET /` — 返回状态监控页面(HTML)
|
|
335
|
-
* - `GET /_chuantou/status` — 返回服务器状态信息(JSON)
|
|
336
|
-
* - `GET /_chuantou/sessions` — 返回会话列表(JSON)
|
|
337
|
-
* - `POST /_chuantou/stop` — 停止服务器(JSON)
|
|
238
|
+
* 根据首字节路由 TCP 连接
|
|
338
239
|
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
240
|
+
* - 魔数 0xFD 0x01 → TCP 数据通道
|
|
241
|
+
* - HTTP 方法开头 → HTTP 服务器(管理端点 + WebSocket 升级)
|
|
341
242
|
*/
|
|
243
|
+
routeConnection(socket, data) {
|
|
244
|
+
if (isDataChannelAuth(data)) {
|
|
245
|
+
// 二进制数据通道
|
|
246
|
+
this.dataChannelManager.handleNewTcpConnection(socket, data);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// HTTP / WebSocket — 回推数据,交给 HTTP 服务器处理
|
|
250
|
+
socket.unshift(data);
|
|
251
|
+
this.httpServer.emit('connection', socket);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
342
254
|
handleHttpRequest(req, res) {
|
|
343
255
|
const url = req.url ?? '/';
|
|
344
|
-
// 状态监控页面
|
|
345
256
|
if (url === '/' && req.method === 'GET') {
|
|
346
257
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
347
258
|
res.end(STATUS_HTML);
|
|
348
259
|
return;
|
|
349
260
|
}
|
|
350
|
-
// 状态 API
|
|
351
261
|
if (url === '/_chuantou/status' && req.method === 'GET') {
|
|
352
262
|
const status = this.getStatus();
|
|
353
263
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
354
264
|
res.end(JSON.stringify(status));
|
|
355
265
|
return;
|
|
356
266
|
}
|
|
357
|
-
// 会话列表 API
|
|
358
267
|
if (url === '/_chuantou/sessions' && req.method === 'GET') {
|
|
359
268
|
const sessions = this.sessionManager.getSessions();
|
|
360
269
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
361
270
|
res.end(JSON.stringify(sessions));
|
|
362
271
|
return;
|
|
363
272
|
}
|
|
364
|
-
// 停止服务器 API
|
|
365
273
|
if (url === '/_chuantou/stop' && req.method === 'POST') {
|
|
366
274
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
367
275
|
res.end(JSON.stringify({ message: '服务器正在停止' }));
|
|
@@ -371,14 +279,6 @@ export class ForwardServer {
|
|
|
371
279
|
res.writeHead(200);
|
|
372
280
|
res.end('穿透服务器正在运行');
|
|
373
281
|
}
|
|
374
|
-
/**
|
|
375
|
-
* 停止服务器
|
|
376
|
-
*
|
|
377
|
-
* 依次停止统计定时器、WebSocket 控制服务器、HTTP 服务器,
|
|
378
|
-
* 以及所有 HTTP 和 WebSocket 代理,最后清理所有会话。
|
|
379
|
-
*
|
|
380
|
-
* @returns 服务器完全停止后的 Promise
|
|
381
|
-
*/
|
|
382
282
|
async stop() {
|
|
383
283
|
logger.log('正在停止服务器...');
|
|
384
284
|
if (this.statsInterval) {
|
|
@@ -386,24 +286,27 @@ export class ForwardServer {
|
|
|
386
286
|
this.statsInterval = undefined;
|
|
387
287
|
}
|
|
388
288
|
this.controlServer.close();
|
|
289
|
+
if (this.udpSocket) {
|
|
290
|
+
this.udpSocket.close();
|
|
291
|
+
this.udpSocket = undefined;
|
|
292
|
+
}
|
|
293
|
+
if (this.tcpServer) {
|
|
294
|
+
this.tcpServer.close();
|
|
295
|
+
this.tcpServer = undefined;
|
|
296
|
+
}
|
|
389
297
|
if (this.httpServer) {
|
|
390
298
|
this.httpServer.close();
|
|
299
|
+
this.httpServer = undefined;
|
|
391
300
|
}
|
|
392
301
|
await this.proxyHandler.stopAll();
|
|
302
|
+
this.dataChannelManager.clear();
|
|
393
303
|
this.sessionManager.clear();
|
|
394
304
|
logger.log('服务器已停止');
|
|
395
305
|
}
|
|
396
|
-
/**
|
|
397
|
-
* 获取服务器状态
|
|
398
|
-
*
|
|
399
|
-
* 汇总当前服务器的运行状态、网络配置和连接统计等信息。
|
|
400
|
-
*
|
|
401
|
-
* @returns 包含服务器运行状态的 {@link ServerStatus} 对象
|
|
402
|
-
*/
|
|
403
306
|
getStatus() {
|
|
404
307
|
const stats = this.sessionManager.getStats();
|
|
405
308
|
return {
|
|
406
|
-
running: this.
|
|
309
|
+
running: this.tcpServer?.listening ?? false,
|
|
407
310
|
host: this.config.host,
|
|
408
311
|
controlPort: this.config.controlPort,
|
|
409
312
|
tls: this.config.tls !== undefined,
|
|
@@ -413,19 +316,9 @@ export class ForwardServer {
|
|
|
413
316
|
activeConnections: stats.totalConnections,
|
|
414
317
|
};
|
|
415
318
|
}
|
|
416
|
-
/**
|
|
417
|
-
* 获取服务器配置
|
|
418
|
-
*
|
|
419
|
-
* @returns 当前服务器使用的 {@link ServerConfig} 配置对象
|
|
420
|
-
*/
|
|
421
319
|
getConfig() {
|
|
422
320
|
return this.config;
|
|
423
321
|
}
|
|
424
|
-
/**
|
|
425
|
-
* 获取会话管理器
|
|
426
|
-
*
|
|
427
|
-
* @returns 当前服务器使用的 {@link SessionManager} 会话管理器实例
|
|
428
|
-
*/
|
|
429
322
|
getSessionManager() {
|
|
430
323
|
return this.sessionManager;
|
|
431
324
|
}
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -115,9 +115,9 @@ export declare class SessionManager {
|
|
|
115
115
|
* @param clientId - 客户端唯一标识 ID
|
|
116
116
|
* @param connectionId - 连接唯一标识 ID
|
|
117
117
|
* @param remoteAddress - 远程连接的 IP 地址
|
|
118
|
-
* @param protocol -
|
|
118
|
+
* @param protocol - 连接协议类型
|
|
119
119
|
*/
|
|
120
|
-
addConnection(clientId: string, connectionId: string, remoteAddress: string, protocol: 'http' | 'websocket'): void;
|
|
120
|
+
addConnection(clientId: string, connectionId: string, remoteAddress: string, protocol: 'http' | 'websocket' | 'tcp' | 'udp'): void;
|
|
121
121
|
/**
|
|
122
122
|
* 移除连接记录
|
|
123
123
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAkC,MAAM,yBAAyB,CAAC;AAErF;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,wBAAwB;IACxB,OAAO,CAAC,OAAO,CAA0B;IACzC,6BAA6B;IAC7B,OAAO,CAAC,gBAAgB,CAAyB;IACjD,mBAAmB;IACnB,OAAO,CAAC,iBAAiB,CAAS;IAClC,iBAAiB;IACjB,OAAO,CAAC,cAAc,CAAS;IAC/B,cAAc;IACd,OAAO,CAAC,cAAc,CAAC,CAAiB;IAExC;;;;;OAKG;gBACS,iBAAiB,GAAE,MAA0C,EAAE,cAAc,GAAE,MAAuC;IAQlI;;;;;;;OAOG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM;IAaxC;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IAIlD;;;;;;;OAOG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IASxD;;;;;;;OAOG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIvD;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAU7C;;;;;;;;OAQG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAerD;;;;;;;;OAQG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAQvD;;;;;;;OAOG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IASjD;;;;;;;;;OASG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAkC,MAAM,yBAAyB,CAAC;AAErF;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,wBAAwB;IACxB,OAAO,CAAC,OAAO,CAA0B;IACzC,6BAA6B;IAC7B,OAAO,CAAC,gBAAgB,CAAyB;IACjD,mBAAmB;IACnB,OAAO,CAAC,iBAAiB,CAAS;IAClC,iBAAiB;IACjB,OAAO,CAAC,cAAc,CAAS;IAC/B,cAAc;IACd,OAAO,CAAC,cAAc,CAAC,CAAiB;IAExC;;;;;OAKG;gBACS,iBAAiB,GAAE,MAA0C,EAAE,cAAc,GAAE,MAAuC;IAQlI;;;;;;;OAOG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM;IAaxC;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IAIlD;;;;;;;OAOG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IASxD;;;;;;;OAOG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIvD;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAU7C;;;;;;;;OAQG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAerD;;;;;;;;OAQG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAQvD;;;;;;;OAOG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IASjD;;;;;;;;;OASG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI;IAalI;;;;;;OAMG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAM5C;;;;;;OAMG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiBrC;;;;;;OAMG;IACH,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAO9C;;;;;;OAMG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOvC;;;;;;OAMG;IACH,uBAAuB,IAAI,MAAM,EAAE;IAUnC;;;;;;OAMG;IACH,qBAAqB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAU5C;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;;;OAIG;IACH,kBAAkB,IAAI,IAAI;IAO1B;;;;;;;;;;OAUG;IACH,QAAQ,IAAI;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAqBhH;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;;OAMG;IACH,WAAW,IAAI,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAa3F"}
|
package/dist/session-manager.js
CHANGED
|
@@ -167,7 +167,7 @@ export class SessionManager {
|
|
|
167
167
|
* @param clientId - 客户端唯一标识 ID
|
|
168
168
|
* @param connectionId - 连接唯一标识 ID
|
|
169
169
|
* @param remoteAddress - 远程连接的 IP 地址
|
|
170
|
-
* @param protocol -
|
|
170
|
+
* @param protocol - 连接协议类型
|
|
171
171
|
*/
|
|
172
172
|
addConnection(clientId, connectionId, remoteAddress, protocol) {
|
|
173
173
|
const client = this.clients.get(clientId);
|