mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-15 01:09:20 +02:00
Add uTLS support for shadowtls
This commit is contained in:
parent
6fb673aee4
commit
0188c2d67d
|
@ -22,8 +22,10 @@ func NewTLSDialer(dialer internet.Dialer, clientFunc tls.CustomClientFunc) *Xray
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *XrayTLSDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
func (d *XrayTLSDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||||
|
var internetTLSConfig *tls.Config
|
||||||
var tlsConfig *gotls.Config
|
var tlsConfig *gotls.Config
|
||||||
conn, err := d.dialer.Dial(tls.ContextWithCustomClient(ctx, func(conn net.Conn, config *gotls.Config) net.Conn {
|
conn, err := d.dialer.Dial(tls.ContextWithCustomClient(ctx, func(conn net.Conn, xrayConfig *tls.Config, config *gotls.Config) net.Conn {
|
||||||
|
internetTLSConfig = xrayConfig
|
||||||
tlsConfig = config
|
tlsConfig = config
|
||||||
return conn
|
return conn
|
||||||
}), ToDestination(destination, ToNetwork(network)))
|
}), ToDestination(destination, ToNetwork(network)))
|
||||||
|
@ -33,7 +35,7 @@ func (d *XrayTLSDialer) DialContext(ctx context.Context, network string, destina
|
||||||
if tlsConfig == nil {
|
if tlsConfig == nil {
|
||||||
return nil, E.New("missing TLS config")
|
return nil, E.New("missing TLS config")
|
||||||
}
|
}
|
||||||
return d.clientFunc(conn, tlsConfig), nil
|
return d.clientFunc(conn, internetTLSConfig, tlsConfig), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *XrayTLSDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
func (d *XrayTLSDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -12,10 +12,10 @@ require (
|
||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/pires/go-proxyproto v0.6.2
|
github.com/pires/go-proxyproto v0.6.2
|
||||||
github.com/quic-go/quic-go v0.32.0
|
github.com/quic-go/quic-go v0.32.0
|
||||||
github.com/refraction-networking/utls v1.2.2
|
|
||||||
github.com/sagernet/sing v0.1.6
|
github.com/sagernet/sing v0.1.6
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7
|
github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221100347-75f55ea45b99
|
github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587
|
||||||
|
github.com/sagernet/utls v0.0.0-20230220130002-c08891932056
|
||||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c
|
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
|
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
|
||||||
github.com/stretchr/testify v1.8.1
|
github.com/stretchr/testify v1.8.1
|
||||||
|
@ -34,7 +34,7 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
||||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||||
|
|
18
go.sum
18
go.sum
|
@ -8,8 +8,8 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1
|
||||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||||
|
@ -138,8 +138,6 @@ github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV5
|
||||||
github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
||||||
github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA=
|
github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA=
|
||||||
github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo=
|
github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo=
|
||||||
github.com/refraction-networking/utls v1.2.2 h1:uBE6V173CwG8MQrSBpNZHAix1fxOvuLKYyjFAu3uqo0=
|
|
||||||
github.com/refraction-networking/utls v1.2.2/go.mod h1:L1goe44KvhnTfctUffM2isnJpSjPlYShrhXDeZaoYKw=
|
|
||||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
@ -147,14 +145,10 @@ github.com/sagernet/sing v0.1.6 h1:Qy63OUfKpcqKjfd5rPmUlj0RGjHZSK/PJn0duyCCsRg=
|
||||||
github.com/sagernet/sing v0.1.6/go.mod h1:JLSXsPTGRJFo/3X7EcAOCUgJH2/gAoxSJgBsnCZRp/w=
|
github.com/sagernet/sing v0.1.6/go.mod h1:JLSXsPTGRJFo/3X7EcAOCUgJH2/gAoxSJgBsnCZRp/w=
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7 h1:Plup6oEiyLzY3HDqQ+QsUBzgBGdVmcsgf3t8h940z9U=
|
github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7 h1:Plup6oEiyLzY3HDqQ+QsUBzgBGdVmcsgf3t8h940z9U=
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7/go.mod h1:O5LtOs8Ivw686FqLpO0Zu+A0ROVE15VeqEK3yDRRAms=
|
github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7/go.mod h1:O5LtOs8Ivw686FqLpO0Zu+A0ROVE15VeqEK3yDRRAms=
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221081357-574313aaae1d h1:yETevmRbJ6Mf9xgavSmgxo9UCdKNyplU4ubgFXqd4XU=
|
github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 h1:OjIXlHT2bblZfp+ciupM4xY9+Ccpj9FsuHRtKRBv+Pg=
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221081357-574313aaae1d/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221093358-af0356df4755 h1:5/GdWkRlHv00+4JrIy0ilWAw2p/EWtuH0CClC2/gko4=
|
github.com/sagernet/utls v0.0.0-20230220130002-c08891932056 h1:gDXi/0uYe8dA48UyUI1LM2la5QYN0IvsDvR2H2+kFnA=
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221093358-af0356df4755/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
github.com/sagernet/utls v0.0.0-20230220130002-c08891932056/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM=
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221100347-75f55ea45b99 h1:LhGnlaH8bV0MCNp/LW4PDPagtkJDSAX0ftN9bJ6HMxY=
|
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221100347-75f55ea45b99/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221110738-214729669cdc h1:T1XsW+0eNGlyy7NXY8AG2pE3d+RsdphRCH5ux0jjWf4=
|
|
||||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221110738-214729669cdc/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
|
||||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo=
|
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo=
|
||||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI=
|
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI=
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
|
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
|
||||||
|
|
|
@ -5,12 +5,15 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
|
||||||
"github.com/sagernet/sing-shadowtls"
|
"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"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/session"
|
"github.com/xtls/xray-core/common/session"
|
||||||
"github.com/xtls/xray-core/common/singbridge"
|
"github.com/xtls/xray-core/common/singbridge"
|
||||||
"github.com/xtls/xray-core/transport"
|
"github.com/xtls/xray-core/transport"
|
||||||
"github.com/xtls/xray-core/transport/internet"
|
"github.com/xtls/xray-core/transport/internet"
|
||||||
|
internet_tls "github.com/xtls/xray-core/transport/internet/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -60,14 +63,14 @@ func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer int
|
||||||
|
|
||||||
var client *shadowtls.Client
|
var client *shadowtls.Client
|
||||||
clientConfig := o.clientConfig
|
clientConfig := o.clientConfig
|
||||||
if clientConfig.Version == 3 {
|
clientConfig.Dialer = singbridge.NewTLSDialer(dialer, func(conn net.Conn, xrayConfig *internet_tls.Config, config *tls.Config) net.Conn {
|
||||||
clientConfig.Dialer = singbridge.NewTLSDialer(dialer, func(conn net.Conn, config *tls.Config) net.Conn {
|
if fingerprint := internet_tls.GetFingerprint(xrayConfig.Fingerprint); fingerprint != nil {
|
||||||
client.SetTLSConfig(config)
|
client.SetHandshakeFunc(uTLSHandshakeFunc(config, *fingerprint))
|
||||||
|
} else {
|
||||||
|
client.SetHandshakeFunc(shadowtls.DefaultTLSHandshakeFunc(clientConfig.Password, config))
|
||||||
|
}
|
||||||
return conn
|
return conn
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
clientConfig.Dialer = singbridge.NewDialer(dialer)
|
|
||||||
}
|
|
||||||
var err error
|
var err error
|
||||||
client, err = shadowtls.NewClient(clientConfig)
|
client, err = shadowtls.NewClient(clientConfig)
|
||||||
if err != nil {
|
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)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
utls "github.com/refraction-networking/utls"
|
utls "github.com/sagernet/utls"
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
utls "github.com/refraction-networking/utls"
|
utls "github.com/sagernet/utls"
|
||||||
"github.com/xtls/reality"
|
"github.com/xtls/reality"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
|
|
|
@ -25,7 +25,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
||||||
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
|
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
|
||||||
customClient, loaded := tls.CustomClientFromContext(ctx)
|
customClient, loaded := tls.CustomClientFromContext(ctx)
|
||||||
if loaded {
|
if loaded {
|
||||||
conn = customClient(conn, tlsConfig)
|
conn = customClient(conn, config, tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
if fingerprint := tls.GetFingerprint(config.Fingerprint); fingerprint != nil {
|
if fingerprint := tls.GetFingerprint(config.Fingerprint); fingerprint != nil {
|
||||||
conn = tls.UClient(conn, tlsConfig, fingerprint)
|
conn = tls.UClient(conn, tlsConfig, fingerprint)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type customClientKey struct{}
|
type customClientKey struct{}
|
||||||
|
|
||||||
type CustomClientFunc func(conn net.Conn, config *tls.Config) net.Conn
|
type CustomClientFunc func(conn net.Conn, xrayConfig *Config, config *tls.Config) net.Conn
|
||||||
|
|
||||||
func CustomClientFromContext(ctx context.Context) (CustomClientFunc, bool) {
|
func CustomClientFromContext(ctx context.Context) (CustomClientFunc, bool) {
|
||||||
client, loaded := ctx.Value(customClientKey{}).(CustomClientFunc)
|
client, loaded := ctx.Value(customClientKey{}).(CustomClientFunc)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
utls "github.com/refraction-networking/utls"
|
utls "github.com/sagernet/utls"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
utls "github.com/refraction-networking/utls"
|
utls "github.com/sagernet/utls"
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue