Refactor client transport modules

This commit is contained in:
Andy Wang 2022-07-11 23:22:20 +01:00
parent 896fd16938
commit 4029763123
No known key found for this signature in database
GPG Key ID: 181B49F9F38F3374
8 changed files with 49 additions and 45 deletions

View File

@ -20,6 +20,8 @@ type CloakClient struct {
session *mux.Session session *mux.Session
} }
const appDataMaxLength = 16401
// On different invocations to NewCloakClient, authInfo.SessionId MUST be different // On different invocations to NewCloakClient, authInfo.SessionId MUST be different
func NewCloakClient(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.Dialer) *CloakClient { func NewCloakClient(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.Dialer) *CloakClient {
log.Info("Attempting to start a new session") log.Info("Attempting to start a new session")

View File

@ -37,7 +37,6 @@ type RawConfig struct {
BrowserSig string // nullable BrowserSig string // nullable
Transport string // nullable Transport string // nullable
CDNOriginHost string // nullable CDNOriginHost string // nullable
CDNWsUrlPath string // nullable
StreamTimeout int // nullable StreamTimeout int // nullable
KeepAlive int // nullable KeepAlive int // nullable
} }
@ -47,7 +46,7 @@ type RemoteConnConfig struct {
NumConn int NumConn int
KeepAlive time.Duration KeepAlive time.Duration
RemoteAddr string RemoteAddr string
TransportMaker func() Transport TransportMaker func() transports.Transport
} }
type LocalConnConfig struct { type LocalConnConfig struct {
@ -56,16 +55,7 @@ type LocalConnConfig struct {
MockDomainList []string MockDomainList []string
} }
type AuthInfo struct { type AuthInfo = transports.AuthInfo
UID []byte
SessionId uint32
ProxyMethod string
EncryptionMethod byte
Unordered bool
ServerPubKey crypto.PublicKey
MockDomain string
WorldState common.WorldState
}
// semi-colon separated value. This is for Android plugin options // semi-colon separated value. This is for Android plugin options
func ssvToJson(ssv string) (ret []byte) { func ssvToJson(ssv string) (ret []byte) {
@ -220,19 +210,18 @@ func (raw *RawConfig) ProcessRawConfig(worldState common.WorldState) (local Loca
// Transport and (if TLS mode), browser // Transport and (if TLS mode), browser
switch strings.ToLower(raw.Transport) { switch strings.ToLower(raw.Transport) {
case "cdn": case "cdn":
var cdnDomainPort string cdnPort := raw.RemotePort
var cdnHost string
if raw.CDNOriginHost == "" { if raw.CDNOriginHost == "" {
cdnDomainPort = net.JoinHostPort(raw.RemoteHost, raw.RemotePort) cdnHost = raw.RemoteHost
} else { } else {
cdnDomainPort = net.JoinHostPort(raw.CDNOriginHost, raw.RemotePort) cdnHost = raw.CDNOriginHost
}
if raw.CDNWsUrlPath == "" {
raw.CDNWsUrlPath = "/"
} }
remote.TransportMaker = func() Transport { remote.TransportMaker = func() transports.Transport {
return &WSOverTLS{ return &transports.WSOverTLS{
wsUrl: "ws://" + cdnDomainPort + raw.CDNWsUrlPath, CDNHost: cdnHost,
CDNPort: cdnPort,
} }
} }
case "direct": case "direct":
@ -249,9 +238,9 @@ func (raw *RawConfig) ProcessRawConfig(worldState common.WorldState) (local Loca
default: default:
browser = chrome browser = chrome
} }
remote.TransportMaker = func() Transport { remote.TransportMaker = func() transports.Transport {
return &DirectTLS{ return &transports.DirectTLS{
browser: browser, Browser: browser,
} }
} }
} }

View File

@ -1,10 +0,0 @@
package client
import (
"net"
)
type Transport interface {
Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error)
net.Conn
}

View File

@ -1,4 +1,4 @@
package client package transports
import ( import (
utls "github.com/refraction-networking/utls" utls "github.com/refraction-networking/utls"
@ -27,6 +27,7 @@ const (
type DirectTLS struct { type DirectTLS struct {
*common.TLSConn *common.TLSConn
Browser browsers.Browser
browser browser browser browser
} }
@ -88,7 +89,6 @@ func (tls *DirectTLS) Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey
x25519KeyShare: payload.ciphertextWithTag[32:64], x25519KeyShare: payload.ciphertextWithTag[32:64],
serverName: authInfo.MockDomain, serverName: authInfo.MockDomain,
} }
var ch []byte var ch []byte
ch, err = buildClientHello(tls.browser, fields) ch, err = buildClientHello(tls.browser, fields)
if err != nil { if err != nil {

View File

@ -1,4 +1,4 @@
package client package transports
import ( import (
"encoding/binary" "encoding/binary"

View File

@ -1,4 +1,4 @@
package client package transports
import ( import (
"bytes" "bytes"

View File

@ -0,0 +1,23 @@
package transports
import (
"crypto"
"github.com/cbeuw/Cloak/internal/common"
"net"
)
type Transport interface {
Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error)
net.Conn
}
type AuthInfo struct {
UID []byte
SessionId uint32
ProxyMethod string
EncryptionMethod byte
Unordered bool
ServerPubKey crypto.PublicKey
MockDomain string
WorldState common.WorldState
}

View File

@ -1,21 +1,21 @@
package client package transports
import ( import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"net"
"net/http"
"net/url"
"github.com/cbeuw/Cloak/internal/common" "github.com/cbeuw/Cloak/internal/common"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
utls "github.com/refraction-networking/utls" utls "github.com/refraction-networking/utls"
"net"
"net/http"
"net/url"
) )
type WSOverTLS struct { type WSOverTLS struct {
*common.WebSocketConn *common.WebSocketConn
wsUrl string CDNHost string
CDNPort string
} }
func (ws *WSOverTLS) Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error) { func (ws *WSOverTLS) Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error) {
@ -41,7 +41,7 @@ func (ws *WSOverTLS) Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey
return return
} }
u, err := url.Parse(ws.wsUrl) u, err := url.Parse("ws://" + net.JoinHostPort(ws.CDNHost, ws.CDNPort))
if err != nil { if err != nil {
return sessionKey, fmt.Errorf("failed to parse ws url: %v", err) return sessionKey, fmt.Errorf("failed to parse ws url: %v", err)
} }