mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-05-24 10:58:15 +08:00
chore: update utls to 1.7.0
This commit is contained in:
parent
d5243adf89
commit
39d6a0d7ba
@ -19,7 +19,6 @@ import (
|
|||||||
shadowtls "github.com/metacubex/mihomo/transport/sing-shadowtls"
|
shadowtls "github.com/metacubex/mihomo/transport/sing-shadowtls"
|
||||||
v2rayObfs "github.com/metacubex/mihomo/transport/v2ray-plugin"
|
v2rayObfs "github.com/metacubex/mihomo/transport/v2ray-plugin"
|
||||||
|
|
||||||
restlsC "github.com/3andne/restls-client-go"
|
|
||||||
shadowsocks "github.com/metacubex/sing-shadowsocks2"
|
shadowsocks "github.com/metacubex/sing-shadowsocks2"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
@ -37,7 +36,7 @@ type ShadowSocks struct {
|
|||||||
v2rayOption *v2rayObfs.Option
|
v2rayOption *v2rayObfs.Option
|
||||||
gostOption *gost.Option
|
gostOption *gost.Option
|
||||||
shadowTLSOption *shadowtls.ShadowTLSOption
|
shadowTLSOption *shadowtls.ShadowTLSOption
|
||||||
restlsConfig *restlsC.Config
|
restlsConfig *restls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShadowSocksOption struct {
|
type ShadowSocksOption struct {
|
||||||
@ -265,7 +264,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
|||||||
var gostOption *gost.Option
|
var gostOption *gost.Option
|
||||||
var obfsOption *simpleObfsOption
|
var obfsOption *simpleObfsOption
|
||||||
var shadowTLSOpt *shadowtls.ShadowTLSOption
|
var shadowTLSOpt *shadowtls.ShadowTLSOption
|
||||||
var restlsConfig *restlsC.Config
|
var restlsConfig *restls.Config
|
||||||
obfsMode := ""
|
obfsMode := ""
|
||||||
|
|
||||||
decoder := structure.NewDecoder(structure.Option{TagName: "obfs", WeaklyTypedInput: true})
|
decoder := structure.NewDecoder(structure.Option{TagName: "obfs", WeaklyTypedInput: true})
|
||||||
@ -350,7 +349,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
|||||||
return nil, fmt.Errorf("ss %s initialize restls-plugin error: %w", addr, err)
|
return nil, fmt.Errorf("ss %s initialize restls-plugin error: %w", addr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
restlsConfig, err = restlsC.NewRestlsConfig(restlsOpt.Host, restlsOpt.Password, restlsOpt.VersionHint, restlsOpt.RestlsScript, option.ClientFingerprint)
|
restlsConfig, err = restls.NewRestlsConfig(restlsOpt.Host, restlsOpt.Password, restlsOpt.VersionHint, restlsOpt.RestlsScript, option.ClientFingerprint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ss %s initialize restls-plugin error: %w", addr, err)
|
return nil, fmt.Errorf("ss %s initialize restls-plugin error: %w", addr, err)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,17 @@ func Filter[T comparable](tSlice []T, filter func(t T) bool) []T {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Map[T any, N any](arr []T, block func(it T) N) []N {
|
||||||
|
if arr == nil { // keep nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
retArr := make([]N, 0, len(arr))
|
||||||
|
for index := range arr {
|
||||||
|
retArr = append(retArr, block(arr[index]))
|
||||||
|
}
|
||||||
|
return retArr
|
||||||
|
}
|
||||||
|
|
||||||
func ToStringSlice(value any) ([]string, error) {
|
func ToStringSlice(value any) ([]string, error) {
|
||||||
strArr := make([]string, 0)
|
strArr := make([]string, 0)
|
||||||
switch reflect.TypeOf(value).Kind() {
|
switch reflect.TypeOf(value).Kind() {
|
||||||
|
@ -111,11 +111,7 @@ func convertFingerprint(fingerprint string) (*[32]byte, error) {
|
|||||||
return (*[32]byte)(fpByte), nil
|
return (*[32]byte)(fpByte), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTLSConfig specified fingerprint, customCA and customCAString
|
func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error) {
|
||||||
func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, customCAString string) (*tls.Config, error) {
|
|
||||||
if tlsConfig == nil {
|
|
||||||
tlsConfig = &tls.Config{}
|
|
||||||
}
|
|
||||||
var certificate []byte
|
var certificate []byte
|
||||||
var err error
|
var err error
|
||||||
if len(customCA) > 0 {
|
if len(customCA) > 0 {
|
||||||
@ -131,17 +127,35 @@ func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, cu
|
|||||||
if !certPool.AppendCertsFromPEM(certificate) {
|
if !certPool.AppendCertsFromPEM(certificate) {
|
||||||
return nil, fmt.Errorf("failed to parse certificate:\n\n %s", certificate)
|
return nil, fmt.Errorf("failed to parse certificate:\n\n %s", certificate)
|
||||||
}
|
}
|
||||||
tlsConfig.RootCAs = certPool
|
return certPool, nil
|
||||||
} else {
|
} else {
|
||||||
tlsConfig.RootCAs = getCertPool()
|
return getCertPool(), nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFingerprintVerifier(fingerprint string) (func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error, error) {
|
||||||
|
fingerprintBytes, err := convertFingerprint(fingerprint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return verifyFingerprint(fingerprintBytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTLSConfig specified fingerprint, customCA and customCAString
|
||||||
|
func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, customCAString string) (_ *tls.Config, err error) {
|
||||||
|
if tlsConfig == nil {
|
||||||
|
tlsConfig = &tls.Config{}
|
||||||
|
}
|
||||||
|
tlsConfig.RootCAs, err = GetCertPool(customCA, customCAString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if len(fingerprint) > 0 {
|
if len(fingerprint) > 0 {
|
||||||
var fingerprintBytes *[32]byte
|
tlsConfig.VerifyPeerCertificate, err = NewFingerprintVerifier(fingerprint)
|
||||||
fingerprintBytes, err = convertFingerprint(fingerprint)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tlsConfig.VerifyPeerCertificate = verifyFingerprint(fingerprintBytes)
|
|
||||||
tlsConfig.InsecureSkipVerify = true
|
tlsConfig.InsecureSkipVerify = true
|
||||||
}
|
}
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
|
@ -4,15 +4,16 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/common/utils"
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
|
|
||||||
utls "github.com/metacubex/utls"
|
utls "github.com/metacubex/utls"
|
||||||
"github.com/mroth/weightedrand/v2"
|
"github.com/mroth/weightedrand/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UConn struct {
|
type UConn = utls.UConn
|
||||||
*utls.UConn
|
|
||||||
}
|
const VersionTLS13 = utls.VersionTLS13
|
||||||
|
|
||||||
type UClientHelloID struct {
|
type UClientHelloID struct {
|
||||||
*utls.ClientHelloID
|
*utls.ClientHelloID
|
||||||
@ -21,13 +22,8 @@ type UClientHelloID struct {
|
|||||||
var initRandomFingerprint UClientHelloID
|
var initRandomFingerprint UClientHelloID
|
||||||
var initUtlsClient string
|
var initUtlsClient string
|
||||||
|
|
||||||
func UClient(c net.Conn, config *tls.Config, fingerprint UClientHelloID) *UConn {
|
func UClient(c net.Conn, config *utls.Config, fingerprint UClientHelloID) *UConn {
|
||||||
utlsConn := utls.UClient(c, copyConfig(config), utls.ClientHelloID{
|
return utls.UClient(c, config, *fingerprint.ClientHelloID)
|
||||||
Client: fingerprint.Client,
|
|
||||||
Version: fingerprint.Version,
|
|
||||||
Seed: fingerprint.Seed,
|
|
||||||
})
|
|
||||||
return &UConn{UConn: utlsConn}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFingerprint(ClientFingerprint string) (UClientHelloID, bool) {
|
func GetFingerprint(ClientFingerprint string) (UClientHelloID, bool) {
|
||||||
@ -95,18 +91,43 @@ func init() {
|
|||||||
Fingerprints["randomized"] = UClientHelloID{&randomized}
|
Fingerprints["randomized"] = UClientHelloID{&randomized}
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyConfig(c *tls.Config) *utls.Config {
|
func UCertificates(it tls.Certificate) utls.Certificate {
|
||||||
|
return utls.Certificate{
|
||||||
|
Certificate: it.Certificate,
|
||||||
|
PrivateKey: it.PrivateKey,
|
||||||
|
SupportedSignatureAlgorithms: utils.Map(it.SupportedSignatureAlgorithms, func(it tls.SignatureScheme) utls.SignatureScheme {
|
||||||
|
return utls.SignatureScheme(it)
|
||||||
|
}),
|
||||||
|
OCSPStaple: it.OCSPStaple,
|
||||||
|
SignedCertificateTimestamps: it.SignedCertificateTimestamps,
|
||||||
|
Leaf: it.Leaf,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UConfig(config *tls.Config) *utls.Config {
|
||||||
return &utls.Config{
|
return &utls.Config{
|
||||||
RootCAs: c.RootCAs,
|
Rand: config.Rand,
|
||||||
ServerName: c.ServerName,
|
Time: config.Time,
|
||||||
InsecureSkipVerify: c.InsecureSkipVerify,
|
Certificates: utils.Map(config.Certificates, UCertificates),
|
||||||
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
VerifyPeerCertificate: config.VerifyPeerCertificate,
|
||||||
|
RootCAs: config.RootCAs,
|
||||||
|
NextProtos: config.NextProtos,
|
||||||
|
ServerName: config.ServerName,
|
||||||
|
InsecureSkipVerify: config.InsecureSkipVerify,
|
||||||
|
CipherSuites: config.CipherSuites,
|
||||||
|
MinVersion: config.MinVersion,
|
||||||
|
MaxVersion: config.MaxVersion,
|
||||||
|
CurvePreferences: utils.Map(config.CurvePreferences, func(it tls.CurveID) utls.CurveID {
|
||||||
|
return utls.CurveID(it)
|
||||||
|
}),
|
||||||
|
SessionTicketsDisabled: config.SessionTicketsDisabled,
|
||||||
|
Renegotiation: utls.RenegotiationSupport(config.Renegotiation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildWebsocketHandshakeState it will only send http/1.1 in its ALPN.
|
// BuildWebsocketHandshakeState it will only send http/1.1 in its ALPN.
|
||||||
// Copy from https://github.com/XTLS/Xray-core/blob/main/transport/internet/tls/tls.go
|
// Copy from https://github.com/XTLS/Xray-core/blob/main/transport/internet/tls/tls.go
|
||||||
func (c *UConn) BuildWebsocketHandshakeState() error {
|
func BuildWebsocketHandshakeState(c *UConn) error {
|
||||||
// Build the handshake state. This will apply every variable of the TLS of the
|
// Build the handshake state. This will apply every variable of the TLS of the
|
||||||
// fingerprint in the UConn
|
// fingerprint in the UConn
|
||||||
if err := c.BuildHandshakeState(); err != nil {
|
if err := c.BuildHandshakeState(); err != nil {
|
||||||
|
2
go.mod
2
go.mod
@ -32,7 +32,7 @@ require (
|
|||||||
github.com/metacubex/sing-vmess v0.1.14-0.20250228002636-abc39e113b82
|
github.com/metacubex/sing-vmess v0.1.14-0.20250228002636-abc39e113b82
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589
|
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589
|
||||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422
|
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422
|
||||||
github.com/metacubex/utls v1.6.8-alpha.6
|
github.com/metacubex/utls v1.7.0-alpha.1
|
||||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181
|
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181
|
||||||
github.com/miekg/dns v1.1.63
|
github.com/miekg/dns v1.1.63
|
||||||
github.com/mroth/weightedrand/v2 v2.1.0
|
github.com/mroth/weightedrand/v2 v2.1.0
|
||||||
|
4
go.sum
4
go.sum
@ -129,8 +129,8 @@ github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589 h1:Z6bNy0
|
|||||||
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589/go.mod h1:4NclTLIZuk+QkHVCGrP87rHi/y8YjgPytxTgApJNMhc=
|
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589/go.mod h1:4NclTLIZuk+QkHVCGrP87rHi/y8YjgPytxTgApJNMhc=
|
||||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422 h1:zGeQt3UyNydIVrMRB97AA5WsYEau/TyCnRtTf1yUmJY=
|
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422 h1:zGeQt3UyNydIVrMRB97AA5WsYEau/TyCnRtTf1yUmJY=
|
||||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||||
github.com/metacubex/utls v1.6.8-alpha.6 h1:5ZdZNiZFkKKgEcuPOOROIc8bA4dX2VJHoY3gajSnSaU=
|
github.com/metacubex/utls v1.7.0-alpha.1 h1:oMFsPh2oTlALJ7vKXPJuqgy0YeiZ+q/LLw+ZdxZ80l4=
|
||||||
github.com/metacubex/utls v1.6.8-alpha.6/go.mod h1:MEZ5WO/VLKYs/s/dOzEK/mlXOQxc04ESeLzRgjmLYtk=
|
github.com/metacubex/utls v1.7.0-alpha.1/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
|
||||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
||||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
||||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||||
|
@ -22,14 +22,13 @@ import (
|
|||||||
mihomoVMess "github.com/metacubex/mihomo/transport/vmess"
|
mihomoVMess "github.com/metacubex/mihomo/transport/vmess"
|
||||||
|
|
||||||
"github.com/metacubex/sing-vmess/vless"
|
"github.com/metacubex/sing-vmess/vless"
|
||||||
utls "github.com/metacubex/utls"
|
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
"github.com/sagernet/sing/common/metadata"
|
"github.com/sagernet/sing/common/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
vless.RegisterTLS(func(conn net.Conn) (loaded bool, netConn net.Conn, reflectType reflect.Type, reflectPointer unsafe.Pointer) {
|
vless.RegisterTLS(func(conn net.Conn) (loaded bool, netConn net.Conn, reflectType reflect.Type, reflectPointer unsafe.Pointer) {
|
||||||
tlsConn, loaded := common.Cast[*reality.Conn](conn)
|
tlsConn, loaded := common.Cast[*reality.Conn](conn) // *utls.Conn
|
||||||
if !loaded {
|
if !loaded {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -37,15 +36,7 @@ func init() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
vless.RegisterTLS(func(conn net.Conn) (loaded bool, netConn net.Conn, reflectType reflect.Type, reflectPointer unsafe.Pointer) {
|
vless.RegisterTLS(func(conn net.Conn) (loaded bool, netConn net.Conn, reflectType reflect.Type, reflectPointer unsafe.Pointer) {
|
||||||
tlsConn, loaded := common.Cast[*utls.UConn](conn)
|
tlsConn, loaded := common.Cast[*tlsC.UConn](conn) // *utls.UConn
|
||||||
if !loaded {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return true, tlsConn.NetConn(), reflect.TypeOf(tlsConn.Conn).Elem(), unsafe.Pointer(tlsConn.Conn)
|
|
||||||
})
|
|
||||||
|
|
||||||
vless.RegisterTLS(func(conn net.Conn) (loaded bool, netConn net.Conn, reflectType reflect.Type, reflectPointer unsafe.Pointer) {
|
|
||||||
tlsConn, loaded := common.Cast[*tlsC.UConn](conn)
|
|
||||||
if !loaded {
|
if !loaded {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ func NewHTTP2Client(dialFn DialFn, tlsConfig *tls.Config, clientFingerprint stri
|
|||||||
if len(clientFingerprint) != 0 {
|
if len(clientFingerprint) != 0 {
|
||||||
if realityConfig == nil {
|
if realityConfig == nil {
|
||||||
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
||||||
utlsConn := tlsC.UClient(pconn, cfg, fingerprint)
|
utlsConn := tlsC.UClient(pconn, tlsC.UConfig(cfg), fingerprint)
|
||||||
if err := utlsConn.HandshakeContext(ctx); err != nil {
|
if err := utlsConn.HandshakeContext(ctx); err != nil {
|
||||||
pconn.Close()
|
pconn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -19,8 +19,12 @@ func (r *Restls) Upstream() any {
|
|||||||
return r.UConn.NetConn()
|
return r.UConn.NetConn()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Config = tls.Config
|
||||||
|
|
||||||
|
var NewRestlsConfig = tls.NewRestlsConfig
|
||||||
|
|
||||||
// NewRestls return a Restls Connection
|
// NewRestls return a Restls Connection
|
||||||
func NewRestls(ctx context.Context, conn net.Conn, config *tls.Config) (net.Conn, error) {
|
func NewRestls(ctx context.Context, conn net.Conn, config *Config) (net.Conn, error) {
|
||||||
clientHellowID := tls.HelloChrome_Auto
|
clientHellowID := tls.HelloChrome_Auto
|
||||||
if config != nil {
|
if config != nil {
|
||||||
clientIDPtr := config.ClientID.Load()
|
clientIDPtr := config.ClientID.Load()
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
|
|
||||||
"github.com/metacubex/sing-shadowtls"
|
"github.com/metacubex/sing-shadowtls"
|
||||||
utls "github.com/metacubex/utls"
|
utls "github.com/metacubex/utls"
|
||||||
sing_common "github.com/sagernet/sing/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -60,32 +59,15 @@ func NewShadowTLS(ctx context.Context, conn net.Conn, option *ShadowTLSOption) (
|
|||||||
|
|
||||||
func uTLSHandshakeFunc(config *tls.Config, clientFingerprint string) shadowtls.TLSHandshakeFunc {
|
func uTLSHandshakeFunc(config *tls.Config, clientFingerprint string) shadowtls.TLSHandshakeFunc {
|
||||||
return func(ctx context.Context, conn net.Conn, sessionIDGenerator shadowtls.TLSSessionIDGeneratorFunc) error {
|
return func(ctx context.Context, conn net.Conn, sessionIDGenerator shadowtls.TLSSessionIDGeneratorFunc) error {
|
||||||
tlsConfig := &utls.Config{
|
tlsConfig := tlsC.UConfig(config)
|
||||||
Rand: config.Rand,
|
tlsConfig.SessionIDGenerator = sessionIDGenerator
|
||||||
Time: config.Time,
|
|
||||||
VerifyPeerCertificate: config.VerifyPeerCertificate,
|
|
||||||
RootCAs: config.RootCAs,
|
|
||||||
NextProtos: config.NextProtos,
|
|
||||||
ServerName: config.ServerName,
|
|
||||||
InsecureSkipVerify: config.InsecureSkipVerify,
|
|
||||||
CipherSuites: config.CipherSuites,
|
|
||||||
MinVersion: config.MinVersion,
|
|
||||||
MaxVersion: config.MaxVersion,
|
|
||||||
CurvePreferences: sing_common.Map(config.CurvePreferences, func(it tls.CurveID) utls.CurveID {
|
|
||||||
return utls.CurveID(it)
|
|
||||||
}),
|
|
||||||
SessionTicketsDisabled: config.SessionTicketsDisabled,
|
|
||||||
Renegotiation: utls.RenegotiationSupport(config.Renegotiation),
|
|
||||||
SessionIDGenerator: sessionIDGenerator,
|
|
||||||
}
|
|
||||||
clientFingerprint := clientFingerprint
|
clientFingerprint := clientFingerprint
|
||||||
if tlsC.HaveGlobalFingerprint() && len(clientFingerprint) == 0 {
|
if tlsC.HaveGlobalFingerprint() && len(clientFingerprint) == 0 {
|
||||||
clientFingerprint = tlsC.GetGlobalFingerprint()
|
clientFingerprint = tlsC.GetGlobalFingerprint()
|
||||||
}
|
}
|
||||||
if len(clientFingerprint) != 0 {
|
if len(clientFingerprint) != 0 {
|
||||||
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
||||||
clientHelloID := *fingerprint.ClientHelloID
|
tlsConn := tlsC.UClient(conn, tlsConfig, fingerprint)
|
||||||
tlsConn := utls.UClient(conn, tlsConfig, clientHelloID)
|
|
||||||
return tlsConn.HandshakeContext(ctx)
|
return tlsConn.HandshakeContext(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,10 @@ import (
|
|||||||
|
|
||||||
"github.com/metacubex/mihomo/common/buf"
|
"github.com/metacubex/mihomo/common/buf"
|
||||||
N "github.com/metacubex/mihomo/common/net"
|
N "github.com/metacubex/mihomo/common/net"
|
||||||
|
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
|
|
||||||
"github.com/gofrs/uuid/v5"
|
"github.com/gofrs/uuid/v5"
|
||||||
utls "github.com/metacubex/utls"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -187,8 +187,8 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) {
|
|||||||
buffer.Release()
|
buffer.Release()
|
||||||
return ErrNotTLS13
|
return ErrNotTLS13
|
||||||
}
|
}
|
||||||
case *utls.UConn:
|
case *tlsC.UConn:
|
||||||
if underlying.ConnectionState().Version != utls.VersionTLS13 {
|
if underlying.ConnectionState().Version != tlsC.VersionTLS13 {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return ErrNotTLS13
|
return ErrNotTLS13
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||||
|
|
||||||
"github.com/gofrs/uuid/v5"
|
"github.com/gofrs/uuid/v5"
|
||||||
utls "github.com/metacubex/utls"
|
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,16 +45,10 @@ func NewConn(conn connWithUpstream, userUUID *uuid.UUID) (*Conn, error) {
|
|||||||
c.tlsConn = underlying
|
c.tlsConn = underlying
|
||||||
t = reflect.TypeOf(underlying).Elem()
|
t = reflect.TypeOf(underlying).Elem()
|
||||||
p = unsafe.Pointer(underlying)
|
p = unsafe.Pointer(underlying)
|
||||||
case *utls.UConn:
|
|
||||||
//log.Debugln("type *utls.UConn")
|
|
||||||
c.Conn = underlying.NetConn()
|
|
||||||
c.tlsConn = underlying
|
|
||||||
t = reflect.TypeOf(underlying.Conn).Elem()
|
|
||||||
p = unsafe.Pointer(underlying.Conn)
|
|
||||||
case *tlsC.UConn:
|
case *tlsC.UConn:
|
||||||
//log.Debugln("type *tlsC.UConn")
|
//log.Debugln("type *tlsC.UConn")
|
||||||
c.Conn = underlying.NetConn()
|
c.Conn = underlying.NetConn()
|
||||||
c.tlsConn = underlying.UConn
|
c.tlsConn = underlying
|
||||||
t = reflect.TypeOf(underlying.Conn).Elem()
|
t = reflect.TypeOf(underlying.Conn).Elem()
|
||||||
//log.Debugln("t:%v", t)
|
//log.Debugln("t:%v", t)
|
||||||
p = unsafe.Pointer(underlying.Conn)
|
p = unsafe.Pointer(underlying.Conn)
|
||||||
|
@ -39,7 +39,7 @@ func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn
|
|||||||
if len(clientFingerprint) != 0 {
|
if len(clientFingerprint) != 0 {
|
||||||
if cfg.Reality == nil {
|
if cfg.Reality == nil {
|
||||||
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
||||||
utlsConn := tlsC.UClient(conn, tlsConfig, fingerprint)
|
utlsConn := tlsC.UClient(conn, tlsC.UConfig(tlsConfig), fingerprint)
|
||||||
err = utlsConn.HandshakeContext(ctx)
|
err = utlsConn.HandshakeContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -360,8 +360,8 @@ func streamWebsocketConn(ctx context.Context, conn net.Conn, c *WebsocketConfig,
|
|||||||
}
|
}
|
||||||
if len(clientFingerprint) != 0 {
|
if len(clientFingerprint) != 0 {
|
||||||
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
if fingerprint, exists := tlsC.GetFingerprint(clientFingerprint); exists {
|
||||||
utlsConn := tlsC.UClient(conn, config, fingerprint)
|
utlsConn := tlsC.UClient(conn, tlsC.UConfig(config), fingerprint)
|
||||||
if err = utlsConn.BuildWebsocketHandshakeState(); err != nil {
|
if err = tlsC.BuildWebsocketHandshakeState(utlsConn); err != nil {
|
||||||
return nil, fmt.Errorf("parse url %s error: %w", c.Path, err)
|
return nil, fmt.Errorf("parse url %s error: %w", c.Path, err)
|
||||||
}
|
}
|
||||||
conn = utlsConn
|
conn = utlsConn
|
||||||
|
Loading…
Reference in New Issue
Block a user