Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/cbeuw/Cloak

go 1.24
go 1.24.0

toolchain go1.24.2

Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
12 changes: 11 additions & 1 deletion internal/client/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
24 changes: 11 additions & 13 deletions internal/client/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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,
}
}

Expand Down
23 changes: 23 additions & 0 deletions internal/client/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
4 changes: 3 additions & 1 deletion internal/server/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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]
Expand Down