From 4c6093c8ae908d15cbf271407a54560d21ae163c Mon Sep 17 00:00:00 2001 From: Fangliding Date: Thu, 5 Nov 2026 16:32:23 +0800 Subject: [PATCH] Fix vless UDP 443 block --- proxy/blackhole/blackhole.go | 11 ++--------- proxy/drop.go | 24 ++++++++++++++++++++++++ proxy/vless/outbound/outbound.go | 1 + 3 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 proxy/drop.go diff --git a/proxy/blackhole/blackhole.go b/proxy/blackhole/blackhole.go index ee0ee7b08..27edeb824 100644 --- a/proxy/blackhole/blackhole.go +++ b/proxy/blackhole/blackhole.go @@ -9,11 +9,10 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" - "github.com/xtls/xray-core/common/signal" + "github.com/xtls/xray-core/proxy" "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/internet" ) @@ -69,14 +68,8 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte } defer common.Interrupt(link.Writer) defer common.Interrupt(link.Reader) - // wait to drain all the possible incoming UDP data if ob.Target.Network == net.Network_UDP { - ctx, cancel := context.WithCancel(ctx) - timer := signal.CancelAfterInactivity(ctx, func() { - cancel() - }, time.Duration(30+dice.Roll(61))*time.Second) - go buf.Copy(link.Reader, buf.Discard, buf.UpdateActivity(timer)) - <-ctx.Done() + proxy.DropUDP(ctx, link.Reader) } return nil } diff --git a/proxy/drop.go b/proxy/drop.go new file mode 100644 index 000000000..b6df202ee --- /dev/null +++ b/proxy/drop.go @@ -0,0 +1,24 @@ +package proxy + +import ( + "context" + "math/rand/v2" + "time" + + "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/buf" + "github.com/xtls/xray-core/common/signal" +) + +// wait to drain all the possible incoming UDP data +// because re-established QUIC UDP may bypass the sniffer +func DropUDP(ctx context.Context, reader buf.Reader) { + ctx, cancel := context.WithCancel(ctx) + timer := signal.CancelAfterInactivity(ctx, func() { + cancel() + }, time.Duration(30+rand.N(60))*time.Second) + context.AfterFunc(ctx, func() { + common.Interrupt(reader) + }) + buf.Copy(reader, buf.Discard, buf.UpdateActivity(timer)) +} diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index 3f6b4b191..29027dd85 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -254,6 +254,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte switch request.Command { case protocol.RequestCommandUDP: if !allowUDP443 && request.Port == 443 { + proxy.DropUDP(ctx, link.Reader) return errors.New("XTLS rejected UDP/443 traffic") } case protocol.RequestCommandMux: