mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-15 22:10:26 +00:00
Routing: Fix process for macOS IPv4-mapped sockets (#6557)
Fixes https://github.com/XTLS/Xray-core/issues/6533
This commit is contained in:
@@ -198,7 +198,9 @@ func darwinSocketInfoMatchLevel(info []byte, network string, srcAddr netip.Addr,
|
|||||||
|
|
||||||
vflag := info[darwinInSockInfoVFlagOff]
|
vflag := info[darwinInSockInfoVFlagOff]
|
||||||
if srcAddr.Is4() {
|
if srcAddr.Is4() {
|
||||||
if family != unix.AF_INET || vflag&darwinInSockInfoIPv4 == 0 {
|
// Dual-stack sockets expose IPv4-mapped connections as AF_INET6
|
||||||
|
// while marking the endpoint as IPv4 in ini_vflag.
|
||||||
|
if (family != unix.AF_INET && family != unix.AF_INET6) || vflag&darwinInSockInfoIPv4 == 0 {
|
||||||
return darwinSocketNoMatch
|
return darwinSocketNoMatch
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -52,6 +52,57 @@ func TestFindProcessDarwinTCP(t *testing.T) {
|
|||||||
assertCurrentProcess(t, pid, name, path)
|
assertCurrentProcess(t, pid, name, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindProcessDarwinTCPIPv4Mapped(t *testing.T) {
|
||||||
|
listener, err := stdnet.Listen("tcp4", "127.0.0.1:0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
|
||||||
|
accepted := make(chan stdnet.Conn, 1)
|
||||||
|
go func() {
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err == nil {
|
||||||
|
accepted <- conn
|
||||||
|
return
|
||||||
|
}
|
||||||
|
close(accepted)
|
||||||
|
}()
|
||||||
|
|
||||||
|
listenerAddr := listener.Addr().(*stdnet.TCPAddr)
|
||||||
|
fd, err := unix.Socket(unix.AF_INET6, unix.SOCK_STREAM, unix.IPPROTO_TCP)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer unix.Close(fd)
|
||||||
|
|
||||||
|
mappedAddr := [16]byte{10: 0xff, 11: 0xff, 12: 127, 15: 1}
|
||||||
|
if err := unix.Connect(fd, &unix.SockaddrInet6{
|
||||||
|
Port: listenerAddr.Port,
|
||||||
|
Addr: mappedAddr,
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverConn := <-accepted
|
||||||
|
if serverConn == nil {
|
||||||
|
t.Fatal("server did not accept tcp connection")
|
||||||
|
}
|
||||||
|
defer serverConn.Close()
|
||||||
|
|
||||||
|
local, err := unix.Getsockname(fd)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
localPort := local.(*unix.SockaddrInet6).Port
|
||||||
|
|
||||||
|
pid, name, path, err := FindProcess("tcp", "127.0.0.1", uint16(localPort), "127.0.0.1", uint16(listenerAddr.Port))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assertCurrentProcess(t, pid, name, path)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFindProcessDarwinUDP(t *testing.T) {
|
func TestFindProcessDarwinUDP(t *testing.T) {
|
||||||
conn, err := stdnet.ListenUDP("udp", &stdnet.UDPAddr{IP: stdnet.ParseIP("127.0.0.1")})
|
conn, err := stdnet.ListenUDP("udp", &stdnet.UDPAddr{IP: stdnet.ParseIP("127.0.0.1")})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -264,6 +315,18 @@ func TestDarwinSocketInfoMatchLevelFallbacks(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDarwinSocketInfoMatchLevelIPv4Mapped(t *testing.T) {
|
||||||
|
src := netip.MustParseAddr("127.0.0.1")
|
||||||
|
dst := netip.MustParseAddr("203.0.113.10")
|
||||||
|
info := newDarwinSocketInfo("tcp", src, 12345, dst, 443)
|
||||||
|
writeDarwinNativeUint32(info, darwinSocketInfoFamilyOff, uint32(unix.AF_INET6))
|
||||||
|
|
||||||
|
level := darwinSocketInfoMatchLevel(info, "tcp", src, 12345, dst, 443, true)
|
||||||
|
if level != darwinSocketExactMatch {
|
||||||
|
t.Fatalf("unexpected match level: got %d, want %d", level, darwinSocketExactMatch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newDarwinSocketInfo(network string, local netip.Addr, localPort uint16, remote netip.Addr, remotePort uint16) []byte {
|
func newDarwinSocketInfo(network string, local netip.Addr, localPort uint16, remote netip.Addr, remotePort uint16) []byte {
|
||||||
info := make([]byte, darwinSocketFDInfoSize)
|
info := make([]byte, darwinSocketFDInfoSize)
|
||||||
switch network {
|
switch network {
|
||||||
|
|||||||
Reference in New Issue
Block a user