| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 | 
							- 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"
 
- )
 
- func IsFromMitm(str string) bool {
 
- 	return strings.ToLower(str) == "frommitm"
 
- }
 
- // 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 {
 
- 		mitmServerName := session.MitmServerNameFromContext(ctx)
 
- 		mitmAlpn11 := session.MitmAlpn11FromContext(ctx)
 
- 		tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
 
- 		if IsFromMitm(tlsConfig.ServerName) {
 
- 			tlsConfig.ServerName = mitmServerName
 
- 		}
 
- 		if r, ok := tlsConfig.Rand.(*tls.RandCarrier); ok && len(r.VerifyPeerCertInNames) > 0 && IsFromMitm(r.VerifyPeerCertInNames[0]) {
 
- 			r.VerifyPeerCertInNames = r.VerifyPeerCertInNames[1:]
 
- 			after := mitmServerName
 
- 			for {
 
- 				if len(after) > 0 {
 
- 					r.VerifyPeerCertInNames = append(r.VerifyPeerCertInNames, after)
 
- 				}
 
- 				_, after, _ = strings.Cut(after, ".")
 
- 				if !strings.Contains(after, ".") {
 
- 					break
 
- 				}
 
- 			}
 
- 		}
 
- 		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" || (IsFromMitm(tlsConfig.NextProtos[0]) && mitmAlpn11)) {
 
- 				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 && IsFromMitm(tlsConfig.NextProtos[0]) {
 
- 				if mitmAlpn11 {
 
- 					tlsConfig.NextProtos[0] = "http/1.1"
 
- 				} else {
 
- 					tlsConfig.NextProtos = nil
 
- 				}
 
- 			}
 
- 			conn = tls.Client(conn, tlsConfig)
 
- 			if err := conn.(*tls.Conn).HandshakeContext(ctx); err != nil {
 
- 				return nil, err
 
- 			}
 
- 		}
 
- 	} 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))
 
- }
 
 
  |