Skip to content

macOS 路由 process 匹配:双栈 socket(IPv4-mapped)连接始终 process not found;非 root 运行时进程查找完全失效 #6533

Description

@mymyme

完整性要求

  • 我读完了 issue 模板中的所有注释,确保填写符合要求。
  • 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
  • 我提供了完整的配置文件和日志,而不是出于自己的判断只给出截取的部分。
  • 我搜索了 issues, 没有发现已提出的类似问题。
  • 问题在 Release 最新的版本上可以成功复现

描述

环境:macOS 26(Darwin 25.5.0)arm64,Xray 26.7.11 官方 release(50231ea)。#6447 引入的 macOS 进程查找存在两个问题。

问题一(主要):双栈 socket 的 IPv4 连接永远无法匹配

.NET / Java 等运行时默认创建 AF_INET6 双栈 socket,以 v4-mapped(::ffff:a.b.c.d)方式连接 IPv4 目标。此类连接在路由评估 process 规则时 100% 报 process not found

代码原因:common/net/find_process_darwin.godarwinSocketInfoMatchLevel

if srcAddr.Is4() {
	if family != unix.AF_INET || vflag&darwinInSockInfoIPv4 == 0 {
		return darwinSocketNoMatch
	}
}

实测内核数据(proc_pidfdinfo PROC_PIDFDSOCKETINFO,arm64):双栈 v4-mapped TCP 连接呈现 soi_family=30 (AF_INET6)insi_vflag=0x1 (INI_IPV4),被 family != unix.AF_INET 排除。

修复建议:family == unix.AF_INET6 && vflag&darwinInSockInfoIPv4 != 0 的条目也应参与 IPv4 匹配。地址比较无需改动:insi_laddr/insi_faddr 是 in4in6 布局,IPv4 地址在 16 字节的最后 4 字节,现有 darwinAddrMatchesraw[12:16] 比较已兼容。

实际影响:v2rayN macOS 每秒轮询 metrics(/debug/vars)的 .NET HttpClient 即双栈 socket,Error 日志每秒刷屏;所有 .NET/Java 桌面应用的流量都无法按 process 分流。

问题二(附加):非 root 运行时查找对任何进程都失败

非 root 启动 xray(普通代理模式,无 TUN),即使纯 AF_INET 的同用户客户端也一律 process not found(见日志:AF_INET + IP 目标、域名目标、目标恰为代理端口三种情况全部失败)。

同一台机器上用 C 复刻同一算法(sysctl kern.proc.all → proc_pidinfo(PROC_PIDLISTFDS) → proc_pidfdinfo(PROC_PIDFDSOCKETINFO)),非 root 可正确命中目标进程(996 个进程枚举、683 个 fd 可访问、精确命中 1 个)。已逐一核对 struct socket_fdinfo 相关 offset 与实现中的硬编码常量完全一致(sizeof=792、proc_fdinfo=8、psi=24、soi_protocol=180、soi_family=184、soi_kind=256、tcpsi_ini=264、insi_lport=268、insi_vflag=288、insi_faddr=296、insi_laddr=312)。

root 运行时 AF_INET 客户端可正常匹配(TUN 生产环境日志验证:浏览器流量无报错,仅双栈客户端报错),因此问题二仅影响非 root 部署。

重现方式

  1. 非 root 启动:xray run -c config.json(配置见下,仅 socks 入站 + freedom 出站 + 一条 process 规则,无需服务端)
  2. 运行以下 python 客户端,先后用 AF_INET 与 AF_INET6 双栈 socket 通过 socks5 发起 CONNECT:
import socket, struct, time

def socks5_request(family, connect_addr, label):
    s = socket.socket(family, socket.SOCK_STREAM)
    try:
        s.settimeout(3)
        s.connect((connect_addr, 11080))
        s.sendall(b"\x05\x01\x00")
        s.recv(2)
        s.sendall(b"\x05\x01\x00\x01" + socket.inet_aton("127.0.0.1") + struct.pack(">H", 11081))
        try:
            s.recv(10)
        except socket.timeout:
            pass
        print(f"{label}: local port {s.getsockname()[1]}")
    finally:
        s.close()

socks5_request(socket.AF_INET, "127.0.0.1", "AF_INET")
time.sleep(0.5)
socks5_request(socket.AF_INET6, "::ffff:127.0.0.1", "AF_INET6 dual-stack v4-mapped")
  1. 观察日志:
    • 非 root:两种客户端全部报 process not found(问题二)
    • root:AF_INET 客户端正常,双栈客户端报 process not found(问题一)

客户端配置

Details

{
  "log": {
    "loglevel": "debug"
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 11080,
      "protocol": "socks",
      "tag": "socks-in"
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "direct"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "process": ["self/"],
        "outboundTag": "direct"
      }
    ]
  }
}

服务端配置

Details

无需服务端。仅本机 socks 入站 + freedom 出站即可复现(见客户端配置),bug 触发点在路由 process 规则评估阶段,与出站无关。

客户端日志

Details

(非 root,最小配置,问题二:AF_INET + IP 目标 / 域名目标 / 目标恰为代理端口,三种情况全部 process not found)

Xray 26.7.11 (Xray, Penetrates Everything.) 50231ea (go1.26.5 darwin/arm64)
A unified platform for anti-censorship.
2026/07/23 17:01:52.170996 [Info] infra/conf/serial: Reading config: &{Name:.../repro-config.json Format:json}
2026/07/23 17:01:52.171774 [Debug] app/log: Logger started
2026/07/23 17:01:52.171906 [Debug] app/proxyman/inbound: creating stream worker on 127.0.0.1:11080
2026/07/23 17:01:52.172033 [Info] transport/internet/tcp: listening TCP on 127.0.0.1:11080
2026/07/23 17:01:53.693980 [Info] [1875774516] proxy/socks: TCP Connect request to tcp:127.0.0.1:11081
2026/07/23 17:01:53.697514 [Error] app/router: Unables to find local process name: common/net: process not found for tcp connection from 127.0.0.1:62467 to 127.0.0.1:11081
2026/07/23 17:01:53.697608 from tcp:127.0.0.1:62467 accepted tcp:127.0.0.1:11081 [socks-in >> direct]
2026/07/23 17:01:54.296428 [Info] [3575305247] proxy/socks: TCP Connect request to tcp:www.example.com:80
2026/07/23 17:01:54.302871 [Error] app/router: Unables to find local process name: common/net: process not found for tcp connection from 127.0.0.1:62474 to :0
2026/07/23 17:01:54.302880 from tcp:127.0.0.1:62474 accepted tcp:www.example.com:80 [socks-in >> direct]
2026/07/23 17:01:54.900447 [Info] [3758766399] proxy/socks: TCP Connect request to tcp:127.0.0.1:11080
2026/07/23 17:01:54.906525 [Error] app/router: Unables to find local process name: common/net: process not found for tcp connection from 127.0.0.1:62478 to 127.0.0.1:11080
2026/07/23 17:01:54.906530 from tcp:127.0.0.1:62478 accepted tcp:127.0.0.1:11080 [socks-in >> direct]

(root + TUN 生产环境,问题一:仅 .NET 双栈客户端每秒轮询报错,浏览器 AF_INET 客户端正常无报错)

2026/07/23 15:24:37.196628 [Error] app/router: Unables to find local process name: common/net: process not found for tcp connection from 127.0.0.1:49548 to 127.0.0.1:49316
2026/07/23 15:24:37.196640 from 127.0.0.1:49548 accepted http://127.0.0.1:49316/debug/vars [socks -> direct]
2026/07/23 15:24:37.745609 from 127.0.0.1:49550 accepted //chat.openai.com:443 [socks >> proxy]
2026/07/23 15:24:38.209920 [Error] app/router: Unables to find local process name: common/net: process not found for tcp connection from 127.0.0.1:49552 to 127.0.0.1:49316

服务端日志

Details

不适用(无服务端,freedom 直连复现)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions