Add XTLS Splice to Trojan Outbound

This commit is contained in:
RPRX 2020-12-11 03:05:39 +00:00 committed by GitHub
parent ee19bcc08c
commit b4e84603a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 9 deletions

View file

@ -94,15 +94,16 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
} }
var rawConn syscall.RawConn var rawConn syscall.RawConn
var sctx context.Context
connWriter := &ConnWriter{} connWriter := &ConnWriter{}
allowUDP443 := false allowUDP443 := false
switch account.Flow { switch account.Flow {
case XRO + "-udp443", XRD + "-udp443": case XRO + "-udp443", XRD + "-udp443", XRS + "-udp443":
allowUDP443 = true allowUDP443 = true
account.Flow = account.Flow[:16] account.Flow = account.Flow[:16]
fallthrough fallthrough
case XRO, XRD: case XRO, XRD, XRS:
if destination.Address.Family().IsDomain() && destination.Address.Domain() == muxCoolAddress { if destination.Address.Family().IsDomain() && destination.Address.Domain() == muxCoolAddress {
return newError(account.Flow + " doesn't support Mux").AtWarning() return newError(account.Flow + " doesn't support Mux").AtWarning()
} }
@ -114,13 +115,18 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
if xtlsConn, ok := iConn.(*xtls.Conn); ok { if xtlsConn, ok := iConn.(*xtls.Conn); ok {
xtlsConn.RPRX = true xtlsConn.RPRX = true
xtlsConn.SHOW = trojanXTLSShow xtlsConn.SHOW = trojanXTLSShow
connWriter.Flow = account.Flow xtlsConn.MARK = "XTLS"
if account.Flow == XRS {
sctx = ctx
account.Flow = XRD
}
if account.Flow == XRD { if account.Flow == XRD {
xtlsConn.DirectMode = true xtlsConn.DirectMode = true
}
if sc, ok := xtlsConn.Connection.(syscall.Conn); ok { if sc, ok := xtlsConn.Connection.(syscall.Conn); ok {
rawConn, _ = sc.SyscallConn() rawConn, _ = sc.SyscallConn()
} }
}
connWriter.Flow = account.Flow
} else { } else {
return newError(`failed to use ` + account.Flow + `, maybe "security" is not "xtls"`).AtWarning() return newError(`failed to use ` + account.Flow + `, maybe "security" is not "xtls"`).AtWarning()
} }
@ -185,7 +191,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
if statConn != nil { if statConn != nil {
counter = statConn.ReadCounter counter = statConn.ReadCounter
} }
return ReadV(reader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter) return ReadV(reader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter, sctx)
} }
return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer)) return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))
} }

View file

@ -1,17 +1,21 @@
package trojan package trojan
import ( import (
"context"
"encoding/binary" "encoding/binary"
fmt "fmt" fmt "fmt"
"io" "io"
"runtime"
"syscall" "syscall"
"github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/signal" "github.com/xtls/xray-core/common/signal"
"github.com/xtls/xray-core/features/stats" "github.com/xtls/xray-core/features/stats"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/xtls" "github.com/xtls/xray-core/transport/internet/xtls"
) )
@ -29,6 +33,8 @@ var (
const ( const (
maxLength = 8192 maxLength = 8192
// XRS is constant for XTLS splice mode
XRS = "xtls-rprx-splice"
// XRD is constant for XTLS direct mode // XRD is constant for XTLS direct mode
XRD = "xtls-rprx-direct" XRD = "xtls-rprx-direct"
// XRO is constant for XTLS origin mode // XRO is constant for XTLS origin mode
@ -307,12 +313,39 @@ func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
return &PacketPayload{Target: dest, Buffer: mb}, nil return &PacketPayload{Target: dest, Buffer: mb}, nil
} }
func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *xtls.Conn, rawConn syscall.RawConn, counter stats.Counter) error { func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *xtls.Conn, rawConn syscall.RawConn, counter stats.Counter, sctx context.Context) error {
err := func() error { err := func() error {
var ct stats.Counter var ct stats.Counter
for { for {
if conn.DirectIn { if conn.DirectIn {
conn.DirectIn = false conn.DirectIn = false
if sctx != nil {
if inbound := session.InboundFromContext(sctx); inbound != nil && inbound.Conn != nil {
iConn := inbound.Conn
statConn, ok := iConn.(*internet.StatCouterConnection)
if ok {
iConn = statConn.Connection
}
if tc, ok := iConn.(*net.TCPConn); ok {
if conn.SHOW {
fmt.Println(conn.MARK, "Splice")
}
runtime.Gosched() // necessary
w, err := tc.ReadFrom(conn.Connection)
if counter != nil {
counter.Add(w)
}
if statConn != nil && statConn.WriteCounter != nil {
statConn.WriteCounter.Add(w)
}
return err
} else {
panic("XTLS Splice: not TCP inbound")
}
} else {
//panic("XTLS Splice: nil inbound or nil inbound.Conn")
}
}
reader = buf.NewReadVReader(conn.Connection, rawConn) reader = buf.NewReadVReader(conn.Connection, rawConn)
ct = counter ct = counter
if conn.SHOW { if conn.SHOW {

View file

@ -310,7 +310,7 @@ func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Sess
if statConn != nil { if statConn != nil {
counter = statConn.ReadCounter counter = statConn.ReadCounter
} }
err = ReadV(clientReader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter) err = ReadV(clientReader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter, nil)
} else { } else {
err = buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)) err = buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer))
} }