Add quic fingerprints and preset configs

This commit is contained in:
yuhan6665 2024-11-02 13:51:40 -04:00
parent 0b7a5086a2
commit 091725fd5d
3 changed files with 63 additions and 3 deletions

View file

@ -120,6 +120,15 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
}, },
} }
transport = roundTripper transport = roundTripper
if fingerprint := tls.GetQuicFingerprint(tlsConfigs.Fingerprint); fingerprint != nil {
quicSpec, err := quic.QUICID2Spec(*fingerprint)
if err != nil {
errors.LogError(ctx, "unknown fingerprint: ", tlsConfigs.Fingerprint)
} else {
transport = http3.GetURoundTripper(roundTripper, &quicSpec, nil)
}
}
} else { } else {
transportH2 := &http2.Transport{ transportH2 := &http2.Transport{
DialTLSContext: func(hctx context.Context, string, addr string, tlsConfig *gotls.Config) (net.Conn, error) { DialTLSContext: func(hctx context.Context, string, addr string, tlsConfig *gotls.Config) (net.Conn, error) {

View file

@ -73,7 +73,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
} }
muxManager = NewMuxManager(mux, func() interface{} { muxManager = NewMuxManager(mux, func() interface{} {
return createHTTPClient(dest, streamSettings) return createHTTPClient(ctx, dest, streamSettings)
}) })
globalDialerMap[key] = muxManager globalDialerMap[key] = muxManager
} }
@ -82,7 +82,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
return res.Resource.(DialerClient), res return res.Resource.(DialerClient), res
} }
func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) DialerClient { func createHTTPClient(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) DialerClient {
tlsConfig := tls.ConfigFromStreamSettings(streamSettings) tlsConfig := tls.ConfigFromStreamSettings(streamSettings)
realityConfig := reality.ConfigFromStreamSettings(streamSettings) realityConfig := reality.ConfigFromStreamSettings(streamSettings)
@ -145,7 +145,7 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
MaxIncomingStreams: -1, MaxIncomingStreams: -1,
KeepAlivePeriod: h3KeepalivePeriod, KeepAlivePeriod: h3KeepalivePeriod,
} }
transport = &http3.RoundTripper{ roundTripper := &http3.RoundTripper{
QuicConfig: quicConfig, QuicConfig: quicConfig,
TLSClientConfig: tls.CopyConfig(gotlsConfig), TLSClientConfig: tls.CopyConfig(gotlsConfig),
Dial: func(ctx context.Context, addr string, tlsCfg *utls.Config, cfg *quic.Config) (quic.EarlyConnection, error) { Dial: func(ctx context.Context, addr string, tlsCfg *utls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
@ -185,6 +185,15 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
return quic.DialEarly(ctx, udpConn, udpAddr, tlsCfg, cfg) return quic.DialEarly(ctx, udpConn, udpAddr, tlsCfg, cfg)
}, },
} }
transport = roundTripper
if fingerprint := tls.GetQuicFingerprint(tlsConfig.Fingerprint); fingerprint != nil {
quicSpec, err := quic.QUICID2Spec(*fingerprint)
if err != nil {
errors.LogError(ctx, "unknown fingerprint: ", tlsConfig.Fingerprint)
} else {
transport = http3.GetURoundTripper(roundTripper, &quicSpec, nil)
}
}
} else if isH2 { } else if isH2 {
transport = &http2.Transport{ transport = &http2.Transport{
DialTLSContext: func(ctxInner context.Context, network string, addr string, cfg *gotls.Config) (net.Conn, error) { DialTLSContext: func(ctxInner context.Context, network string, addr string, cfg *gotls.Config) (net.Conn, error) {

View file

@ -7,6 +7,7 @@ import (
"math/big" "math/big"
"time" "time"
"github.com/refraction-networking/uquic"
utls "github.com/refraction-networking/utls" utls "github.com/refraction-networking/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"
@ -154,6 +155,18 @@ func init() {
} }
i++ i++
} }
bigInt, _ = rand.Int(rand.Reader, big.NewInt(int64(len(QuicAllFingerprints))))
stopAt = int(bigInt.Int64())
i = 0
for _, v := range QuicAllFingerprints {
if i == stopAt {
QuicPresetFingerprints["random"] = v
break
}
i++
}
weights := utls.DefaultWeights weights := utls.DefaultWeights
weights.TLSVersMax_Set_VersionTLS13 = 1 weights.TLSVersMax_Set_VersionTLS13 = 1
weights.FirstKeyShare_Set_CurveP256 = 0 weights.FirstKeyShare_Set_CurveP256 = 0
@ -179,6 +192,35 @@ func GetFingerprint(name string) (fingerprint *utls.ClientHelloID) {
return return
} }
func GetQuicFingerprint(name string) (fingerprint *quic.QUICID) {
if name == "" {
return
}
if fingerprint = QuicPresetFingerprints[name]; fingerprint != nil {
return
}
if fingerprint = QuicAllFingerprints[name]; fingerprint != nil {
return
}
return
}
var QuicPresetFingerprints = map[string]*quic.QUICID {
"chrome": &quic.QUICChrome_115,
"firefox": &quic.QUICFirefox_116,
"random": nil,
}
var QuicAllFingerprints = map[string]*quic.QUICID {
"quicchrome_115": &quic.QUICChrome_115,
"quicchrome_115_ipv4": &quic.QUICChrome_115_IPv4,
"quicchrome_115_ipv6": &quic.QUICChrome_115_IPv6,
"quicfirefox_116": &quic.QUICFirefox_116,
"quicfirefox_116a": &quic.QUICFirefox_116A,
"quicfirefox_116b": &quic.QUICFirefox_116B,
"quicfirefox_116c": &quic.QUICFirefox_116C,
}
var PresetFingerprints = map[string]*utls.ClientHelloID{ var PresetFingerprints = map[string]*utls.ClientHelloID{
// Recommended preset options in GUI clients // Recommended preset options in GUI clients
"chrome": &utls.HelloChrome_Auto, "chrome": &utls.HelloChrome_Auto,