From ad3d347cfc1fada5e951ebcd3de9696f69a1f927 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Fri, 2 Feb 2024 20:32:46 +0000 Subject: [PATCH] XTLS Vision: Apply padding to single XUDP by default at client side Requires Xray-core v1.8.1+ at server side: https://github.com/XTLS/Xray-core/commit/242f3b0e0b635699db26a991aa6c0cd47927e8b6 --- proxy/vless/encoding/addons.go | 6 +----- proxy/vless/encoding/encoding.go | 3 +-- proxy/vless/inbound/inbound.go | 1 + proxy/vless/outbound/outbound.go | 12 +++++++++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/proxy/vless/encoding/addons.go b/proxy/vless/encoding/addons.go index e3e5071b..9426f6a0 100644 --- a/proxy/vless/encoding/addons.go +++ b/proxy/vless/encoding/addons.go @@ -62,11 +62,7 @@ func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) { // EncodeBodyAddons returns a Writer that auto-encrypt content written by caller. func EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons, state *proxy.TrafficState, context context.Context) buf.Writer { if request.Command == protocol.RequestCommandUDP { - w := writer.(buf.Writer) - if requestAddons.Flow == vless.XRV { - w = proxy.NewVisionWriter(w, state, context) - } - return NewMultiLengthPacketWriter(w) + return NewMultiLengthPacketWriter(writer.(buf.Writer)) } w := buf.NewWriter(writer) if requestAddons.Flow == vless.XRV { diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index 5fe79c08..455f896b 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -176,7 +176,6 @@ func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*A // XtlsRead filter and read xtls protocol func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, trafficState *proxy.TrafficState, ctx context.Context) error { err := func() error { - visionReader := proxy.NewVisionReader(reader, trafficState, ctx) for { if trafficState.ReaderSwitchToDirectCopy { var writerConn net.Conn @@ -188,7 +187,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater } return proxy.CopyRawConnIfExist(ctx, conn, writerConn, writer, timer) } - buffer, err := visionReader.ReadMultiBuffer() + buffer, err := reader.ReadMultiBuffer() if !buffer.IsEmpty() { timer.Update() if trafficState.ReaderSwitchToDirectCopy { diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 4cd3fcb1..0ffa61d2 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -522,6 +522,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s if requestAddons.Flow == vless.XRV { ctx1 := session.ContextWithInbound(ctx, nil) // TODO enable splice + clientReader = proxy.NewVisionReader(clientReader, trafficState, ctx1) err = encoding.XtlsRead(clientReader, serverWriter, timer, connection, input, rawInput, trafficState, ctx1) } else { // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index cd30617c..a9368813 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -138,7 +138,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte if !allowUDP443 && request.Port == 443 { return newError("XTLS rejected UDP/443 traffic").AtInfo() } - requestAddons.Flow = "" case protocol.RequestCommandMux: fallthrough // let server break Mux connections that contain TCP requests case protocol.RequestCommandTCP: @@ -185,7 +184,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte clientReader := link.Reader // .(*pipe.Reader) clientWriter := link.Writer // .(*pipe.Writer) trafficState := proxy.NewTrafficState(account.ID.Bytes()) - if request.Command == protocol.RequestCommandUDP && h.cone && request.Port != 53 && request.Port != 443 { + if request.Command == protocol.RequestCommandUDP && (requestAddons.Flow == vless.XRV || (h.cone && request.Port != 53 && request.Port != 443)) { request.Command = protocol.RequestCommandMux request.Address = net.DomainAddress("v1.mux.cool") request.Port = net.Port(666) @@ -266,8 +265,15 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte // default: serverReader := buf.NewReader(conn) serverReader := encoding.DecodeBodyAddons(conn, request, responseAddons) + if requestAddons.Flow == vless.XRV { + serverReader = proxy.NewVisionReader(serverReader, trafficState, ctx) + } if request.Command == protocol.RequestCommandMux && request.Port == 666 { - serverReader = xudp.NewPacketReader(conn) + if requestAddons.Flow == vless.XRV { + serverReader = xudp.NewPacketReader(&buf.BufferedReader{Reader: serverReader}) + } else { + serverReader = xudp.NewPacketReader(conn) + } } if requestAddons.Flow == vless.XRV {