diff --git a/common/session/context.go b/common/session/context.go index b7af69cc..a2c97d37 100644 --- a/common/session/context.go +++ b/common/session/context.go @@ -23,6 +23,7 @@ const ( timeoutOnlyKey ctx.SessionKey = 8 allowedNetworkKey ctx.SessionKey = 9 handlerSessionKey ctx.SessionKey = 10 + mitmAlpn11Key ctx.SessionKey = 11 ) func ContextWithInbound(ctx context.Context, inbound *Inbound) context.Context { @@ -162,3 +163,14 @@ func AllowedNetworkFromContext(ctx context.Context) net.Network { } return net.Network_Unknown } + +func ContextWithMitmAlpn11(ctx context.Context, alpn11 bool) context.Context { + return context.WithValue(ctx, mitmAlpn11Key, alpn11) +} + +func MitmAlpn11FromContext(ctx context.Context) bool { + if val, ok := ctx.Value(mitmAlpn11Key).(bool); ok { + return val + } + return false +} diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index 6522f071..6bd3e28f 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -18,6 +18,7 @@ import ( "github.com/xtls/xray-core/features/policy" "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/transport/internet/stat" + "github.com/xtls/xray-core/transport/internet/tls" ) func init() { @@ -90,6 +91,9 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st addr := handshake.HandshakeAddressContext(ctx) if addr != nil { dest.Address = addr + if conn.(*tls.Conn).ConnectionState().NegotiatedProtocol == "http/1.1" { + ctx = session.ContextWithMitmAlpn11(ctx, true) + } destinationOverridden = true } } diff --git a/transport/internet/tcp/dialer.go b/transport/internet/tcp/dialer.go index 19b3f6b4..abc2688e 100644 --- a/transport/internet/tcp/dialer.go +++ b/transport/internet/tcp/dialer.go @@ -2,10 +2,12 @@ package tcp import ( "context" + "strings" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/reality" "github.com/xtls/xray-core/transport/internet/stat" @@ -24,7 +26,8 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me tlsConfig := config.GetTLSConfig(tls.WithDestination(dest)) if fingerprint := tls.GetFingerprint(config.Fingerprint); fingerprint != nil { conn = tls.UClient(conn, tlsConfig, fingerprint) - if len(tlsConfig.NextProtos) == 1 && tlsConfig.NextProtos[0] == "http/1.1" { + if len(tlsConfig.NextProtos) == 1 && (tlsConfig.NextProtos[0] == "http/1.1" || + (strings.ToLower(tlsConfig.NextProtos[0]) == "frommitm" && session.MitmAlpn11FromContext(ctx))) { if err := conn.(*tls.UConn).WebsocketHandshakeContext(ctx); err != nil { return nil, err } @@ -34,6 +37,13 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } } } else { + if len(tlsConfig.NextProtos) == 1 && strings.ToLower(tlsConfig.NextProtos[0]) == "frommitm" { + if session.MitmAlpn11FromContext(ctx) { + tlsConfig.NextProtos = []string{"http/1.1"} // new slice + } else { + tlsConfig.NextProtos = nil + } + } conn = tls.Client(conn, tlsConfig) } } else if config := reality.ConfigFromStreamSettings(streamSettings); config != nil {