Skip to content

[问题报告 BUG]HarmonyOS 6 后台或锁屏后 VPN 长时间运行出现断流 #158

Description

@muyuqingqiu

问题说明

在 HarmonyOS 6.0 以上系统中,ClashBox 开启 VPN 后切到后台或锁屏,运行一段时间后可能出现数据通道停止转发。应用页面和系统状态仍显示 VPN 正在运行,但新的网络请求无法通过代理出口;停止并重新启动 VPN 后,网络通常可以恢复。

该问题不是简单的应用崩溃或进程被系统结束。断流时曾观察到应用进程、VPN 进程、vpn-tun 网卡和 TCP/UDP 7890 端口仍然存在,亮屏状态也可以复现。

同一个 ClashBox 包同时在普通空间和隐私空间运行时,还会竞争系统 VPN 和 7890 端口,造成刚启动就没有代理。这是独立的账号实例冲突。复现长时间后台问题时,应只保留一个账号实例运行。

影响范围

  • 后台或锁屏后,浏览器、Google、出境易、Google Play 和游戏等依赖 VPN 的网络请求可能停止正常转发。
  • 断流时 VPN 图标和应用运行状态可能仍然保持,容易被误判为连接正常。
  • 完全停止并重新启动 VPN 可以恢复部分现场的代理出口和新请求。
  • 浏览器和 Google 的访问已有现场恢复记录;出境易真实账号下载和后台行为仍需在实际使用条件下确认。

环境

项目 环境
设备 HUAWEI Mate 60 Pro(ALN-AL80)
系统 HarmonyOS 7.0.0,API 26
网络 Wi-Fi,设备未插入 SIM 卡
应用 ClashBox 1.7.4
目标应用 出境易
VPN 网卡 vpn-tun,地址 172.19.0.1
TUN MTU 1400
代理端口 TCP、UDP 7890

复现步骤

  1. 在普通空间中只保留一个 ClashBox 实例运行,停止隐私空间中的同包实例。
  2. 启动 ClashBox,选择可用节点并开启 VPN。
  3. 确认代理出口已经切换,并用浏览器或 Google 产生新的网络请求。
  4. 将 ClashBox 切到后台,或锁定屏幕,继续保持 VPN 和代理网络运行。
  5. 持续使用代理网络,直到出现新的请求无法联网或数据不再增长的情况。
  6. 解锁后不要先重启 VPN,直接重新访问网页并观察出口、请求结果、vpn-tun 流量和 7890 端口状态。
  7. 记录断流时的运行状态;完成观察后再停止并重新启动 VPN,对比恢复结果。

实际结果

  • 页面和系统仍可能显示 VPN 已启动,应用进程、VPN 进程、vpn-tun 和 7890 端口也仍然存在。
  • vpn-tun 收发计数在一段时间内停止增长,新的连接停留在等待建立状态,没有形成有效代理出口连接。
  • 断流时没有发现 ClashBox 崩溃记录,亮屏和锁屏场景都出现过相同的数据通道停止现象。
  • 使用 GvisorMixed 模式不能稳定消除问题;完整停止并重新启动 VPN 后,同一节点可以恢复代理出口和数据传输。
  • TUN 与系统网卡 MTU 不一致时,现场出现发送丢包持续增加的情况。
  • 普通空间和隐私空间同时运行同包应用时,7890 可能被其中一个账号持有,另一个账号显示运行但没有正常代理出口。

期望结果

  • ClashBox 在后台或锁屏期间持续保持 VPN 连接和流量转发。
  • 解锁后不需要重启 VPN,新的网页和应用请求即可通过所选代理出口完成连接。
  • VPN、TUN、IPC 和出口保护连接的启动、停止、重启按顺序完成,不残留旧连接或错误状态。
  • TUN 收发数据能够随真实请求继续变化,丢包和文件句柄不出现持续单向增长。
  • 同一个账号只运行一个 ClashBox 实例时,VPN 和 7890 端口由该实例稳定使用。

调查结果

已确认的故障链路

  1. 本地 IPC 消息边界和连接回收不可靠:ArkTS 与 Go 核心之间的本地 Socket 可能拆分或合并消息,原处理不能稳定判断一条 JSON 消息是否完整。普通状态请求和长连接没有可靠关闭时,文件句柄会持续累积,达到核心保护阈值后可能阻止新连接。
  2. TUN 启停存在假成功和竞态:TUN 创建、关闭在后台异步执行,上层可能在真实结果返回前收到成功状态;快速停止再启动时,晚到的停止操作可能关闭新建立的 TUN。
  3. 出口 Socket 保护失败后仍可能继续拨号protect 超时或失败没有及时终止本次拨号,确认记录也可能累积,造成出口回环或新连接无法建立。
  4. VPN 启停缺少统一排队和完整清理:页面操作、系统回调和恢复流程可能交叉执行,旧 TUN、保护连接和系统 VPN 销毁状态没有统一等待。
  5. 后台定时器在异常路径中没有及时释放:实况窗系统接口失败时,原停止流程可能提前中断,留下重复的每秒任务,反复启停后持续消耗主进程资源。
  6. TUN MTU 与系统网卡不一致:代理核心原先使用 9000,而真机 vpn-tun 为 1400;大流量时会放大发包和队列压力。
  7. 账号实例冲突可以单独造成即时无代理:普通空间和隐私空间同时运行同包应用时会竞争系统 VPN 和 7890 端口。该现象与长时间后台断流需要分开判断。

公开上游现状

  • ClashBox 仓库未归档、未禁用。公开默认分支是 main,当前 HEAD 为 f78de056;源代码所在的公开 master 当前 HEAD 为 1fdc47eb。当前候选基于 master,贡献目标分支需要维护者确认。
  • ClashBox 已合并的 PR #147PR #151 分别处理 IPv6 路由和 DNS hijack 配置,没有覆盖本 Issue 中的 IPC、TUN 读取、出口保护、启停队列、后台定时器或 MTU 方向。
  • 父仓当前配置的 Mihomo 目标是 xfz347/Clash.Meta,其公开默认分支 HEAD 为 53b2dbba,公开内容与当前 HarmonyOS 候选不是同一代码项目。当前候选的历史更接近 MetaCubeX/mihomoMeta 分支,其公开 HEAD 为 e26714a1;目标仓库、基线和是否保留版本升级需要维护者确认。
  • gVisor 公开默认分支为 meta-20250325-9e676ea1de20,公开 ohos 分支为 ohos。当前 TUN 候选建立在公开 ohos 分支之后,候选提交尚未出现在公开引用中,目标分支需要维护者确认。
  • ClashBox 最近公开 Release 为 1.7.4,没有公开证据表明本 Issue 所述候选已经被上游接收、合并或发布。

相近问题

ClashBox 已有多个 HarmonyOS、VPN、TUN 和应用流量异常的相近 Issue:

  • #24 记录了系统频繁断开并重连 VPN,但没有当前问题的后台或锁屏长时间运行、VPN 仍显示运行和 TUN 停止转发条件。
  • #80 记录了全局模式下出口未切换和没有网络速率,关注点是 TUN 路由或 DNS,不是长时间运行后的数据通道停止。
  • #98#102#113 记录了出境易、卓易通或原生鸿蒙应用的代理范围差异,没有同时确认后台或锁屏长时间运行后的转发停止。
  • #121 记录了平板设备经常代理失败;#132 记录了系统代理不可用;两者都没有当前问题的完整长稳条件。
  • #146 记录了鸿蒙 6.1 节点超时;#154#155 分别涉及 Tailscale 权限和配置加载。

公开搜索和 Issue、Pull Request 列表没有找到同时具备“后台或锁屏、长时间运行、VPN 仍显示运行但 TUN 或出口停止转发”完整条件的主 Issue。这些公开记录只用于说明现象差异,不能直接视为同一个问题或等价修复。

修复方向

父仓候选

当前候选父仓分支为 fix/harmonyos-vpn-stability-pr,基于公开 master1fdc47eb,包含以下五个提交:

  1. f61f09680377f8bab0e767873402cbc476b087a5:升级 Mihomo 并恢复 HarmonyOS 接入。
  2. 1a4595b161a393094a2111aa0ecce423e197c004:修复 HarmonyOS TUN 长期转发停滞。
  3. 7b9119411861f96f1a92ea312e79939b844dd59d:修复 VPN 启停与出口 Socket 保护竞态。
  4. 4b011af85dedd627e7a92e1e0d8f2da354f3426e:清理实况窗重复后台定时器。
  5. e163d6ed9250f933e8104fe1196c8db84be93bcb:更新鸿蒙代理核心产物。

代码改动范围

  • IPC 使用完整消息边界处理拆包、合包和尾部数据;请求完成后关闭普通连接,长连接在客户端断开后回收。
  • TUN 创建和关闭改为等待真实结果;只有核心真实启动成功才报告 TUN_STARTED,失败、超时和提前断开会清理系统 VPN。
  • 出口 Socket 使用独立保护请求和确认通道;保护失败或超时终止本次拨号,确认记录使用后删除,停止 VPN 时清理未完成记录。
  • VPN 启动、停止和重启进入统一队列,等待核心、保护连接和系统 VPN 完整销毁。
  • 实况窗启动和停止统一排队;定时器在启动失败、停止和系统接口异常时都先清理,避免重复累积。实况窗系统功能本身仍有上下文初始化问题,不作为本 Issue 的修复目标。
  • 代理核心 TUN MTU 统一为 1400,并补齐 HarmonyOS 网卡查询和默认地址处理。

子模块候选

  • Mihomo 候选提交为 22810ffba3cb4935a38026eb7220db92af5095a7,包含 HarmonyOS 接入恢复和相关适配,涉及 22 个文件;目标仓库和基线待维护者指定。
  • gVisor 候选提交为 2d619610b188453dfb51eea6322c62e9ce29d676,在 ohos 分支基础上为 TUN 读取增加 100 毫秒轮询,并避免单个异常包使整个读取循环退出;目标分支待维护者指定。
  • 候选核心二进制是否随父仓贡献提交,以及父仓、子模块和核心产物如何拆分,交由维护者确认。

以上内容是待审核的本地候选,不表示任何提交已经被维护者接受、合并或发布。

验证状态

已完成验证

  • IPC 单元测试通过,退出码为 0
  • Mihomo 相关包测试通过,退出码为 0
  • gVisor 相关代码编译通过,退出码为 0
  • HarmonyOS ARM64 代理核心构建通过,退出码为 0
  • HarmonyOS 无签名 release 构建通过,退出码为 0
  • 验证版本已完成真机安装,安装退出码为 0
  • 普通空间完成 VPN 启动、停止、再次启动、MTU 1400、短时零丢包、香港出口和 Google 访问验证。
  • 普通空间完成锁屏五分钟验证,共 11 个采样;解锁后可以产生新的 Google 请求,出口和 VPN 数据通道仍可用。
  • 隐私空间完成验证版本的短时启停回归和锁屏一分钟验证;解锁后的唯一 Google 查询产生了新的 TUN 流量。
  • 实况窗定时器完成一次启动、停止、再次启动的短时不重复累积验证。

历史八小时结果的版本边界

已有一次历史长测产生 689 个样本,覆盖 28,781 秒,最大采样间隔 58 秒,监控退出码为 0;长测后完成 Google 搜索、出境易、Google Play 搜索下载和棕色尘埃2启动验证。

八小时长测所用的验证版本与候选核心产物不属于同一版本绑定。因此该结果只能作为候选修复的历史验证材料,不能写成最终 PR 二进制已经通过八小时验证。进入后续代码贡献阶段前必须重新绑定最终父仓提交、两个子模块提交、核心产物和真机结果。

仍待验证或确认

  • 最终提交组合的八小时或过夜锁屏稳定性。
  • Wi-Fi 断开重连和深度休眠场景。
  • 出境易真实账号、下载任务和后台行为。
  • 父仓、Mihomo、gVisor 的公开目标仓库、分支、基线和提交拆分方式。
  • 是否接受核心二进制更新,以及维护者要求的公开构建和产物绑定材料。

需要维护者确认的问题

  1. 是否接收 HarmonyOS 后台或锁屏后 VPN 长时间运行稳定性问题,复现环境是否按 HUAWEI Mate 60 Pro、HarmonyOS 6.0 以上、Wi-Fi 和单实例条件执行?
  2. 父仓贡献目标应使用 master 还是 main?当前候选是否需要先整理到维护者指定的源分支?
  3. 父仓修复应保持一个 PR,还是按 IPC/TUN、VPN 启停与出口保护、实况窗定时器、Mihomo 接入和核心产物拆分?
  4. Mihomo 修复应提交到 xfz347/Clash.Meta,还是提交到 MetaCubeX/mihomoMeta 分支?采用哪个基线和版本?
  5. gVisor 修复应提交到 ohos、默认分支,还是维护者指定的其他分支?
  6. 父仓是否接受 libflclash.so 更新?如果接受,是否需要公开可复现的源码、工具链、构建标识和摘要绑定?
  7. 是否需要按维护者指定的最小修复范围重新移植,还是可以继续审核当前包含 Mihomo HarmonyOS 接入和稳定性修复的候选组合?
  8. 当前问题是否应与已有相近 Issue 关联或合并,避免重复建立沟通线?

计划公开的材料

  • 本 Issue 正文和必要的公开提交链接。
  • 维护者确认目标仓库和分支后,提供可以公开检出的子模块提交链接。
  • 按维护者要求提供简短的复现结果和测试摘要。

不附加本地证据目录、完整现场记录、大体积材料或与问题无关的个人资料。

公开参考

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions