Pārlūkot izejas kodu

XTLS Vision processes struct TLS Conn's input and rawInput

Fixes https://github.com/XTLS/Xray-core/issues/1444
RPRX 2 gadi atpakaļ
vecāks
revīzija
6f61021f7a

+ 12 - 0
proxy/vless/encoding/encoding.go

@@ -250,6 +250,7 @@ func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, c
 
 // XtlsRead filter and read xtls protocol
 func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn,
+	input *bytes.Reader, rawInput *bytes.Buffer,
 	counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool,
 	isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32,
 ) error {
@@ -301,6 +302,17 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
 						} else if currentCommand == 2 {
 							filterUUID = false
 							shouldSwitchToDirectCopy = true
+							// XTLS Vision processes struct TLS Conn's input and rawInput
+							if inputBuffer, err := buf.ReadFrom(input); err == nil {
+								if !inputBuffer.IsEmpty() {
+									buffer, _ = buf.MergeMulti(buffer, inputBuffer)
+								}
+							}
+							if rawInputBuffer, err := buf.ReadFrom(rawInput); err == nil {
+								if !rawInputBuffer.IsEmpty() {
+									buffer, _ = buf.MergeMulti(buffer, rawInputBuffer)
+								}
+							}
 						} else if currentCommand != 0 {
 							newError("XtlsRead unknown command ", currentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
 						}

+ 14 - 1
proxy/vless/inbound/inbound.go

@@ -3,12 +3,15 @@ package inbound
 //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
 
 import (
+	"bytes"
 	"context"
 	"io"
+	"reflect"
 	"strconv"
 	"strings"
 	"syscall"
 	"time"
+	"unsafe"
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
@@ -441,6 +444,8 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
 
 	var netConn net.Conn
 	var rawConn syscall.RawConn
+	var input *bytes.Reader
+	var rawInput *bytes.Buffer
 	allowNoneFlow := false
 	accountFlow := account.Flow
 	flows := strings.Split(account.Flow, ",")
@@ -462,11 +467,15 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
 				return newError(requestAddons.Flow + " doesn't support UDP").AtWarning()
 			case protocol.RequestCommandTCP:
 				if requestAddons.Flow == vless.XRV {
+					var t reflect.Type
+					var p uintptr
 					if tlsConn, ok := iConn.(*tls.Conn); ok {
 						netConn = tlsConn.NetConn()
 						if sc, ok := netConn.(syscall.Conn); ok {
 							rawConn, _ = sc.SyscallConn()
 						}
+						t = reflect.TypeOf(tlsConn.Conn).Elem()
+						p = uintptr(unsafe.Pointer(tlsConn.Conn))
 					} else if _, ok := iConn.(*tls.UConn); ok {
 						return newError("XTLS only supports UTLS fingerprint for the outbound.").AtWarning()
 					} else if _, ok := iConn.(*xtls.Conn); ok {
@@ -474,6 +483,10 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
 					} else {
 						return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
 					}
+					i, _ := t.FieldByName("input")
+					r, _ := t.FieldByName("rawInput")
+					input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
+					rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
 				} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
 					xtlsConn.RPRX = true
 					xtlsConn.SHOW = xtls_show
@@ -545,7 +558,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
 			// TODO enable splice
 			ctx = session.ContextWithInbound(ctx, nil)
 			if requestAddons.Flow == vless.XRV {
-				err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(),
+				err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(),
 					&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
 			} else {
 				err = encoding.ReadV(clientReader, serverWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx)

+ 16 - 1
proxy/vless/outbound/outbound.go

@@ -3,9 +3,12 @@ package outbound
 //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
 
 import (
+	"bytes"
 	"context"
+	"reflect"
 	"syscall"
 	"time"
+	"unsafe"
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
@@ -130,6 +133,8 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 
 	var netConn net.Conn
 	var rawConn syscall.RawConn
+	var input *bytes.Reader
+	var rawInput *bytes.Buffer
 	allowUDP443 := false
 	switch requestAddons.Flow {
 	case vless.XRO + "-udp443", vless.XRD + "-udp443", vless.XRS + "-udp443", vless.XRV + "-udp443":
@@ -147,21 +152,31 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 			requestAddons.Flow = ""
 		case protocol.RequestCommandTCP:
 			if requestAddons.Flow == vless.XRV {
+				var t reflect.Type
+				var p uintptr
 				if tlsConn, ok := iConn.(*tls.Conn); ok {
 					netConn = tlsConn.NetConn()
 					if sc, ok := netConn.(syscall.Conn); ok {
 						rawConn, _ = sc.SyscallConn()
 					}
+					t = reflect.TypeOf(tlsConn.Conn).Elem()
+					p = uintptr(unsafe.Pointer(tlsConn.Conn))
 				} else if utlsConn, ok := iConn.(*tls.UConn); ok {
 					netConn = utlsConn.Conn.NetConn()
 					if sc, ok := netConn.(syscall.Conn); ok {
 						rawConn, _ = sc.SyscallConn()
 					}
+					t = reflect.TypeOf(utlsConn.Conn).Elem()
+					p = uintptr(unsafe.Pointer(utlsConn.Conn))
 				} else if _, ok := iConn.(*xtls.Conn); ok {
 					return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning()
 				} else {
 					return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
 				}
+				i, _ := t.FieldByName("input")
+				r, _ := t.FieldByName("rawInput")
+				input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
+				rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
 			} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
 				xtlsConn.RPRX = true
 				xtlsConn.SHOW = xtls_show
@@ -287,7 +302,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 				counter = statConn.ReadCounter
 			}
 			if requestAddons.Flow == vless.XRV {
-				err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(),
+				err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(),
 					&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
 			} else {
 				if requestAddons.Flow != vless.XRS {