mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-10-16 20:44:03 +00:00
Compare commits
1
Commits
main
...
tls-update
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
969e5b6c11 |
+9
-6
@@ -180,14 +180,14 @@ type VisionReader struct {
|
||||
isUplink bool
|
||||
conn net.Conn
|
||||
input *bytes.Reader
|
||||
rawInput *bytes.Buffer
|
||||
rawInput **bytes.Buffer
|
||||
ob *session.Outbound
|
||||
|
||||
// internal
|
||||
directReadCounter stats.Counter
|
||||
}
|
||||
|
||||
func NewVisionReader(reader buf.Reader, trafficState *TrafficState, isUplink bool, ctx context.Context, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, ob *session.Outbound) *VisionReader {
|
||||
func NewVisionReader(reader buf.Reader, trafficState *TrafficState, isUplink bool, ctx context.Context, conn net.Conn, input *bytes.Reader, rawInput **bytes.Buffer, ob *session.Outbound) *VisionReader {
|
||||
return &VisionReader{
|
||||
Reader: reader,
|
||||
trafficState: trafficState,
|
||||
@@ -261,12 +261,15 @@ func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||
if inputBuffer, err := buf.ReadFrom(w.input); err == nil && !inputBuffer.IsEmpty() {
|
||||
buffer, _ = buf.MergeMulti(buffer, inputBuffer)
|
||||
}
|
||||
if rawInputBuffer, err := buf.ReadFrom(w.rawInput); err == nil && !rawInputBuffer.IsEmpty() {
|
||||
buffer, _ = buf.MergeMulti(buffer, rawInputBuffer)
|
||||
}
|
||||
*w.input = bytes.Reader{} // release memory
|
||||
w.input = nil
|
||||
*w.rawInput = bytes.Buffer{} // release memory
|
||||
|
||||
if raw := *w.rawInput; raw != nil {
|
||||
if rawInputBuffer, err := buf.ReadFrom(raw); err == nil && !rawInputBuffer.IsEmpty() {
|
||||
buffer, _ = buf.MergeMulti(buffer, rawInputBuffer)
|
||||
}
|
||||
*raw = bytes.Buffer{} // release memory
|
||||
}
|
||||
w.rawInput = nil
|
||||
|
||||
if inbound := session.InboundFromContext(w.ctx); inbound != nil && inbound.Conn != nil {
|
||||
|
||||
@@ -6,11 +6,9 @@ import (
|
||||
gotls "crypto/tls"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/xtls/xray-core/app/dispatcher"
|
||||
"github.com/xtls/xray-core/app/reverse"
|
||||
@@ -548,7 +546,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
||||
}
|
||||
|
||||
var input *bytes.Reader
|
||||
var rawInput *bytes.Buffer
|
||||
var rawInput **bytes.Buffer
|
||||
switch requestAddons.Flow {
|
||||
case vless.XRV:
|
||||
if account.Flow == requestAddons.Flow {
|
||||
@@ -560,30 +558,23 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
||||
inbound.CanSpliceCopy = 3
|
||||
fallthrough // we will break Mux connections that contain TCP requests
|
||||
case protocol.RequestCommandTCP:
|
||||
var t reflect.Type
|
||||
var p uintptr
|
||||
var target net.Conn
|
||||
if commonConn, ok := connection.(*encryption.CommonConn); ok {
|
||||
if _, ok := commonConn.Conn.(*encryption.XorConn); ok || !proxy.IsRAWTransportWithoutSecurity(iConn) {
|
||||
inbound.CanSpliceCopy = 3 // full-random xorConn / non-RAW transport / another securityConn should not be penetrated
|
||||
}
|
||||
t = reflect.TypeOf(commonConn).Elem()
|
||||
p = uintptr(unsafe.Pointer(commonConn))
|
||||
target = commonConn
|
||||
} else if tlsConn, ok := iConn.(*tls.Conn); ok {
|
||||
if tlsConn.ConnectionState().Version != gotls.VersionTLS13 {
|
||||
return errors.New(`failed to use `+requestAddons.Flow+`, found outer tls version `, tlsConn.ConnectionState().Version)
|
||||
}
|
||||
t = reflect.TypeOf(tlsConn.Conn).Elem()
|
||||
p = uintptr(unsafe.Pointer(tlsConn.Conn))
|
||||
target = tlsConn.Conn
|
||||
} else if realityConn, ok := iConn.(*reality.Conn); ok {
|
||||
t = reflect.TypeOf(realityConn.Conn).Elem()
|
||||
p = uintptr(unsafe.Pointer(realityConn.Conn))
|
||||
target = realityConn.Conn
|
||||
} else {
|
||||
return errors.New("XTLS only supports TLS and REALITY directly for now.")
|
||||
}
|
||||
i, _ := t.FieldByName("input")
|
||||
r, _ := t.FieldByName("rawInput")
|
||||
input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
|
||||
rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
|
||||
input, rawInput = vless.AccessTLSBuffers(target)
|
||||
}
|
||||
} else {
|
||||
return errors.New("account " + account.ID.String() + " is not able to use the flow " + requestAddons.Flow)
|
||||
|
||||
@@ -5,11 +5,9 @@ import (
|
||||
"context"
|
||||
gotls "crypto/tls"
|
||||
"encoding/base64"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
utls "github.com/refraction-networking/utls"
|
||||
proxymanConfig "github.com/xtls/xray-core/app/proxyman"
|
||||
@@ -244,7 +242,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
}
|
||||
|
||||
var input *bytes.Reader
|
||||
var rawInput *bytes.Buffer
|
||||
var rawInput **bytes.Buffer
|
||||
allowUDP443 := false
|
||||
switch requestAddons.Flow {
|
||||
case vless.XRV + "-udp443":
|
||||
@@ -261,30 +259,22 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
case protocol.RequestCommandMux:
|
||||
fallthrough // let server break Mux connections that contain TCP requests
|
||||
case protocol.RequestCommandTCP, protocol.RequestCommandRvs:
|
||||
var t reflect.Type
|
||||
var p uintptr
|
||||
var target net.Conn
|
||||
if commonConn, ok := conn.(*encryption.CommonConn); ok {
|
||||
if _, ok := commonConn.Conn.(*encryption.XorConn); ok || !proxy.IsRAWTransportWithoutSecurity(iConn) {
|
||||
ob.CanSpliceCopy = 3 // full-random xorConn / non-RAW transport / another securityConn should not be penetrated
|
||||
}
|
||||
t = reflect.TypeOf(commonConn).Elem()
|
||||
p = uintptr(unsafe.Pointer(commonConn))
|
||||
target = commonConn
|
||||
} else if tlsConn, ok := iConn.(*tls.Conn); ok {
|
||||
t = reflect.TypeOf(tlsConn.Conn).Elem()
|
||||
p = uintptr(unsafe.Pointer(tlsConn.Conn))
|
||||
target = tlsConn.Conn
|
||||
} else if utlsConn, ok := iConn.(*tls.UConn); ok {
|
||||
t = reflect.TypeOf(utlsConn.Conn).Elem()
|
||||
p = uintptr(unsafe.Pointer(utlsConn.Conn))
|
||||
target = utlsConn.Conn
|
||||
} else if realityConn, ok := iConn.(*reality.UConn); ok {
|
||||
t = reflect.TypeOf(realityConn.Conn).Elem()
|
||||
p = uintptr(unsafe.Pointer(realityConn.Conn))
|
||||
target = realityConn.Conn
|
||||
} else {
|
||||
return errors.New("XTLS only supports TLS and REALITY directly for now.")
|
||||
}
|
||||
i, _ := t.FieldByName("input")
|
||||
r, _ := t.FieldByName("rawInput")
|
||||
input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
|
||||
rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
|
||||
input, rawInput = vless.AccessTLSBuffers(target)
|
||||
default:
|
||||
panic("unknown VLESS request command")
|
||||
}
|
||||
|
||||
@@ -5,7 +5,28 @@
|
||||
// clients with 'socks' for proxying.
|
||||
package vless
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"reflect"
|
||||
|
||||
"github.com/xtls/xray-core/common/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
None = "none"
|
||||
XRV = "xtls-rprx-vision"
|
||||
)
|
||||
|
||||
// Old TLS lib holds bytes.Buffer, but new TLS lib holds *bytes.Buffer
|
||||
// Since Xray has 3 TLS libraries (std, utls, REALITY server)
|
||||
// we detect the type of rawInput and return the appropriate pointer
|
||||
func AccessTLSBuffers(conn net.Conn) (*bytes.Reader, **bytes.Buffer) {
|
||||
input := utils.AccessField[bytes.Reader](conn, "input")
|
||||
field := reflect.ValueOf(conn).Elem().FieldByName("rawInput")
|
||||
if field.Kind() == reflect.Pointer {
|
||||
return input, utils.AccessField[*bytes.Buffer](conn, "rawInput")
|
||||
}
|
||||
raw := utils.AccessField[bytes.Buffer](conn, "rawInput")
|
||||
return input, &raw
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user