From 5146ea8503d6a333e995b6e228cb84fd08a396bd Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 7 Jun 2025 11:31:28 +0100 Subject: [PATCH 1/3] Increase server first packet buffer size to 3000 --- internal/server/dispatcher.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/server/dispatcher.go b/internal/server/dispatcher.go index 4285ed3..2633030 100644 --- a/internal/server/dispatcher.go +++ b/internal/server/dispatcher.go @@ -20,6 +20,8 @@ import ( var b64 = base64.StdEncoding.EncodeToString +const firstPacketSize = 3000 + func Serve(l net.Listener, sta *State) { waitDur := [10]time.Duration{ 50 * time.Millisecond, 100 * time.Millisecond, 300 * time.Millisecond, 500 * time.Millisecond, 1 * time.Second, @@ -124,7 +126,7 @@ func readFirstPacket(conn net.Conn, buf []byte, timeout time.Duration) (int, Tra func dispatchConnection(conn net.Conn, sta *State) { var err error - buf := make([]byte, 1500) + buf := make([]byte, firstPacketSize) i, transport, redirOnErr, err := readFirstPacket(conn, buf, 15*time.Second) data := buf[:i] From 51ed286f3503cafa4c667666197e27c99716e7d2 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 7 Jun 2025 11:32:01 +0100 Subject: [PATCH 2/3] Update utls to 1.7.3 --- go.mod | 4 ++-- go.sum | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index a78fbe7..09e9560 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cbeuw/Cloak -go 1.24 +go 1.24.0 toolchain go1.24.2 @@ -9,7 +9,7 @@ require ( github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.3 github.com/juju/ratelimit v1.0.2 - github.com/refraction-networking/utls v1.6.6 + github.com/refraction-networking/utls v1.7.3 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.10.0 go.etcd.io/bbolt v1.4.0 diff --git a/go.sum b/go.sum index 7c83b92..2bdf5ce 100644 --- a/go.sum +++ b/go.sum @@ -28,6 +28,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/refraction-networking/utls v1.6.6 h1:igFsYBUJPYM8Rno9xUuDoM5GQrVEqY4llzEXOkL43Ig= github.com/refraction-networking/utls v1.6.6/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0= +github.com/refraction-networking/utls v1.7.0/go.mod h1:lV0Gwc1/Fi+HYH8hOtgFRdHfKo4FKSn6+FdyOz9hRms= +github.com/refraction-networking/utls v1.7.3 h1:L0WRhHY7Oq1T0zkdzVZMR6zWZv+sXbHB9zcuvsAEqCo= +github.com/refraction-networking/utls v1.7.3/go.mod h1:TUhh27RHMGtQvjQq+RyO11P6ZNQNBb3N0v7wsEjKAIQ= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= From 8af137637e646253ceef125e18fada2536404c45 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sun, 8 Jun 2025 18:14:39 +0100 Subject: [PATCH 3/3] 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 + } +}