mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-30 09:18:34 +00:00
Add XTLS RPRX's Vision (#1235)
* Add XTLS RPRX's Vision * Add helpful warning when security is wrong * Add XTLS padding (draft) * Fix number of packet to filter * Xtls padding version 1.0 and unpadding logic
This commit is contained in:
parent
341d317d0c
commit
5e695327b1
7 changed files with 420 additions and 56 deletions
|
@ -5,7 +5,6 @@ package outbound
|
|||
import (
|
||||
"context"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
|
@ -25,6 +24,7 @@ import (
|
|||
"github.com/xtls/xray-core/transport"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||
)
|
||||
|
||||
|
@ -128,15 +128,13 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||
}
|
||||
|
||||
var rawConn syscall.RawConn
|
||||
var sctx context.Context
|
||||
|
||||
allowUDP443 := false
|
||||
switch requestAddons.Flow {
|
||||
case vless.XRO + "-udp443", vless.XRD + "-udp443", vless.XRS + "-udp443":
|
||||
case vless.XRO + "-udp443", vless.XRD + "-udp443", vless.XRS + "-udp443", vless.XRV + "-udp443":
|
||||
allowUDP443 = true
|
||||
requestAddons.Flow = requestAddons.Flow[:16]
|
||||
fallthrough
|
||||
case vless.XRO, vless.XRD, vless.XRS:
|
||||
case vless.XRO, vless.XRD, vless.XRS, vless.XRV:
|
||||
switch request.Command {
|
||||
case protocol.RequestCommandMux:
|
||||
return newError(requestAddons.Flow + " doesn't support Mux").AtWarning()
|
||||
|
@ -146,12 +144,18 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||
}
|
||||
requestAddons.Flow = ""
|
||||
case protocol.RequestCommandTCP:
|
||||
if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
||||
if requestAddons.Flow == vless.XRV {
|
||||
if _, ok := iConn.(*xtls.Conn); ok {
|
||||
return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning()
|
||||
}
|
||||
if sc, ok := iConn.(*tls.Conn).NetConn().(syscall.Conn); ok {
|
||||
rawConn, _ = sc.SyscallConn()
|
||||
}
|
||||
} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
||||
xtlsConn.RPRX = true
|
||||
xtlsConn.SHOW = xtls_show
|
||||
xtlsConn.MARK = "XTLS"
|
||||
if requestAddons.Flow == vless.XRS {
|
||||
sctx = ctx
|
||||
requestAddons.Flow = vless.XRD
|
||||
}
|
||||
if requestAddons.Flow == vless.XRD {
|
||||
|
@ -176,6 +180,10 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||
|
||||
clientReader := link.Reader // .(*pipe.Reader)
|
||||
clientWriter := link.Writer // .(*pipe.Writer)
|
||||
isTLS13 := false
|
||||
isTLS12 := false
|
||||
isTLS := false
|
||||
numberOfPacketToFilter := 8
|
||||
|
||||
if request.Command == protocol.RequestCommandUDP && h.cone && request.Port != 53 && request.Port != 443 {
|
||||
request.Command = protocol.RequestCommandMux
|
||||
|
@ -196,17 +204,39 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||
if request.Command == protocol.RequestCommandMux && request.Port == 666 {
|
||||
serverWriter = xudp.NewPacketWriter(serverWriter, target)
|
||||
}
|
||||
if err := buf.CopyOnceTimeout(clientReader, serverWriter, time.Millisecond*100); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {
|
||||
userUUID := account.ID.Bytes()
|
||||
multiBuffer, err1 := clientReader.ReadMultiBuffer()
|
||||
if err1 != nil {
|
||||
return err1 // ...
|
||||
}
|
||||
if requestAddons.Flow == vless.XRV {
|
||||
encoding.XtlsFilterTls13(multiBuffer, &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS, ctx)
|
||||
if isTLS {
|
||||
for i, b := range multiBuffer {
|
||||
multiBuffer[i] = encoding.XtlsPadding(b, 0x00, &userUUID, ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := serverWriter.WriteMultiBuffer(multiBuffer); err != nil {
|
||||
return err // ...
|
||||
}
|
||||
|
||||
// Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer
|
||||
if err := bufferWriter.SetBuffered(false); err != nil {
|
||||
return newError("failed to write A request payload").Base(err).AtWarning()
|
||||
}
|
||||
|
||||
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
|
||||
if err := buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)); err != nil {
|
||||
var err error
|
||||
if rawConn != nil && requestAddons.Flow == vless.XRV {
|
||||
var counter stats.Counter
|
||||
if statConn != nil {
|
||||
counter = statConn.WriteCounter
|
||||
}
|
||||
err = encoding.XtlsWrite(clientReader, serverWriter, timer, iConn.(*tls.Conn), counter, ctx, &userUUID, &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS)
|
||||
} else {
|
||||
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
|
||||
err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer))
|
||||
}
|
||||
if err != nil {
|
||||
return newError("failed to transfer request payload").Base(err).AtInfo()
|
||||
}
|
||||
|
||||
|
@ -236,7 +266,11 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||
if statConn != nil {
|
||||
counter = statConn.ReadCounter
|
||||
}
|
||||
err = encoding.ReadV(serverReader, clientWriter, timer, iConn.(*xtls.Conn), rawConn, counter, sctx)
|
||||
if requestAddons.Flow == vless.XRV {
|
||||
err = encoding.XtlsRead(serverReader, clientWriter, timer, iConn.(*tls.Conn), rawConn, counter, ctx, account.ID.Bytes(), &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS)
|
||||
} else {
|
||||
err = encoding.ReadV(serverReader, clientWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx)
|
||||
}
|
||||
} else {
|
||||
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
|
||||
err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue