From ee13bbd9cffcd0db42f2a3b5480e2c7b792a8e17 Mon Sep 17 00:00:00 2001 From: gVisor bot Date: Sat, 26 Nov 2022 11:27:24 +0800 Subject: [PATCH] Fix: drop UDP packet which mismatched destination for VMess (#2410) Co-authored-by: SUN Sizhe --- adapter/outbound/vmess.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index 31d0a2cf..aaa9105d 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -20,6 +20,8 @@ import ( "golang.org/x/net/http2" ) +var ErrUDPRemoteAddrMismatch = errors.New("udp packet dropped due to mismatched remote address") + type Vmess struct { *Base client *vmess.Client @@ -358,7 +360,14 @@ type vmessPacketConn struct { rAddr net.Addr } +// WriteTo implments C.PacketConn.WriteTo +// Since VMess doesn't support full cone NAT by design, we verify if addr matches uc.rAddr, and drop the packet if not. func (uc *vmessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { + allowedAddr := uc.rAddr.(*net.UDPAddr) + destAddr := addr.(*net.UDPAddr) + if !(allowedAddr.IP.Equal(destAddr.IP) && allowedAddr.Port == destAddr.Port) { + return 0, ErrUDPRemoteAddrMismatch + } return uc.Conn.Write(b) }