diff --git a/proxy/redir/udp.go b/proxy/redir/udp.go index 83506d86..89209aa9 100644 --- a/proxy/redir/udp.go +++ b/proxy/redir/udp.go @@ -35,8 +35,7 @@ func NewRedirUDPProxy(addr string) (*RedirUDPListener, error) { oob := make([]byte, 1024) for { buf := pool.BufPool.Get().([]byte) - - n, oobn, _, remoteAddr, err := c.ReadMsgUDP(buf, oob) + n, oobn, _, lAddr, err := c.ReadMsgUDP(buf, oob) if err != nil { pool.BufPool.Put(buf[:cap(buf)]) if rl.closed { @@ -45,11 +44,11 @@ func NewRedirUDPProxy(addr string) (*RedirUDPListener, error) { continue } - origDst, err := getOrigDst(oob, oobn) + rAddr, err := getOrigDst(oob, oobn) if err != nil { continue } - handleRedirUDP(l, buf[:n], remoteAddr, origDst) + handleRedirUDP(l, buf[:n], lAddr, rAddr) } }() @@ -65,13 +64,11 @@ func (l *RedirUDPListener) Address() string { return l.address } -func handleRedirUDP(pc net.PacketConn, buf []byte, addr *net.UDPAddr, origDst *net.UDPAddr) { - target := socks5.ParseAddrToSocksAddr(origDst) - +func handleRedirUDP(pc net.PacketConn, buf []byte, lAddr *net.UDPAddr, rAddr *net.UDPAddr) { + target := socks5.ParseAddrToSocksAddr(rAddr) packet := &fakeConn{ PacketConn: pc, - origDst: origDst, - rAddr: addr, + lAddr: lAddr, buf: buf, } tunnel.AddPacket(adapters.NewPacket(target, packet, C.REDIR)) diff --git a/proxy/redir/utils.go b/proxy/redir/utils.go index 71756d4d..f6a60d46 100644 --- a/proxy/redir/utils.go +++ b/proxy/redir/utils.go @@ -8,18 +8,17 @@ import ( type fakeConn struct { net.PacketConn - origDst net.Addr - rAddr net.Addr - buf []byte + lAddr *net.UDPAddr + buf []byte } func (c *fakeConn) Data() []byte { return c.buf } -// WriteBack opens a new socket binding `origDst` to wirte UDP packet back +// WriteBack opens a new socket binding `addr` to wirte UDP packet back func (c *fakeConn) WriteBack(b []byte, addr net.Addr) (n int, err error) { - tc, err := dialUDP("udp", c.origDst.(*net.UDPAddr), c.rAddr.(*net.UDPAddr)) + tc, err := dialUDP("udp", addr.(*net.UDPAddr), c.lAddr) if err != nil { n = 0 return @@ -31,7 +30,7 @@ func (c *fakeConn) WriteBack(b []byte, addr net.Addr) (n int, err error) { // LocalAddr returns the source IP/Port of UDP Packet func (c *fakeConn) LocalAddr() net.Addr { - return c.rAddr + return c.lAddr } func (c *fakeConn) Close() error { diff --git a/tunnel/connection.go b/tunnel/connection.go index b1d9978c..9553ed73 100644 --- a/tunnel/connection.go +++ b/tunnel/connection.go @@ -88,7 +88,7 @@ func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata DefaultManager.Upload() <- int64(len(packet.Data())) } -func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string) { +func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, fAddr net.Addr) { buf := pool.BufPool.Get().([]byte) defer pool.BufPool.Put(buf[:cap(buf)]) defer natTable.Delete(key) @@ -101,6 +101,10 @@ func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string) { return } + if fAddr != nil { + from = fAddr + } + n, err = packet.WriteBack(buf[:n], from) if err != nil { return diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index b35688aa..7dbb61e0 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -182,6 +182,12 @@ func handleUDPConn(packet *inbound.PacketAdapter) { return } + // make a fAddr if requset ip is fakeip + var fAddr net.Addr + if enhancedMode != nil && enhancedMode.IsFakeIP(metadata.DstIP) { + fAddr = metadata.UDPAddr() + } + if err := preHandleMetadata(metadata); err != nil { log.Debugln("[Metadata PreHandle] error: %s", err) return @@ -231,7 +237,7 @@ func handleUDPConn(packet *inbound.PacketAdapter) { natTable.Set(key, pc) natTable.Delete(lockKey) wg.Done() - go handleUDPToLocal(packet.UDPPacket, pc, key) + go handleUDPToLocal(packet.UDPPacket, pc, key, fAddr) } wg.Wait()