From 57279cd97197f6073df2e875344c5a50d7e08fd1 Mon Sep 17 00:00:00 2001 From: gVisor bot Date: Tue, 7 Feb 2023 16:08:59 +0800 Subject: [PATCH] chore: move global-utls-client snippets to components\tls --- adapter/outbound/trojan.go | 5 +-- adapter/outbound/vless.go | 4 +- adapter/outbound/vmess.go | 4 +- adapter/parser.go | 9 +++-- {transport/vmess => component/tls}/utls.go | 44 +++++++++++++--------- config/config.go | 5 ++- transport/gun/gun.go | 16 +++----- transport/trojan/trojan.go | 2 +- transport/vmess/tls.go | 12 ++---- transport/vmess/websocket.go | 13 +++---- 10 files changed, 56 insertions(+), 58 deletions(-) rename {transport/vmess => component/tls}/utls.go (90%) diff --git a/adapter/outbound/trojan.go b/adapter/outbound/trojan.go index 5fe946b0..2a8cfe47 100644 --- a/adapter/outbound/trojan.go +++ b/adapter/outbound/trojan.go @@ -15,7 +15,6 @@ import ( "github.com/Dreamacro/clash/transport/gun" "github.com/Dreamacro/clash/transport/trojan" "github.com/Dreamacro/clash/transport/vless" - "github.com/Dreamacro/clash/transport/vmess" ) type Trojan struct { @@ -79,8 +78,8 @@ func (t *Trojan) plainStream(c net.Conn) (net.Conn, error) { func (t *Trojan) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { var err error - if vmess.HaveGlobalFingerprint() && len(t.option.ClientFingerprint) == 0 { - t.option.ClientFingerprint = vmess.GetGlobalFingerprint() + if tlsC.HaveGlobalFingerprint() && len(t.option.ClientFingerprint) == 0 { + t.option.ClientFingerprint = tlsC.GetGlobalFingerprint() } if t.transport != nil { diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index 0550fd7a..e46e245d 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -72,8 +72,8 @@ type VlessOption struct { func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { var err error - if vmess.HaveGlobalFingerprint() && len(v.option.ClientFingerprint) == 0 { - v.option.ClientFingerprint = vmess.GetGlobalFingerprint() + if tlsC.HaveGlobalFingerprint() && len(v.option.ClientFingerprint) == 0 { + v.option.ClientFingerprint = tlsC.GetGlobalFingerprint() } switch v.option.Network { diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index a2dff6ee..5da8c8b1 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -88,8 +88,8 @@ type WSOptions struct { func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { var err error - if clashVMess.HaveGlobalFingerprint() && (len(v.option.ClientFingerprint) == 0) { - v.option.ClientFingerprint = clashVMess.GetGlobalFingerprint() + if tlsC.HaveGlobalFingerprint() && (len(v.option.ClientFingerprint) == 0) { + v.option.ClientFingerprint = tlsC.GetGlobalFingerprint() } switch v.option.Network { diff --git a/adapter/parser.go b/adapter/parser.go index 97663540..d9c18694 100644 --- a/adapter/parser.go +++ b/adapter/parser.go @@ -3,10 +3,11 @@ package adapter import ( "fmt" + tlsC "github.com/Dreamacro/clash/component/tls" + "github.com/Dreamacro/clash/adapter/outbound" "github.com/Dreamacro/clash/common/structure" C "github.com/Dreamacro/clash/constant" - "github.com/Dreamacro/clash/transport/vmess" ) func ParseProxy(mapping map[string]any) (C.Proxy, error) { @@ -57,7 +58,7 @@ func ParseProxy(mapping map[string]any) (C.Proxy, error) { }, } - if GlobalUtlsClient := vmess.GetGlobalFingerprint(); len(GlobalUtlsClient) != 0 { + if GlobalUtlsClient := tlsC.GetGlobalFingerprint(); len(GlobalUtlsClient) != 0 { vmessOption.ClientFingerprint = GlobalUtlsClient } @@ -69,7 +70,7 @@ func ParseProxy(mapping map[string]any) (C.Proxy, error) { case "vless": vlessOption := &outbound.VlessOption{} - if GlobalUtlsClient := vmess.GetGlobalFingerprint(); len(GlobalUtlsClient) != 0 { + if GlobalUtlsClient := tlsC.GetGlobalFingerprint(); len(GlobalUtlsClient) != 0 { vlessOption.ClientFingerprint = GlobalUtlsClient } @@ -88,7 +89,7 @@ func ParseProxy(mapping map[string]any) (C.Proxy, error) { case "trojan": trojanOption := &outbound.TrojanOption{} - if GlobalUtlsClient := vmess.GetGlobalFingerprint(); len(GlobalUtlsClient) != 0 { + if GlobalUtlsClient := tlsC.GetGlobalFingerprint(); len(GlobalUtlsClient) != 0 { trojanOption.ClientFingerprint = GlobalUtlsClient } diff --git a/transport/vmess/utls.go b/component/tls/utls.go similarity index 90% rename from transport/vmess/utls.go rename to component/tls/utls.go index cae7d52f..ed35bd99 100644 --- a/transport/vmess/utls.go +++ b/component/tls/utls.go @@ -1,4 +1,4 @@ -package vmess +package tls import ( "crypto/tls" @@ -14,29 +14,22 @@ type UConn struct { *utls.UConn } +type UClientHelloID struct { + *utls.ClientHelloID +} + var initRandomFingerprint *utls.ClientHelloID var initUtlsClient string -func UClient(c net.Conn, config *tls.Config, fingerprint *utls.ClientHelloID) net.Conn { - utlsConn := utls.UClient(c, CopyConfig(config), *fingerprint) +func UClient(c net.Conn, config *tls.Config, fingerprint *UClientHelloID) net.Conn { + utlsConn := utls.UClient(c, CopyConfig(config), utls.ClientHelloID{ + Client: fingerprint.Client, + Version: fingerprint.Version, + Seed: fingerprint.Seed, + }) return &UConn{UConn: utlsConn} } -func SetGlobalUtlsClient(Client string) { - initUtlsClient = Client -} - -func HaveGlobalFingerprint() bool { - if len(initUtlsClient) != 0 && initUtlsClient != "none" { - return true - } - return false -} - -func GetGlobalFingerprint() string { - return initUtlsClient -} - func GetFingerprint(ClientFingerprint string) (*utls.ClientHelloID, bool) { if ClientFingerprint == "none" { return nil, false @@ -113,3 +106,18 @@ func (c *UConn) WebsocketHandshake() error { } return c.Handshake() } + +func SetGlobalUtlsClient(Client string) { + initUtlsClient = Client +} + +func HaveGlobalFingerprint() bool { + if len(initUtlsClient) != 0 && initUtlsClient != "none" { + return true + } + return false +} + +func GetGlobalFingerprint() string { + return initUtlsClient +} diff --git a/config/config.go b/config/config.go index be2e49cf..ac6ddda7 100644 --- a/config/config.go +++ b/config/config.go @@ -4,6 +4,7 @@ import ( "container/list" "errors" "fmt" + "net" "net/netip" "net/url" @@ -26,6 +27,7 @@ import ( "github.com/Dreamacro/clash/component/geodata/router" P "github.com/Dreamacro/clash/component/process" SNIFF "github.com/Dreamacro/clash/component/sniffer" + tlsC "github.com/Dreamacro/clash/component/tls" "github.com/Dreamacro/clash/component/trie" C "github.com/Dreamacro/clash/constant" providerTypes "github.com/Dreamacro/clash/constant/provider" @@ -36,7 +38,6 @@ import ( "github.com/Dreamacro/clash/log" R "github.com/Dreamacro/clash/rules" RP "github.com/Dreamacro/clash/rules/provider" - "github.com/Dreamacro/clash/transport/vmess" T "github.com/Dreamacro/clash/tunnel" "gopkg.in/yaml.v3" @@ -523,7 +524,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { if len(config.General.GlobalClientFingerprint) != 0 { log.Debugln("GlobalClientFingerprint:%s", config.General.GlobalClientFingerprint) - vmess.SetGlobalUtlsClient(config.General.GlobalClientFingerprint) + tlsC.SetGlobalUtlsClient(config.General.GlobalClientFingerprint) } return config, nil diff --git a/transport/gun/gun.go b/transport/gun/gun.go index a176e8fb..8c096861 100644 --- a/transport/gun/gun.go +++ b/transport/gun/gun.go @@ -19,9 +19,7 @@ import ( "github.com/Dreamacro/clash/common/buf" "github.com/Dreamacro/clash/common/pool" - U "github.com/Dreamacro/clash/transport/vmess" - utls "github.com/refraction-networking/utls" - + tlsC "github.com/Dreamacro/clash/component/tls" "go.uber.org/atomic" "golang.org/x/net/http2" ) @@ -203,17 +201,15 @@ func NewHTTP2Client(dialFn DialFn, tlsConfig *tls.Config, Fingerprint string) *T wrap.remoteAddr = pconn.RemoteAddr() if len(Fingerprint) != 0 { - if fingerprint, exists := U.GetFingerprint(Fingerprint); exists { - utlsConn := U.UClient(pconn, cfg, &utls.ClientHelloID{ - Client: fingerprint.Client, - Version: fingerprint.Version, - Seed: nil, + if fingerprint, exists := tlsC.GetFingerprint(Fingerprint); exists { + utlsConn := tlsC.UClient(pconn, cfg, &tlsC.UClientHelloID{ + ClientHelloID: fingerprint, }) - if err := utlsConn.(*U.UConn).HandshakeContext(ctx); err != nil { + if err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx); err != nil { pconn.Close() return nil, err } - state := utlsConn.(*U.UConn).ConnectionState() + state := utlsConn.(*tlsC.UConn).ConnectionState() if p := state.NegotiatedProtocol; p != http2.NextProtoTLS { utlsConn.Close() return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http2.NextProtoTLS) diff --git a/transport/trojan/trojan.go b/transport/trojan/trojan.go index 235d4d38..e336d9db 100644 --- a/transport/trojan/trojan.go +++ b/transport/trojan/trojan.go @@ -122,7 +122,7 @@ func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) { ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) defer cancel() - err := utlsConn.(*vmess.UConn).HandshakeContext(ctx) + err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx) return utlsConn, err } diff --git a/transport/vmess/tls.go b/transport/vmess/tls.go index 7dbde61b..27924ccc 100644 --- a/transport/vmess/tls.go +++ b/transport/vmess/tls.go @@ -7,8 +7,6 @@ import ( tlsC "github.com/Dreamacro/clash/component/tls" C "github.com/Dreamacro/clash/constant" - - utls "github.com/refraction-networking/utls" ) type TLSConfig struct { @@ -41,7 +39,7 @@ func StreamTLSConn(conn net.Conn, cfg *TLSConfig) (net.Conn, error) { ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) defer cancel() - err := utlsConn.(*UConn).HandshakeContext(ctx) + err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx) return utlsConn, err } } @@ -56,11 +54,9 @@ func StreamTLSConn(conn net.Conn, cfg *TLSConfig) (net.Conn, error) { func GetUtlsConnWithClientFingerprint(conn net.Conn, ClientFingerprint string, tlsConfig *tls.Config) (net.Conn, bool) { - if fingerprint, exists := GetFingerprint(ClientFingerprint); exists { - utlsConn := UClient(conn, tlsConfig, &utls.ClientHelloID{ - Client: fingerprint.Client, - Version: fingerprint.Version, - Seed: nil, + if fingerprint, exists := tlsC.GetFingerprint(ClientFingerprint); exists { + utlsConn := tlsC.UClient(conn, tlsConfig, &tlsC.UClientHelloID{ + ClientHelloID: fingerprint, }) return utlsConn, true diff --git a/transport/vmess/websocket.go b/transport/vmess/websocket.go index a7ca82b3..d56cf07c 100644 --- a/transport/vmess/websocket.go +++ b/transport/vmess/websocket.go @@ -21,9 +21,8 @@ import ( "github.com/Dreamacro/clash/common/buf" N "github.com/Dreamacro/clash/common/net" + tlsC "github.com/Dreamacro/clash/component/tls" "github.com/gorilla/websocket" - - utls "github.com/refraction-networking/utls" ) type websocketConn struct { @@ -334,15 +333,13 @@ func streamWebsocketConn(conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buf scheme = "wss" dialer.TLSClientConfig = c.TLSConfig if len(c.ClientFingerprint) != 0 { - if fingerprint, exists := GetFingerprint(c.ClientFingerprint); exists { + if fingerprint, exists := tlsC.GetFingerprint(c.ClientFingerprint); exists { dialer.NetDialTLSContext = func(_ context.Context, _, addr string) (net.Conn, error) { - utlsConn := UClient(conn, c.TLSConfig, &utls.ClientHelloID{ - Client: fingerprint.Client, - Version: fingerprint.Version, - Seed: fingerprint.Seed, + utlsConn := tlsC.UClient(conn, c.TLSConfig, &tlsC.UClientHelloID{ + ClientHelloID: fingerprint, }) - if err := utlsConn.(*UConn).WebsocketHandshake(); err != nil { + if err := utlsConn.(*tlsC.UConn).WebsocketHandshake(); err != nil { return nil, fmt.Errorf("parse url %s error: %w", c.Path, err) } return utlsConn, nil