mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-02-26 16:57:08 +00:00
chore: simplify gun code
This commit is contained in:
@@ -27,7 +27,7 @@ type Trojan struct {
|
|||||||
hexPassword [trojan.KeyLength]byte
|
hexPassword [trojan.KeyLength]byte
|
||||||
|
|
||||||
// for gun mux
|
// for gun mux
|
||||||
gunTLSConfig *tls.Config
|
gunTLSConfig *vmess.TLSConfig
|
||||||
gunConfig *gun.Config
|
gunConfig *gun.Config
|
||||||
transport *gun.TransportWrap
|
transport *gun.TransportWrap
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.
|
|||||||
|
|
||||||
c, err = vmess.StreamWebsocketConn(ctx, c, wsOpts)
|
c, err = vmess.StreamWebsocketConn(ctx, c, wsOpts)
|
||||||
case "grpc":
|
case "grpc":
|
||||||
c, err = gun.StreamGunWithConn(c, t.gunTLSConfig, t.gunConfig, t.echConfig, t.realityConfig)
|
c, err = gun.StreamGunWithConn(c, t.gunTLSConfig, t.gunConfig)
|
||||||
default:
|
default:
|
||||||
// default tcp network
|
// default tcp network
|
||||||
// handle TLS
|
// handle TLS
|
||||||
@@ -336,29 +336,25 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
tlsConfig := &vmess.TLSConfig{
|
||||||
TLSConfig: &tls.Config{
|
Host: option.SNI,
|
||||||
NextProtos: option.ALPN,
|
SkipCertVerify: option.SkipCertVerify,
|
||||||
MinVersion: tls.VersionTLS12,
|
FingerPrint: option.Fingerprint,
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
Certificate: option.Certificate,
|
||||||
ServerName: option.SNI,
|
PrivateKey: option.PrivateKey,
|
||||||
},
|
ClientFingerprint: option.ClientFingerprint,
|
||||||
Fingerprint: option.Fingerprint,
|
NextProtos: []string{"h2"},
|
||||||
Certificate: option.Certificate,
|
ECH: t.echConfig,
|
||||||
PrivateKey: option.PrivateKey,
|
Reality: t.realityConfig,
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.transport = gun.NewHTTP2Client(dialFn, tlsConfig, option.ClientFingerprint, t.echConfig, t.realityConfig)
|
t.transport = gun.NewHTTP2Client(dialFn, tlsConfig)
|
||||||
|
|
||||||
t.gunTLSConfig = tlsConfig
|
t.gunTLSConfig = tlsConfig
|
||||||
t.gunConfig = &gun.Config{
|
t.gunConfig = &gun.Config{
|
||||||
ServiceName: option.GrpcOpts.GrpcServiceName,
|
ServiceName: option.GrpcOpts.GrpcServiceName,
|
||||||
UserAgent: option.GrpcOpts.GrpcUserAgent,
|
UserAgent: option.GrpcOpts.GrpcUserAgent,
|
||||||
Host: option.SNI,
|
Host: option.SNI,
|
||||||
ClientFingerprint: option.ClientFingerprint,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ type Vless struct {
|
|||||||
encryption *encryption.ClientInstance
|
encryption *encryption.ClientInstance
|
||||||
|
|
||||||
// for gun mux
|
// for gun mux
|
||||||
gunTLSConfig *tls.Config
|
gunTLSConfig *vmess.TLSConfig
|
||||||
gunConfig *gun.Config
|
gunConfig *gun.Config
|
||||||
transport *gun.TransportWrap
|
transport *gun.TransportWrap
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
|||||||
|
|
||||||
c, err = vmess.StreamH2Conn(ctx, c, h2Opts)
|
c, err = vmess.StreamH2Conn(ctx, c, h2Opts)
|
||||||
case "grpc":
|
case "grpc":
|
||||||
c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig, v.echConfig, v.realityConfig)
|
c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig)
|
||||||
default:
|
default:
|
||||||
// default tcp network
|
// default tcp network
|
||||||
// handle TLS
|
// handle TLS
|
||||||
@@ -461,38 +461,36 @@ func NewVless(option VlessOption) (*Vless, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gunConfig := &gun.Config{
|
gunConfig := &gun.Config{
|
||||||
ServiceName: v.option.GrpcOpts.GrpcServiceName,
|
ServiceName: option.GrpcOpts.GrpcServiceName,
|
||||||
UserAgent: v.option.GrpcOpts.GrpcUserAgent,
|
UserAgent: option.GrpcOpts.GrpcUserAgent,
|
||||||
Host: v.option.ServerName,
|
Host: option.ServerName,
|
||||||
ClientFingerprint: v.option.ClientFingerprint,
|
|
||||||
}
|
}
|
||||||
if option.ServerName == "" {
|
if option.ServerName == "" {
|
||||||
gunConfig.Host = v.addr
|
gunConfig.Host = v.addr
|
||||||
}
|
}
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *vmess.TLSConfig
|
||||||
if option.TLS {
|
if option.TLS {
|
||||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
tlsConfig = &vmess.TLSConfig{
|
||||||
TLSConfig: &tls.Config{
|
Host: option.ServerName,
|
||||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
SkipCertVerify: option.SkipCertVerify,
|
||||||
ServerName: v.option.ServerName,
|
FingerPrint: option.Fingerprint,
|
||||||
},
|
Certificate: option.Certificate,
|
||||||
Fingerprint: v.option.Fingerprint,
|
PrivateKey: option.PrivateKey,
|
||||||
Certificate: v.option.Certificate,
|
ClientFingerprint: option.ClientFingerprint,
|
||||||
PrivateKey: v.option.PrivateKey,
|
NextProtos: []string{"h2"},
|
||||||
})
|
ECH: v.echConfig,
|
||||||
if err != nil {
|
Reality: v.realityConfig,
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
if option.ServerName == "" {
|
if option.ServerName == "" {
|
||||||
host, _, _ := net.SplitHostPort(v.addr)
|
host, _, _ := net.SplitHostPort(v.addr)
|
||||||
tlsConfig.ServerName = host
|
tlsConfig.Host = host
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.gunTLSConfig = tlsConfig
|
v.gunTLSConfig = tlsConfig
|
||||||
v.gunConfig = gunConfig
|
v.gunConfig = gunConfig
|
||||||
|
|
||||||
v.transport = gun.NewHTTP2Client(dialFn, tlsConfig, v.option.ClientFingerprint, v.echConfig, v.realityConfig)
|
v.transport = gun.NewHTTP2Client(dialFn, tlsConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, nil
|
return v, nil
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ type Vmess struct {
|
|||||||
option *VmessOption
|
option *VmessOption
|
||||||
|
|
||||||
// for gun mux
|
// for gun mux
|
||||||
gunTLSConfig *tls.Config
|
gunTLSConfig *mihomoVMess.TLSConfig
|
||||||
gunConfig *gun.Config
|
gunConfig *gun.Config
|
||||||
transport *gun.TransportWrap
|
transport *gun.TransportWrap
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
|||||||
|
|
||||||
c, err = mihomoVMess.StreamH2Conn(ctx, c, h2Opts)
|
c, err = mihomoVMess.StreamH2Conn(ctx, c, h2Opts)
|
||||||
case "grpc":
|
case "grpc":
|
||||||
c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig, v.echConfig, v.realityConfig)
|
c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig)
|
||||||
default:
|
default:
|
||||||
// handle TLS
|
// handle TLS
|
||||||
if v.option.TLS {
|
if v.option.TLS {
|
||||||
@@ -467,38 +467,36 @@ func NewVmess(option VmessOption) (*Vmess, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gunConfig := &gun.Config{
|
gunConfig := &gun.Config{
|
||||||
ServiceName: v.option.GrpcOpts.GrpcServiceName,
|
ServiceName: option.GrpcOpts.GrpcServiceName,
|
||||||
UserAgent: v.option.GrpcOpts.GrpcUserAgent,
|
UserAgent: option.GrpcOpts.GrpcUserAgent,
|
||||||
Host: v.option.ServerName,
|
Host: option.ServerName,
|
||||||
ClientFingerprint: v.option.ClientFingerprint,
|
|
||||||
}
|
}
|
||||||
if option.ServerName == "" {
|
if option.ServerName == "" {
|
||||||
gunConfig.Host = v.addr
|
gunConfig.Host = v.addr
|
||||||
}
|
}
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *mihomoVMess.TLSConfig
|
||||||
if option.TLS {
|
if option.TLS {
|
||||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
tlsConfig = &mihomoVMess.TLSConfig{
|
||||||
TLSConfig: &tls.Config{
|
Host: option.ServerName,
|
||||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
SkipCertVerify: option.SkipCertVerify,
|
||||||
ServerName: v.option.ServerName,
|
FingerPrint: option.Fingerprint,
|
||||||
},
|
Certificate: option.Certificate,
|
||||||
Fingerprint: v.option.Fingerprint,
|
PrivateKey: option.PrivateKey,
|
||||||
Certificate: v.option.Certificate,
|
ClientFingerprint: option.ClientFingerprint,
|
||||||
PrivateKey: v.option.PrivateKey,
|
NextProtos: []string{"h2"},
|
||||||
})
|
ECH: v.echConfig,
|
||||||
if err != nil {
|
Reality: v.realityConfig,
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
if option.ServerName == "" {
|
if option.ServerName == "" {
|
||||||
host, _, _ := net.SplitHostPort(v.addr)
|
host, _, _ := net.SplitHostPort(v.addr)
|
||||||
tlsConfig.ServerName = host
|
tlsConfig.Host = host
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.gunTLSConfig = tlsConfig
|
v.gunTLSConfig = tlsConfig
|
||||||
v.gunConfig = gunConfig
|
v.gunConfig = gunConfig
|
||||||
|
|
||||||
v.transport = gun.NewHTTP2Client(dialFn, tlsConfig, v.option.ClientFingerprint, v.echConfig, v.realityConfig)
|
v.transport = gun.NewHTTP2Client(dialFn, tlsConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, nil
|
return v, nil
|
||||||
|
|||||||
@@ -135,6 +135,8 @@ func UEncryptedClientHelloKey(it tls.EncryptedClientHelloKey) utls.EncryptedClie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ConnectionState = utls.ConnectionState
|
||||||
|
|
||||||
type Config = utls.Config
|
type Config = utls.Config
|
||||||
|
|
||||||
var tlsCertificateRequestInfoCtxOffset = utils.MustOK(reflect.TypeOf((*tls.CertificateRequestInfo)(nil)).Elem().FieldByName("ctx")).Offset
|
var tlsCertificateRequestInfoCtxOffset = utils.MustOK(reflect.TypeOf((*tls.CertificateRequestInfo)(nil)).Elem().FieldByName("ctx")).Offset
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import (
|
|||||||
|
|
||||||
"github.com/metacubex/mihomo/common/buf"
|
"github.com/metacubex/mihomo/common/buf"
|
||||||
"github.com/metacubex/mihomo/common/pool"
|
"github.com/metacubex/mihomo/common/pool"
|
||||||
"github.com/metacubex/mihomo/component/ech"
|
|
||||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
|
"github.com/metacubex/mihomo/transport/vmess"
|
||||||
|
|
||||||
"github.com/metacubex/http"
|
"github.com/metacubex/http"
|
||||||
"github.com/metacubex/http/httptrace"
|
"github.com/metacubex/http/httptrace"
|
||||||
@@ -59,10 +59,9 @@ type Conn struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ServiceName string
|
ServiceName string
|
||||||
UserAgent string
|
UserAgent string
|
||||||
Host string
|
Host string
|
||||||
ClientFingerprint string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Conn) initReader() {
|
func (g *Conn) initReader() {
|
||||||
@@ -247,7 +246,7 @@ func (g *Conn) SetDeadline(t time.Time) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTP2Client(dialFn DialFn, tlsConfig *tls.Config, clientFingerprint string, echConfig *ech.Config, realityConfig *tlsC.RealityConfig) *TransportWrap {
|
func NewHTTP2Client(dialFn DialFn, tlsConfig *vmess.TLSConfig) *TransportWrap {
|
||||||
dialFunc := func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
dialFunc := func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||||
ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout)
|
ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -260,65 +259,33 @@ func NewHTTP2Client(dialFn DialFn, tlsConfig *tls.Config, clientFingerprint stri
|
|||||||
return pconn, nil
|
return pconn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if clientFingerprint, ok := tlsC.GetFingerprint(clientFingerprint); ok {
|
conn, err := vmess.StreamTLSConn(ctx, pconn, tlsConfig)
|
||||||
if realityConfig == nil {
|
if err != nil {
|
||||||
tlsConfig := tlsC.UConfig(cfg)
|
_ = pconn.Close()
|
||||||
err := echConfig.ClientHandleUTLS(ctx, tlsConfig)
|
return nil, err
|
||||||
if err != nil {
|
}
|
||||||
pconn.Close()
|
|
||||||
return nil, err
|
if tlsConfig.Reality == nil { // reality doesn't return the negotiated ALPN
|
||||||
}
|
switch tlsConn := conn.(type) {
|
||||||
tlsConn := tlsC.UClient(pconn, tlsConfig, clientFingerprint)
|
case interface{ ConnectionState() tls.ConnectionState }:
|
||||||
if err := tlsConn.HandshakeContext(ctx); err != nil {
|
|
||||||
pconn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
state := tlsConn.ConnectionState()
|
state := tlsConn.ConnectionState()
|
||||||
if p := state.NegotiatedProtocol; p != http.Http2NextProtoTLS {
|
if p := state.NegotiatedProtocol; p != http.Http2NextProtoTLS {
|
||||||
tlsConn.Close()
|
_ = conn.Close()
|
||||||
return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http.Http2NextProtoTLS)
|
return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http.Http2NextProtoTLS)
|
||||||
}
|
}
|
||||||
return tlsConn, nil
|
case interface{ ConnectionState() tlsC.ConnectionState }:
|
||||||
} else {
|
state := tlsConn.ConnectionState()
|
||||||
realityConn, err := tlsC.GetRealityConn(ctx, pconn, clientFingerprint, cfg.ServerName, realityConfig)
|
if p := state.NegotiatedProtocol; p != http.Http2NextProtoTLS {
|
||||||
if err != nil {
|
_ = conn.Close()
|
||||||
pconn.Close()
|
return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http.Http2NextProtoTLS)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
//state := realityConn.(*utls.UConn).ConnectionState()
|
|
||||||
//if p := state.NegotiatedProtocol; p != http.Http2NextProtoTLS {
|
|
||||||
// realityConn.Close()
|
|
||||||
// return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http.Http2NextProtoTLS)
|
|
||||||
//}
|
|
||||||
return realityConn, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if realityConfig != nil {
|
|
||||||
return nil, errors.New("REALITY is based on uTLS, please set a client-fingerprint")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = echConfig.ClientHandle(ctx, cfg)
|
|
||||||
if err != nil {
|
|
||||||
pconn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := tls.Client(pconn, cfg)
|
|
||||||
if err := conn.HandshakeContext(ctx); err != nil {
|
|
||||||
pconn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
state := conn.ConnectionState()
|
|
||||||
if p := state.NegotiatedProtocol; p != http.Http2NextProtoTLS {
|
|
||||||
conn.Close()
|
|
||||||
return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http.Http2NextProtoTLS)
|
|
||||||
}
|
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
transport := &http.Http2Transport{
|
transport := &http.Http2Transport{
|
||||||
DialTLSContext: dialFunc,
|
DialTLSContext: dialFunc,
|
||||||
TLSClientConfig: tlsConfig,
|
|
||||||
AllowHTTP: false,
|
AllowHTTP: false,
|
||||||
DisableCompression: true,
|
DisableCompression: true,
|
||||||
PingTimeout: 0,
|
PingTimeout: 0,
|
||||||
@@ -394,12 +361,12 @@ func StreamGunWithTransport(transport *TransportWrap, cfg *Config) (net.Conn, er
|
|||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StreamGunWithConn(conn net.Conn, tlsConfig *tls.Config, cfg *Config, echConfig *ech.Config, realityConfig *tlsC.RealityConfig) (net.Conn, error) {
|
func StreamGunWithConn(conn net.Conn, tlsConfig *vmess.TLSConfig, cfg *Config) (net.Conn, error) {
|
||||||
dialFn := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
dialFn := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
transport := NewHTTP2Client(dialFn, tlsConfig, cfg.ClientFingerprint, echConfig, realityConfig)
|
transport := NewHTTP2Client(dialFn, tlsConfig)
|
||||||
c, err := StreamGunWithTransport(transport, cfg)
|
c, err := StreamGunWithTransport(transport, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -24,10 +24,6 @@ type TLSConfig struct {
|
|||||||
Reality *tlsC.RealityConfig
|
Reality *tlsC.RealityConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type ECHConfig struct {
|
|
||||||
Enable bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
|
func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
|
||||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||||
TLSConfig: &tls.Config{
|
TLSConfig: &tls.Config{
|
||||||
|
|||||||
Reference in New Issue
Block a user