From 161e18299cdb4e3856c0ab1d1324062edea78f72 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+rprx@users.noreply.github.com> Date: Thu, 7 Jan 2021 12:21:27 +0000 Subject: [PATCH] Fix TPROXY UDP/IPv6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/XTLS/Xray-core/issues/137#issuecomment-756064627 十分感谢 @Ninedyz @changyp6 --- proxy/dokodemo/dokodemo.go | 27 ++++++++++++++------------- proxy/dokodemo/fakeudp_linux.go | 15 +-------------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index bae3b106..91b0dc2f 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -163,14 +163,19 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in if !destinationOverridden { writer = &buf.SequentialWriter{Writer: conn} } else { - var addr *net.UDPAddr - var mark int - if dest.Address.Family().IsIP() { - addr = &net.UDPAddr{ - IP: dest.Address.IP(), - Port: int(dest.Port), + back := conn.RemoteAddr().(*net.UDPAddr) + if !dest.Address.Family().IsIP() { + if len(back.IP) == 4 { + dest.Address = net.AnyIP + } else { + dest.Address = net.AnyIPv6 } } + addr := &net.UDPAddr{ + IP: dest.Address.IP(), + Port: int(dest.Port), + } + var mark int if d.sockopt != nil { mark = int(d.sockopt.Mark) } @@ -178,8 +183,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in if err != nil { return err } - back := net.DestinationFromAddr(conn.RemoteAddr()) - writer = NewPacketWriter(pConn, &dest, mark, &back) + writer = NewPacketWriter(pConn, &dest, mark, back) defer writer.(*PacketWriter).Close() /* sockopt := &internet.SocketConfig{ @@ -236,15 +240,12 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in return nil } -func NewPacketWriter(conn net.PacketConn, d *net.Destination, mark int, back *net.Destination) buf.Writer { +func NewPacketWriter(conn net.PacketConn, d *net.Destination, mark int, back *net.UDPAddr) buf.Writer { writer := &PacketWriter{ conn: conn, conns: make(map[net.Destination]net.PacketConn), mark: mark, - back: &net.UDPAddr{ - IP: back.Address.IP(), - Port: int(back.Port), - }, + back: back, } writer.conns[*d] = conn return writer diff --git a/proxy/dokodemo/fakeudp_linux.go b/proxy/dokodemo/fakeudp_linux.go index f793661b..c1eae057 100644 --- a/proxy/dokodemo/fakeudp_linux.go +++ b/proxy/dokodemo/fakeudp_linux.go @@ -6,19 +6,11 @@ import ( "fmt" "net" "os" - "strconv" "syscall" ) func FakeUDP(addr *net.UDPAddr, mark int) (net.PacketConn, error) { - if addr == nil { - addr = &net.UDPAddr{ - IP: []byte{0, 0, 0, 0}, - Port: 0, - } - } - localSocketAddress, af, err := udpAddrToSocketAddr(addr) if err != nil { return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("build local socket address: %s", err)} @@ -75,11 +67,6 @@ func udpAddrToSocketAddr(addr *net.UDPAddr) (syscall.Sockaddr, int, error) { ip := [16]byte{} copy(ip[:], addr.IP.To16()) - zoneID, err := strconv.ParseUint(addr.Zone, 10, 32) - if err != nil { - return nil, 0, err - } - - return &syscall.SockaddrInet6{Addr: ip, Port: addr.Port, ZoneId: uint32(zoneID)}, syscall.AF_INET6, nil + return &syscall.SockaddrInet6{Addr: ip, Port: addr.Port, ZoneId: 0}, syscall.AF_INET6, nil } }