Browse Source

Fix TPROXY UDP/IPv6

https://github.com/XTLS/Xray-core/issues/137#issuecomment-756064627

十分感谢 @Ninedyz @changyp6
RPRX 4 years ago
parent
commit
161e18299c
2 changed files with 15 additions and 27 deletions
  1. 14 13
      proxy/dokodemo/dokodemo.go
  2. 1 14
      proxy/dokodemo/fakeudp_linux.go

+ 14 - 13
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

+ 1 - 14
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
 	}
 }