|
@@ -7,7 +7,6 @@ import (
|
|
|
"context"
|
|
"context"
|
|
|
gotls "crypto/tls"
|
|
gotls "crypto/tls"
|
|
|
"reflect"
|
|
"reflect"
|
|
|
- "syscall"
|
|
|
|
|
"time"
|
|
"time"
|
|
|
"unsafe"
|
|
"unsafe"
|
|
|
|
|
|
|
@@ -23,7 +22,6 @@ import (
|
|
|
"github.com/xtls/xray-core/common/xudp"
|
|
"github.com/xtls/xray-core/common/xudp"
|
|
|
"github.com/xtls/xray-core/core"
|
|
"github.com/xtls/xray-core/core"
|
|
|
"github.com/xtls/xray-core/features/policy"
|
|
"github.com/xtls/xray-core/features/policy"
|
|
|
- "github.com/xtls/xray-core/features/stats"
|
|
|
|
|
"github.com/xtls/xray-core/proxy/vless"
|
|
"github.com/xtls/xray-core/proxy/vless"
|
|
|
"github.com/xtls/xray-core/proxy/vless/encoding"
|
|
"github.com/xtls/xray-core/proxy/vless/encoding"
|
|
|
"github.com/xtls/xray-core/transport"
|
|
"github.com/xtls/xray-core/transport"
|
|
@@ -71,9 +69,15 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
|
|
|
|
|
|
|
|
// Process implements proxy.Outbound.Process().
|
|
// Process implements proxy.Outbound.Process().
|
|
|
func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
|
|
func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
|
|
|
|
|
+ outbound := session.OutboundFromContext(ctx)
|
|
|
|
|
+ if outbound == nil || !outbound.Target.IsValid() {
|
|
|
|
|
+ return newError("target not specified").AtError()
|
|
|
|
|
+ }
|
|
|
|
|
+ outbound.Name = "vless"
|
|
|
|
|
+ inbound := session.InboundFromContext(ctx)
|
|
|
|
|
+
|
|
|
var rec *protocol.ServerSpec
|
|
var rec *protocol.ServerSpec
|
|
|
var conn stat.Connection
|
|
var conn stat.Connection
|
|
|
-
|
|
|
|
|
if err := retry.ExponentialBackoff(5, 200).On(func() error {
|
|
if err := retry.ExponentialBackoff(5, 200).On(func() error {
|
|
|
rec = h.serverPicker.PickServer()
|
|
rec = h.serverPicker.PickServer()
|
|
|
var err error
|
|
var err error
|
|
@@ -88,16 +92,9 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|
|
defer conn.Close()
|
|
defer conn.Close()
|
|
|
|
|
|
|
|
iConn := conn
|
|
iConn := conn
|
|
|
- statConn, ok := iConn.(*stat.CounterConnection)
|
|
|
|
|
- if ok {
|
|
|
|
|
|
|
+ if statConn, ok := iConn.(*stat.CounterConnection); ok {
|
|
|
iConn = statConn.Connection
|
|
iConn = statConn.Connection
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- outbound := session.OutboundFromContext(ctx)
|
|
|
|
|
- if outbound == nil || !outbound.Target.IsValid() {
|
|
|
|
|
- return newError("target not specified").AtError()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
target := outbound.Target
|
|
target := outbound.Target
|
|
|
newError("tunneling request to ", target, " via ", rec.Destination().NetAddr()).AtInfo().WriteToLog(session.ExportIDToError(ctx))
|
|
newError("tunneling request to ", target, " via ", rec.Destination().NetAddr()).AtInfo().WriteToLog(session.ExportIDToError(ctx))
|
|
|
|
|
|
|
@@ -123,8 +120,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|
|
Flow: account.Flow,
|
|
Flow: account.Flow,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var netConn net.Conn
|
|
|
|
|
- var rawConn syscall.RawConn
|
|
|
|
|
var input *bytes.Reader
|
|
var input *bytes.Reader
|
|
|
var rawInput *bytes.Buffer
|
|
var rawInput *bytes.Buffer
|
|
|
allowUDP443 := false
|
|
allowUDP443 := false
|
|
@@ -134,6 +129,9 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|
|
requestAddons.Flow = requestAddons.Flow[:16]
|
|
requestAddons.Flow = requestAddons.Flow[:16]
|
|
|
fallthrough
|
|
fallthrough
|
|
|
case vless.XRV:
|
|
case vless.XRV:
|
|
|
|
|
+ if inbound != nil {
|
|
|
|
|
+ inbound.SetCanSpliceCopy(2)
|
|
|
|
|
+ }
|
|
|
switch request.Command {
|
|
switch request.Command {
|
|
|
case protocol.RequestCommandUDP:
|
|
case protocol.RequestCommandUDP:
|
|
|
if !allowUDP443 && request.Port == 443 {
|
|
if !allowUDP443 && request.Port == 443 {
|
|
@@ -146,28 +144,26 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|
|
var t reflect.Type
|
|
var t reflect.Type
|
|
|
var p uintptr
|
|
var p uintptr
|
|
|
if tlsConn, ok := iConn.(*tls.Conn); ok {
|
|
if tlsConn, ok := iConn.(*tls.Conn); ok {
|
|
|
- netConn = tlsConn.NetConn()
|
|
|
|
|
t = reflect.TypeOf(tlsConn.Conn).Elem()
|
|
t = reflect.TypeOf(tlsConn.Conn).Elem()
|
|
|
p = uintptr(unsafe.Pointer(tlsConn.Conn))
|
|
p = uintptr(unsafe.Pointer(tlsConn.Conn))
|
|
|
} else if utlsConn, ok := iConn.(*tls.UConn); ok {
|
|
} else if utlsConn, ok := iConn.(*tls.UConn); ok {
|
|
|
- netConn = utlsConn.NetConn()
|
|
|
|
|
t = reflect.TypeOf(utlsConn.Conn).Elem()
|
|
t = reflect.TypeOf(utlsConn.Conn).Elem()
|
|
|
p = uintptr(unsafe.Pointer(utlsConn.Conn))
|
|
p = uintptr(unsafe.Pointer(utlsConn.Conn))
|
|
|
} else if realityConn, ok := iConn.(*reality.UConn); ok {
|
|
} else if realityConn, ok := iConn.(*reality.UConn); ok {
|
|
|
- netConn = realityConn.NetConn()
|
|
|
|
|
t = reflect.TypeOf(realityConn.Conn).Elem()
|
|
t = reflect.TypeOf(realityConn.Conn).Elem()
|
|
|
p = uintptr(unsafe.Pointer(realityConn.Conn))
|
|
p = uintptr(unsafe.Pointer(realityConn.Conn))
|
|
|
} else {
|
|
} else {
|
|
|
return newError("XTLS only supports TLS and REALITY directly for now.").AtWarning()
|
|
return newError("XTLS only supports TLS and REALITY directly for now.").AtWarning()
|
|
|
}
|
|
}
|
|
|
- if sc, ok := netConn.(syscall.Conn); ok {
|
|
|
|
|
- rawConn, _ = sc.SyscallConn()
|
|
|
|
|
- }
|
|
|
|
|
i, _ := t.FieldByName("input")
|
|
i, _ := t.FieldByName("input")
|
|
|
r, _ := t.FieldByName("rawInput")
|
|
r, _ := t.FieldByName("rawInput")
|
|
|
input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
|
|
input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
|
|
|
rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
|
|
rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
|
|
|
}
|
|
}
|
|
|
|
|
+ default:
|
|
|
|
|
+ if inbound != nil {
|
|
|
|
|
+ inbound.SetCanSpliceCopy(3)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var newCtx context.Context
|
|
var newCtx context.Context
|
|
@@ -257,11 +253,8 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|
|
return newError(`failed to use `+requestAddons.Flow+`, found outer tls version `, utlsConn.ConnectionState().Version).AtWarning()
|
|
return newError(`failed to use `+requestAddons.Flow+`, found outer tls version `, utlsConn.ConnectionState().Version).AtWarning()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- var counter stats.Counter
|
|
|
|
|
- if statConn != nil {
|
|
|
|
|
- counter = statConn.WriteCounter
|
|
|
|
|
- }
|
|
|
|
|
- err = encoding.XtlsWrite(clientReader, serverWriter, timer, netConn, counter, ctx, &numberOfPacketToFilter,
|
|
|
|
|
|
|
+ ctx1 := session.ContextWithOutbound(ctx, nil) // TODO enable splice
|
|
|
|
|
+ err = encoding.XtlsWrite(clientReader, serverWriter, timer, conn, ctx1, &numberOfPacketToFilter,
|
|
|
&enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
|
&enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
|
|
} else {
|
|
} else {
|
|
|
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
|
|
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
|
|
@@ -293,11 +286,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if requestAddons.Flow == vless.XRV {
|
|
if requestAddons.Flow == vless.XRV {
|
|
|
- var counter stats.Counter
|
|
|
|
|
- if statConn != nil {
|
|
|
|
|
- counter = statConn.ReadCounter
|
|
|
|
|
- }
|
|
|
|
|
- err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(),
|
|
|
|
|
|
|
+ err = encoding.XtlsRead(serverReader, clientWriter, timer, conn, input, rawInput, ctx, account.ID.Bytes(),
|
|
|
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
|
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
|
|
} else {
|
|
} else {
|
|
|
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
|
|
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
|