ITADN

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

#6533Closedmymyme 创建于 2026-07-23
M
mymymecommented
### 完整性要求 - [x] 我读完了 issue 模板中的所有注释,确保填写符合要求。 - [x] 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。 - [x] 我提供了完整的配置文件和日志,而不是出于自己的判断只给出截取的部分。 - [x] 我搜索了 issues, 没有发现已提出的类似问题。 - [x] 问题在 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.go` 的 `darwinSocketInfoMatchLevel`: ```go 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 字节,现有 `darwinAddrMatches` 的 `raw[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: ```python 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") ``` 3. 观察日志: - 非 root:两种客户端全部报 `process not found`(问题二) - root:AF_INET 客户端正常,双栈客户端报 `process not found`(问题一) ### 客户端配置 <details><pre><code> { "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" } ] } } </code></pre></details> ### 服务端配置 <details><pre><code> 无需服务端。仅本机 socks 入站 + freedom 出站即可复现(见客户端配置),bug 触发点在路由 process 规则评估阶段,与出站无关。 </code></pre></details> ### 客户端日志 <details><pre><code> (非 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 </code></pre></details> ### 服务端日志 <details><pre><code> 不适用(无服务端,freedom 直连复现)。 </code></pre></details>
关闭于 13 天前 1 条评论