Skip to content

feat(harmony): 移植隧道解析器决策规则(对齐上游 DNS 修复 #266) - #37

Merged
nicholyx merged 1 commit into
mainfrom
feat/harmony-dns-resolver
Sep 17, 2026
Merged

nicholyx merged 1 commit into
mainfrom
feat/harmony-dns-resolver

Conversation

@nicholyx

Copy link
Copy Markdown
Owner

为什么

上游刚修了隧道解析器的一个静默失效(netbirdio#266 / be8ec8e,已随 #35 合入 main):
判据用「Private DNS 是否活跃」时,Automatic 模式(运营商与不少家庭网络的
默认状态)会被误判成冲突,于是 NetBird 域名与自定义 DNS 区域解析不了,而且
能否解析取决于重建隧道时手机所处的网络——同一台设备换个网就变。

鸿蒙侧目前完全没有解析器决策概念。真实引擎接入(Roadmap #25)时若重新发明
这条规则,极可能原样重蹈上游的坑。对应 Issue #36。

做了什么

  • engine/TunnelDns.ets(新):判据落成纯函数——只有平台钉了 Private DNS
    主机名才排除解析器;Automatic / Off 都保留。含上游来由的完整注释
  • 与既有用户设置组合:AdvancedSettings.disableDns(Advanced → Disable DNS)
    打开时不装解析器
  • 引擎缝接线(两个新契约方法):
    • VpnEngine.tunnelDnsServer() —— 隧道实际装入的解析器,空串表示没装,
      对齐 Android IFace.prepareDnsSetting
    • VpnEngine.setAdvancedOptions() —— 高级设置下发引擎的通道
  • EngineManager.saveAdvanced() 现在真的把设置发给引擎
  • logic-tests 补三条断言;本机 hvigorw assembleHap 真实编译通过

关键取舍

为什么规则放引擎缝,而不是 UI 层随手判断? 判据要被真实引擎遵守,且必须
可测。放在引擎层 + 纯函数,logic-tests 能真实执行它(node --test 转译跑),
未来真实实现直接复用,不必重新发明。

为什么给 VpnEngine 加两个方法,而不是只留一个没人调用的策略模块? 只写一个
没有调用者的纯函数等于死代码,且下次有人实现引擎时未必会去找它。挂到契约上
(并由 MockVpnEngine 实现 + static-verify 校验「接口方法全部实现」)才是一条
活的约定:tunnelDnsServer() 对应 Android 的 addDnsServer 行为,
setAdvancedOptions() 对应 Android 把配置传给 Go 内核的路径。

顺带补齐一个真实缺口:setAdvancedOptions 之前,鸿蒙侧的高级设置只写进
AppStorage、从未到达引擎层——Advanced 页除主题外的开关都是「有界面、无行为」的。
本次先把通道建起来,disableDns 已是真行为;其余字段由真实引擎接入时接上。

不加 UI:Android 的 Troubleshoot 与 Advanced 都没有 DNS 呈现面(已核对
TroubleshootFragment 与布局文件),鸿蒙保持一致。呈现问题留给真实引擎接入时
单独评估,不在本次顺手发明。

被否的方案:照搬 Android 让引擎自己去读平台设置。鸿蒙无等价平台能力,
故 mock 侧按「未配置」处理,但规则本身完整保留并全覆盖测试——真实实现只需
把平台值读出来传进同一个函数。

测试策略

  • node tools/run-all-tests.mjs → 20/20 通过(新增 3 条):
    • 判据真值表:null(Off/Automatic)保留、空串保留、主机名排除
    • disableDns 与判据的四象限组合
    • mock 端集成:默认装入 100.72.68.1,disableDns 后为空
  • node tools/static-verify.mjs → 55 项 0 失败;引擎缝完整性检查
    「MockVpnEngine implements all 17 VpnEngine methods」(新增的两个方法
    也在这个检查的约束内,不会漏实现)
  • 本机真实编译 hvigorw assembleHap → BUILD SUCCESSFUL
    (规范里的头号教训:静态验证查不出 ArkTS 严格模式错误,必须过编译器)
  • bash scripts/lint.sh → 全绿

Closes #36

对应 Issue #36。上游 netbirdio#266 修过一次静默解析失败:判据用「Private DNS 是否
活跃」时,Automatic 模式(运营商与不少家庭网络默认)被误判,NetBird 域名与
自定义 DNS 区域解析不了,且能否解析随手机所在网络变化。只有**配置了**
Private DNS 主机名才真的冲突——系统把查询全走 TLS 发给该主机并拒绝明文 DNS。

- 新增 engine/TunnelDns.ets:判据落成纯函数(只有主机名才排除),并与既有
  AdvancedSettings.disableDns 组合;含上游来由注释,避免真实引擎重新发明判据
- VpnEngine 新增两个契约方法:tunnelDnsServer()(隧道实际装入的解析器,对齐
  Android IFace.prepareDnsSetting)、setAdvancedOptions()(高级设置下发引擎)
- EngineManager.saveAdvanced 真正把设置下发给引擎——此前只写 AppStorage,
  Advanced 里除主题外的开关是「有界面、无行为」的
- logic-tests 补三条断言:判据真值表(null/空串/主机名)、disableDns 组合、
  mock 端集成;本机 hvigorw 真实编译通过(静态验证替代不了编译器)
- 不加 UI:Android 的 Troubleshoot/Advanced 都没有 DNS 呈现面,保持一致
@github-actions github-actions Bot added documentation Improvements or additions to documentation harmony HarmonyOS 客户端 labels Sep 17, 2026
@nicholyx
nicholyx merged commit f30a4f0 into main Sep 17, 2026
11 checks passed
@nicholyx
nicholyx deleted the feat/harmony-dns-resolver branch September 17, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation harmony HarmonyOS 客户端

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(harmony): 移植隧道解析器决策规则(对齐上游 DNS 修复 #266)

1 participant