Add uTLS support for shadowtls

This commit is contained in:
世界 2023-02-21 20:42:44 +08:00
parent 6fb673aee4
commit 0188c2d67d
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
10 changed files with 55 additions and 31 deletions

View file

@ -5,12 +5,15 @@ import (
"crypto/tls"
"github.com/sagernet/sing-shadowtls"
sing_common "github.com/sagernet/sing/common"
utls "github.com/sagernet/utls"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/singbridge"
"github.com/xtls/xray-core/transport"
"github.com/xtls/xray-core/transport/internet"
internet_tls "github.com/xtls/xray-core/transport/internet/tls"
)
func init() {
@ -60,14 +63,14 @@ func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer int
var client *shadowtls.Client
clientConfig := o.clientConfig
if clientConfig.Version == 3 {
clientConfig.Dialer = singbridge.NewTLSDialer(dialer, func(conn net.Conn, config *tls.Config) net.Conn {
client.SetTLSConfig(config)
return conn
})
} else {
clientConfig.Dialer = singbridge.NewDialer(dialer)
}
clientConfig.Dialer = singbridge.NewTLSDialer(dialer, func(conn net.Conn, xrayConfig *internet_tls.Config, config *tls.Config) net.Conn {
if fingerprint := internet_tls.GetFingerprint(xrayConfig.Fingerprint); fingerprint != nil {
client.SetHandshakeFunc(uTLSHandshakeFunc(config, *fingerprint))
} else {
client.SetHandshakeFunc(shadowtls.DefaultTLSHandshakeFunc(clientConfig.Password, config))
}
return conn
})
var err error
client, err = shadowtls.NewClient(clientConfig)
if err != nil {
@ -81,3 +84,28 @@ func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer int
return singbridge.CopyConn(ctx, inboundConn, link, conn)
}
func uTLSHandshakeFunc(config *tls.Config, clientHelloID utls.ClientHelloID) shadowtls.TLSHandshakeFunc {
return func(ctx context.Context, conn net.Conn, sessionIDGenerator shadowtls.TLSSessionIDGeneratorFunc) error {
tlsConfig := &utls.Config{
Rand: config.Rand,
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,
}
tlsConn := utls.UClient(conn, tlsConfig, clientHelloID)
return tlsConn.HandshakeContext(ctx)
}
}