Files
Xray-core/transport/internet/tcp/dialer.go
RPRX 9b7841178a
Some checks are pending
Build and Release / build (ppc64le, linux) (push) Waiting to run
Build docker image / build-image (push) Waiting to run
Build and Release for Windows 7 / build (win7-32, 386, windows) (push) Waiting to run
Build and Release for Windows 7 / build (win7-64, amd64, windows) (push) Waiting to run
Build and Release / build (386, freebsd, ) (push) Waiting to run
Build and Release / build (386, linux, ) (push) Waiting to run
Build and Release / build (386, openbsd, ) (push) Waiting to run
Build and Release / build (386, windows, ) (push) Waiting to run
Build and Release / build (amd64, darwin, ) (push) Waiting to run
Build and Release / build (amd64, freebsd, ) (push) Waiting to run
Build and Release / build (amd64, linux, ) (push) Waiting to run
Build and Release / build (amd64, openbsd, ) (push) Waiting to run
Build and Release / build (amd64, windows, ) (push) Waiting to run
Build and Release / build (arm, 5, linux) (push) Waiting to run
Build and Release / build (arm, 6, linux) (push) Waiting to run
Build and Release / build (arm, 7, freebsd) (push) Waiting to run
Build and Release / build (arm, 7, linux) (push) Waiting to run
Build and Release / build (arm, 7, openbsd) (push) Waiting to run
Build and Release / build (arm, 7, windows) (push) Waiting to run
Build and Release / build (arm64, android) (push) Waiting to run
Build and Release / build (arm64, darwin) (push) Waiting to run
Build and Release / build (arm64, freebsd) (push) Waiting to run
Build and Release / build (arm64, linux) (push) Waiting to run
Build and Release / build (arm64, openbsd) (push) Waiting to run
Build and Release / build (arm64, windows) (push) Waiting to run
Build and Release / build (loong64, linux) (push) Waiting to run
Build and Release / build (mips, linux) (push) Waiting to run
Build and Release / build (mips64, linux) (push) Waiting to run
Build and Release / build (mips64le, linux) (push) Waiting to run
Build and Release / build (mipsle, linux) (push) Waiting to run
Build and Release / build (ppc64, linux) (push) Waiting to run
Build and Release / build (riscv64, linux) (push) Waiting to run
Build and Release / build (s390x, linux) (push) Waiting to run
Test / test (macos-latest) (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
Test / test (windows-latest) (push) Waiting to run
MITM: Allow forwarding local negotiated ALPN http/1.1 to the real website
https://github.com/XTLS/Xray-core/issues/4348#issuecomment-2633656408

https://github.com/XTLS/Xray-core/issues/4348#issuecomment-2633865039

Local negotiated ALPN http/1.1 was sent by browser/app or is written in dokodemo-door RAW's `tlsSettings`.

Set `"alpn": ["fromMitm"]` in freedom RAW's `tlsSettings` to forward it to the real website.
2025-02-04 15:10:08 +00:00

73 lines
2.5 KiB
Go

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"
"github.com/xtls/xray-core/transport/internet/tls"
)
// Dial dials a new TCP connection to the given destination.
func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (stat.Connection, error) {
errors.LogInfo(ctx, "dialing TCP to ", dest)
conn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
if err != nil {
return nil, err
}
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
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" ||
(strings.ToLower(tlsConfig.NextProtos[0]) == "frommitm" && session.MitmAlpn11FromContext(ctx))) {
if err := conn.(*tls.UConn).WebsocketHandshakeContext(ctx); err != nil {
return nil, err
}
} else {
if err := conn.(*tls.UConn).HandshakeContext(ctx); err != nil {
return nil, err
}
}
} 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 {
if conn, err = reality.UClient(conn, config, ctx, dest); err != nil {
return nil, err
}
}
tcpSettings := streamSettings.ProtocolSettings.(*Config)
if tcpSettings.HeaderSettings != nil {
headerConfig, err := tcpSettings.HeaderSettings.GetInstance()
if err != nil {
return nil, errors.New("failed to get header settings").Base(err).AtError()
}
auth, err := internet.CreateConnectionAuthenticator(headerConfig)
if err != nil {
return nil, errors.New("failed to create header authenticator").Base(err).AtError()
}
conn = auth.Client(conn)
}
return stat.Connection(conn), nil
}
func init() {
common.Must(internet.RegisterTransportDialer(protocolName, Dial))
}