From 8af137637e646253ceef125e18fada2536404c45 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sun, 8 Jun 2025 18:14:39 +0100 Subject: [PATCH] Add backwards compatibility fallback to firefox --- internal/client/connector.go | 12 +++++++++++- internal/client/state.go | 24 +++++++++++------------- internal/client/transport.go | 23 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/internal/client/connector.go b/internal/client/connector.go index 9bd1f7b..610ce5b 100644 --- a/internal/client/connector.go +++ b/internal/client/connector.go @@ -21,8 +21,10 @@ func MakeSession(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.D var wg sync.WaitGroup for i := 0; i < connConfig.NumConn; i++ { wg.Add(1) + transportConfig := connConfig.Transport go func() { makeconn: + transportConn := transportConfig.CreateTransport() remoteConn, err := dialer.Dial("tcp", connConfig.RemoteAddr) if err != nil { log.Errorf("Failed to establish new connections to remote: %v", err) @@ -31,12 +33,20 @@ func MakeSession(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.D goto makeconn } - transportConn := connConfig.TransportMaker() sk, err := transportConn.Handshake(remoteConn, authInfo) if err != nil { log.Errorf("Failed to prepare connection to remote: %v", err) transportConn.Close() + + // In Cloak v2.11.0, we've updated uTLS version and subsequently increased the first packet size for chrome above 1500 + // https://github.com/cbeuw/Cloak/pull/306#issuecomment-2862728738. As a backwards compatibility feature, if we fail + // to connect using chrome signature, retry with firefox which has a smaller packet size. + if transportConfig.mode == "direct" && transportConfig.browser == chrome { + transportConfig.browser = firefox + log.Warnf("failed to connect with chrome signature, falling back to retry with firefox") + } time.Sleep(time.Second * 3) + goto makeconn } // sessionKey given by each connection should be identical diff --git a/internal/client/state.go b/internal/client/state.go index c3d1ded..dbbb929 100644 --- a/internal/client/state.go +++ b/internal/client/state.go @@ -43,11 +43,11 @@ type RawConfig struct { } type RemoteConnConfig struct { - Singleplex bool - NumConn int - KeepAlive time.Duration - RemoteAddr string - TransportMaker func() Transport + Singleplex bool + NumConn int + KeepAlive time.Duration + RemoteAddr string + Transport TransportConfig } type LocalConnConfig struct { @@ -230,10 +230,9 @@ func (raw *RawConfig) ProcessRawConfig(worldState common.WorldState) (local Loca raw.CDNWsUrlPath = "/" } - remote.TransportMaker = func() Transport { - return &WSOverTLS{ - wsUrl: "ws://" + cdnDomainPort + raw.CDNWsUrlPath, - } + remote.Transport = TransportConfig{ + mode: "cdn", + wsUrl: "ws://" + cdnDomainPort + raw.CDNWsUrlPath, } case "direct": fallthrough @@ -249,10 +248,9 @@ func (raw *RawConfig) ProcessRawConfig(worldState common.WorldState) (local Loca default: browser = chrome } - remote.TransportMaker = func() Transport { - return &DirectTLS{ - browser: browser, - } + remote.Transport = TransportConfig{ + mode: "direct", + browser: browser, } } diff --git a/internal/client/transport.go b/internal/client/transport.go index e86ffd5..539600c 100644 --- a/internal/client/transport.go +++ b/internal/client/transport.go @@ -8,3 +8,26 @@ type Transport interface { Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error) net.Conn } + +type TransportConfig struct { + mode string + + wsUrl string + + browser browser +} + +func (t TransportConfig) CreateTransport() Transport { + switch t.mode { + case "cdn": + return &WSOverTLS{ + wsUrl: t.wsUrl, + } + case "direct": + return &DirectTLS{ + browser: t.browser, + } + default: + return nil + } +}