14
14
import top .meethigher .proxy .tcp .tunnel .handler .TunnelHandler ;
15
15
import top .meethigher .proxy .tcp .tunnel .proto .TunnelMessage ;
16
16
17
- import java .util .HashSet ;
18
- import java .util .Set ;
17
+ import java .util .LinkedHashMap ;
18
+ import java .util .Map ;
19
+ import java .util .concurrent .CountDownLatch ;
19
20
import java .util .concurrent .ThreadLocalRandom ;
21
+ import java .util .concurrent .atomic .AtomicBoolean ;
20
22
21
23
/**
24
+ *
25
+ *
22
26
* <p>背景:</p><p>我近期买了个树莓派,但是又不想随身带着树莓派,因此希望可以公网访问。</p>
23
27
* <p>
24
28
* 但是使用<a href="https://github.com/fatedier/frp">fatedier/frp</a>的过程中,不管在Windows还是Linux,都被扫出病毒了。
@@ -33,12 +37,12 @@ public class ReverseTcpProxyTunnelServer extends TunnelServer {
33
37
34
38
private static final Logger log = LoggerFactory .getLogger (ReverseTcpProxyTunnelServer .class );
35
39
protected static final char [] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" .toCharArray ();
36
- protected static final String SECRECT_TOKEN = "123456789 " ;
40
+ protected static final String SECRET_DEFAULT = "0123456789 " ;
37
41
38
42
39
43
protected String host = "0.0.0.0" ;
40
44
protected int port = 44444 ;
41
- protected Set <NetSocket > authedSockets = new HashSet <>(); // 授权成功的socket列表
45
+ protected Map <NetSocket , DataProxyServer > authedSockets = new LinkedHashMap <>();// 授权成功的socket列表
42
46
43
47
protected final String secret ;
44
48
protected final String name ;
@@ -53,7 +57,10 @@ public ReverseTcpProxyTunnelServer(Vertx vertx, NetServer netServer, String secr
53
57
socket .handler (decode (socket ));
54
58
socket .closeHandler (v -> {
55
59
log .debug ("closed {} -- {}" , socket .remoteAddress (), socket .localAddress ());
56
- authedSockets .remove (socket );
60
+ DataProxyServer removed = authedSockets .remove (socket );
61
+ if (removed != null ) {
62
+ removed .stop ();
63
+ }
57
64
});
58
65
TunnelHandler connectedHandler = tunnelHandlers .get (null );
59
66
if (connectedHandler != null ) {
@@ -71,6 +78,23 @@ protected void addMessageHandler() {
71
78
// 监听连接成功事件
72
79
this .onConnected ((vertx1 , netSocket , buffer ) -> log .debug ("{} connected" , netSocket .remoteAddress ()));
73
80
81
+ // 监听心跳事件
82
+ this .on (TunnelMessageType .HEARTBEAT , new AbstractTunnelHandler () {
83
+ @ Override
84
+ protected boolean doHandle (Vertx vertx , NetSocket netSocket , TunnelMessageType type , byte [] bodyBytes ) {
85
+ if (authedSockets .containsKey (netSocket )) {
86
+ netSocket .write (encode (TunnelMessageType .HEARTBEAT_ACK ,
87
+ TunnelMessage .HeartbeatAck .newBuilder ().setTimestamp (System .currentTimeMillis ())
88
+ .buildPartial ().toByteArray ()));
89
+ return true ;
90
+ } else {
91
+ // 未经过授权的心跳,直接拒绝
92
+ netSocket .close ();
93
+ return false ;
94
+ }
95
+ }
96
+ });
97
+
74
98
// 监听授权与开通端口事件
75
99
this .on (TunnelMessageType .OPEN_DATA_PORT , new AbstractTunnelHandler () {
76
100
@ Override
@@ -79,16 +103,30 @@ protected boolean doHandle(Vertx vertx, NetSocket netSocket, TunnelMessageType t
79
103
boolean result = false ;
80
104
try {
81
105
TunnelMessage .OpenDataPort parsed = TunnelMessage .OpenDataPort .parseFrom (bodyBytes );
106
+ TunnelMessage .OpenDataPortAck .Builder builder = TunnelMessage .OpenDataPortAck
107
+ .newBuilder ();
82
108
if (secret .equals (parsed .getSecret ())) {
83
- final int tPort = parsed .getPort ();
84
-
109
+ final DataProxyServer dataProxyServer = new DataProxyServer (vertx , parsed .getDataProxyName (), parsed .getDataProxyPort ());
110
+ if (dataProxyServer .startSync ()) {
111
+ result = true ;
112
+ builder .setSuccess (result ).setMessage ("success" );
113
+ netSocket .write (encode (TunnelMessageType .OPEN_DATA_PORT_ACK ,
114
+ builder .build ().toByteArray ()));
115
+ authedSockets .put (netSocket , dataProxyServer );
116
+ } else {
117
+ builder .setSuccess (result ).setMessage ("fail to open data port " + parsed .getDataProxyPort ());
118
+ netSocket .write (encode (TunnelMessageType .OPEN_DATA_PORT_ACK ,
119
+ builder .build ().toByteArray ())).onComplete (ar -> netSocket .close ());
120
+ }
121
+
85
122
} else {
123
+ TunnelMessage .OpenDataPortAck ack = TunnelMessage .OpenDataPortAck
124
+ .newBuilder ()
125
+ .setSuccess (result )
126
+ .setMessage ("your secret is incorrect!" )
127
+ .build ();
86
128
netSocket .write (encode (TunnelMessageType .OPEN_DATA_PORT_ACK ,
87
- TunnelMessage .OpenDataPortAck
88
- .newBuilder ()
89
- .setSuccess (result )
90
- .setMessage ("your secret is incorrect!" )
91
- .build ().toByteArray ())).onComplete (ar -> netSocket .close ());
129
+ ack .toByteArray ())).onComplete (ar -> netSocket .close ());
92
130
}
93
131
} catch (Exception e ) {
94
132
}
@@ -106,11 +144,11 @@ public static ReverseTcpProxyTunnelServer create(Vertx vertx, NetServer netServe
106
144
}
107
145
108
146
public static ReverseTcpProxyTunnelServer create (Vertx vertx , NetServer netServer ) {
109
- return new ReverseTcpProxyTunnelServer (vertx , netServer , SECRECT_TOKEN , generateName ());
147
+ return new ReverseTcpProxyTunnelServer (vertx , netServer , SECRET_DEFAULT , generateName ());
110
148
}
111
149
112
150
public static ReverseTcpProxyTunnelServer create (Vertx vertx ) {
113
- return new ReverseTcpProxyTunnelServer (vertx , vertx .createNetServer (), SECRECT_TOKEN , generateName ());
151
+ return new ReverseTcpProxyTunnelServer (vertx , vertx .createNetServer (), SECRET_DEFAULT , generateName ());
114
152
}
115
153
116
154
@@ -152,4 +190,99 @@ public void stop() {
152
190
.onFailure (e -> log .error ("{} close failed" , name , e ));
153
191
}
154
192
193
+
194
+ protected static class DataProxyServer {
195
+
196
+ protected final Vertx vertx ;
197
+ protected final NetServer netServer ;
198
+ protected final String name ;
199
+ protected final Handler <NetSocket > connectHandler ;
200
+
201
+ protected final String host ;
202
+ protected final int port ;
203
+
204
+ public DataProxyServer (Vertx vertx , String name ,
205
+ String host , int port ) {
206
+ this .vertx = vertx ;
207
+ this .name = name ;
208
+ this .host = host ;
209
+ this .port = port ;
210
+ this .netServer = this .vertx .createNetServer ();
211
+ this .connectHandler = socket -> {
212
+ };
213
+ }
214
+
215
+ public DataProxyServer (Vertx vertx , String name ,
216
+ int port ) {
217
+ this (vertx , name , "0.0.0.0" , port );
218
+ }
219
+
220
+ public void start () {
221
+ this .netServer
222
+ .connectHandler (this .connectHandler )
223
+ .listen (port , host )
224
+ .onComplete (ar -> {
225
+ if (ar .succeeded ()) {
226
+ log .info ("{} started on {}:{}" , name , host , port );
227
+ } else {
228
+ Throwable e = ar .cause ();
229
+ log .error ("{} start failed" , name , e );
230
+ }
231
+ });
232
+ }
233
+
234
+ public void stop () {
235
+ this .netServer .close ()
236
+ .onSuccess (v -> log .info ("{} closed" , name ))
237
+ .onFailure (e -> log .error ("{} close failed" , name , e ));
238
+ }
239
+
240
+ public boolean startSync () {
241
+ CountDownLatch latch = new CountDownLatch (1 );
242
+ AtomicBoolean success = new AtomicBoolean (false );
243
+ this .netServer
244
+ .connectHandler (this .connectHandler )
245
+ .listen (port , host )
246
+ .onComplete (ar -> {
247
+ if (ar .succeeded ()) {
248
+ success .set (true );
249
+ log .info ("{} started on {}:{}" , name , host , port );
250
+ } else {
251
+ Throwable e = ar .cause ();
252
+ log .error ("{} start failed" , name , e );
253
+ }
254
+ latch .countDown ();
255
+ });
256
+
257
+ try {
258
+ latch .await ();
259
+ } catch (Exception ignore ) {
260
+
261
+ }
262
+ return success .get ();
263
+ }
264
+
265
+ public boolean stopSync () {
266
+ CountDownLatch latch = new CountDownLatch (1 );
267
+ AtomicBoolean success = new AtomicBoolean (false );
268
+ this .netServer .close ()
269
+ .onComplete (ar -> {
270
+ if (ar .succeeded ()) {
271
+ success .set (true );
272
+ log .info ("{} closed" , name );
273
+ } else {
274
+ log .error ("{} close failed" , name , ar .cause ());
275
+ }
276
+ latch .countDown ();
277
+ });
278
+ try {
279
+ latch .await ();
280
+ } catch (Exception ignore ) {
281
+
282
+ }
283
+ return success .get ();
284
+ }
285
+
286
+ }
287
+
155
288
}
0 commit comments