@@ -19,6 +19,7 @@ import (
19
19
"crypto/tls"
20
20
"fmt"
21
21
"io"
22
+ "math"
22
23
"math/rand"
23
24
"net"
24
25
"runtime"
@@ -256,9 +257,21 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
256
257
}
257
258
dialOptions := []libdial.DialOption {}
258
259
protocol := svr .cfg .Protocol
259
- if protocol == "websocket" {
260
+ var websocketAfterHook * libdial.AfterHook
261
+ if protocol == "websocket" || protocol == "wss" {
262
+ if protocol == "wss" {
263
+ websocketAfterHook = & libdial.AfterHook {
264
+ Priority : math .MaxUint64 , // in case of wss, we first want to make the TLS handshake and then switch protocols from https to wss
265
+ Hook : frpNet .DialHookWebsocket (true ),
266
+ }
267
+ } else {
268
+ websocketAfterHook = & libdial.AfterHook {
269
+ Priority : 0 , // in case of ws, we first want to switch protocols from http to ws, and only then make the TLS handshake in case TLS is enabled
270
+ Hook : frpNet .DialHookWebsocket (false ),
271
+ }
272
+ }
273
+
260
274
protocol = "tcp"
261
- dialOptions = append (dialOptions , libdial .WithAfterHook (libdial.AfterHook {Hook : frpNet .DialHookWebsocket ()}))
262
275
}
263
276
if svr .cfg .ConnectServerLocalIP != "" {
264
277
dialOptions = append (dialOptions , libdial .WithLocalAddr (svr .cfg .ConnectServerLocalIP ))
@@ -269,11 +282,18 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
269
282
libdial .WithKeepAlive (time .Duration (svr .cfg .DialServerKeepAlive )* time .Second ),
270
283
libdial .WithProxy (proxyType , addr ),
271
284
libdial .WithProxyAuth (auth ),
272
- libdial .WithTLSConfig (tlsConfig ),
285
+ libdial .WithTLSConfig (tlsConfig ), // TLS AfterHook has math.MaxUint64 priority
273
286
libdial .WithAfterHook (libdial.AfterHook {
274
- Hook : frpNet .DialHookCustomTLSHeadByte (tlsConfig != nil , svr .cfg .DisableCustomTLSFirstByte ),
287
+ Priority : 1 , // should be executed before TLS AfterHook but after the rest of the AfterHooks (except for wss)
288
+ Hook : frpNet .DialHookCustomTLSHeadByte (tlsConfig != nil , svr .cfg .DisableCustomTLSFirstByte ),
275
289
}),
276
290
)
291
+ if websocketAfterHook != nil {
292
+ // websocketAfterHook must be appended after TLS AfterHook because they both might have the
293
+ // same priority of math.MaxUint64 in case of wss but TLS AfterHook must be executed first
294
+ dialOptions = append (dialOptions , libdial .WithAfterHook (* websocketAfterHook ))
295
+ }
296
+
277
297
conn , err = libdial .Dial (
278
298
net .JoinHostPort (svr .cfg .ServerAddr , strconv .Itoa (svr .cfg .ServerPort )),
279
299
dialOptions ... ,
0 commit comments