@@ -19,6 +19,7 @@ import (
1919 "crypto/tls"
2020 "fmt"
2121 "io"
22+ "math"
2223 "math/rand"
2324 "net"
2425 "runtime"
@@ -256,9 +257,21 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
256257 }
257258 dialOptions := []libdial.DialOption {}
258259 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+
260274 protocol = "tcp"
261- dialOptions = append (dialOptions , libdial .WithAfterHook (libdial.AfterHook {Hook : frpNet .DialHookWebsocket ()}))
262275 }
263276 if svr .cfg .ConnectServerLocalIP != "" {
264277 dialOptions = append (dialOptions , libdial .WithLocalAddr (svr .cfg .ConnectServerLocalIP ))
@@ -269,11 +282,18 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
269282 libdial .WithKeepAlive (time .Duration (svr .cfg .DialServerKeepAlive )* time .Second ),
270283 libdial .WithProxy (proxyType , addr ),
271284 libdial .WithProxyAuth (auth ),
272- libdial .WithTLSConfig (tlsConfig ),
285+ libdial .WithTLSConfig (tlsConfig ), // TLS AfterHook has math.MaxUint64 priority
273286 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 ),
275289 }),
276290 )
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+
277297 conn , err = libdial .Dial (
278298 net .JoinHostPort (svr .cfg .ServerAddr , strconv .Itoa (svr .cfg .ServerPort )),
279299 dialOptions ... ,
0 commit comments