SSRVPN v5.0.15 发布

已发布 v5.0.15,以下为官方变更日志。

官方变更日志

SSRVPN v5.0.15

工程与内核校验

  • 修复 PR 模板中遗留的两页、IPv4-only 要求,统一为现行三页、双栈策略;纯文档 CI

同样校验硬规则编号和审查说明,删除规则文件、重复编号或过时要求会阻断合并。

  • Android 定制内核补齐 -ssrvpn.1 版本标识并按规范主机重建;构建、二进制身份及桌面

真实版本接口增加回归,固定 SHA-256 校验继续失败关闭。真实双栈转发和加密协议检查
纳入 macOS CI 与发布门禁,不代替目标设备实机验收。

Windows 安装

  • 安装器不再把其他本地代理工具设置的系统代理误判为 SSRVPN 自有。系统代理端点的归属改为

要求本安装自身的恢复记录佐证,不再仅凭「回环端点 + 常见旁路列表」的形状推断;在从未
运行过 SSRVPN 的全新机器上,安装准备阶段不再因此失败关闭并报 PROXY_UNSAFE。

  • 去除按名结束进程后的旧归属推断:第三方 mihomo.exe 正在运行且启用了回环系统代理时,

不再绕过恢复记录检查而误报 PROXY_UNSAFE;损坏或未完成的恢复记录仍保留失败保护。

  • 安装与卸载改为按精确映像名结束本产品随包的三个进程(ssrvpnwindowsapp.exe、

ssrvpn_windows.exe、mihomo.exe),无论运行自哪个目录,含便携版与更旧安装副本
(见 ADR-021)。此前只结束「路径精确等于本次安装目录」的进程,换目录安装或机器上残留
便携版时,第三目录副本仍持有全局单实例互斥体,安装会卡在 APPINSTANCEACTIVE 并把
「退出所有 SSRVPN」转嫁给用户。映像名清单是封闭白名单,逐 PID 身份校验与失败关闭出口
保留,旧副本文件不触碰;mihomo.exe 为开源内核通用名,安装期间会一并结束恰好同名的
其他代理软件进程,该影响已写入安装覆盖提示向用户披露。Windows 安装器始终显示安装目录
选择页并预填上次目录,修复换路径安装无法结束旧实例的问题。

  • 有 SSRVPN 代理恢复记录时的失败关闭语义不变:恢复日志仍需通过可重放检查;应用退出与

异常恢复仍只结束路径、PID、会话、创建时间和所有权能够证明属于当前安装的进程,第三方
代理/VPN 软件不受影响。

界面

  • 三端启动后复用本地保存的上次节点延迟和失败状态,不再每次打开都清空显示;

单点和批量测速均更新记录,节点身份匹配后恢复。缓存独立保存、原子写入,
地址或端口改变不复用旧值,损坏或写入失败不影响启动和已有订阅。

  • 强制直连、强制代理填写弹窗在玻璃层上绘制独立的不透明表单底色,遮住后方节点文字;

修复只调整玻璃参数仍会透出底层页面的问题。三端共用同一底色策略,并通过深浅主题、
四档特效的实际像素回归检查;关于、教程和订阅选择继续保留透明玻璃表面。

  • 三端默认改为静止壁纸:「动态背景」默认关闭,BackgroundStyle.flowing 只表示选择内置壁纸,不再隐含一直在动。静止壁纸不请求任何一帧,也不会带动其上所有玻璃卡片重新合成。
  • 设置页「外观」新增「动态背景」开关,仅对「壁纸」背景可用;纯色与自定义背景本就不运行流动动画,开关对其禁用并说明原因。关闭时壁纸停在当前相位而不是跳回起点,重新开启从同一相位继续。
  • 旧安装无需迁移:设置里没有该字段时按关闭解析,原 flowing 取值继续保留原有的壁纸选择。

界面性能

  • 修复静止壁纸在节流窗口内更新后,玻璃纹理需要等下一次点击才刷新的问题。尾部刷新和

冷启动重试现在会按需请求绘制帧,页面静止后不会持续请求帧。

  • 漂移壁纸的高档玻璃背景纹理不再逐帧重新光栅化:捕获按帧时钟节流到 100 毫秒窗口,窗口内的重绘在尺寸不变时只复用上一张纹理并更新取样原点。同一 480 毫秒窗口的界面测试中,捕获次数由每帧一次(30 次)降为 5 次。
  • 修复窗口尺寸变化期间玻璃复用旧尺寸纹理的问题。节流窗口内复用的纹理仍是改动前的尺寸,玻璃会按新尺寸取样一张偏小的背景;实测 3.0 倍像素比下最大偏小 21 个设备像素,且默认的静止壁纸配置同样存在(布局变化本身会触发重绘)。现在尺寸变化与像素比变化一样绕过节流:放大窗口 300 设备像素后仅推进 32 毫秒(仍在 100 毫秒窗口内),纹理即已匹配新尺寸。代价只在缩放期间逐帧光栅化,与引入节流之前的行为相同,稳态漂移仍保持约 6 倍的捕获削减。
  • 首个捕获、devicePixelRatio 变化、窗口尺寸变化、重新启用和从后台恢复均不受节流限制;静止或暂停的壁纸依旧完全不触发捕获,玻璃取样原点仍逐帧跟随页面位移,不影响切页与转场复用。
  • 真机实测(Apple M1 / 8 GiB,380×793 窗口保持前台且未连接,高档玻璃):官方 5.0.13 默认为 35.25% 单核 CPU,静止壁纸为 0.32%,壁纸加「动态背景」为 33.36%。同一会话内以翻转节流常量隔离出的捕获节流净效果约 2 个百分点。采样口径与限制见 docs/PERFORMANCE.md。
  • 新增漂移壁纸捕获频率的界面回归测试,同时约束“漂移仍刷新纹理”与“捕获次数远低于重绘次数”两侧,避免节流退化为不再更新或退化为逐帧捕获。

连接与恢复

  • 修复自动恢复结束时清空新连接进度的时序问题;恢复提示现在在串行任务退出前完成清理。
  • 修复断开或重连后旧网卡枚举结果污染新网络基线的问题;旧查询不再阻塞新会话的网络检查。
  • 自动恢复判定窗口由约 35 秒缩短到约 9 秒,并且是确定性的 9 秒。连续失败阈值仍为 3 次;宽限由 30 秒降到 3 秒(一个轮询周期),Android 原生的软失败宽限由 30 秒降到 15 秒。
  • 修复宽限与采样跨度打平导致恢复窗口随机跳到 12 秒的问题。三次采样本身已覆盖约 6 秒持续失败,此前宽限取其 2 倍正好与之相等,实测第 3 次失败只差 5 毫秒没够到宽限,恢复整整多等一个轮询周期;宽限改为严格小于采样覆盖跨度后,定时器抖动不再影响判定结果。单次瞬时抖动依旧不会触发重启。
  • Android 原生存活监控把“本地 API 端口已不再监听”作为核心进程已退出的硬证据:达到失败阈值后连续两次探测都不可达才立即恢复,不再等满宽限;端口仍在监听(核心活着但暂时无响应)时保留原有宽限,避免把短暂卡顿当成崩溃。之所以要求连续两次,是因为该探测本身只是一次 100 毫秒的本机 TCP 连接(CorePortReleaseVerifier.canConnect),比同一判定里 2000 毫秒的 API 探测严 20 倍,设备调度抖动或休眠唤醒瞬间的伪超时足以让它误报;两次采样把硬失败路径的耗时从约 6 秒改为约 9 秒,仍远快于此前的 30 秒。
  • 修复 Android 连接后不再做任何周期性数据面检查的问题。此前 Android 把控制面监测整体交给原生服务,共享层里唯一会周期性重探数据面的钩子随之停用,导致“节点已不再转发、本地控制面却仍然健康”时永远只显示“已连接”、没有任何提醒;现在以 60 秒周期独立观察,且只告警、不重启核心。
  • 三端新增物理网络变化监听(10 秒比较一次接口指纹),Wi-Fi 切网线或网络重连时立即重新观察数据面,不再等待 30 秒节流到期。此前桌面端在这种场景下最长约 70 秒维持“已连接但不可用”。
  • 物理网络指纹不再把 IPv6 临时地址计入比较。macOS 会为同一张网卡大约每天轮换一次 IPv6 隐私地址,此前这会被判成“物理网络变化”,每天触发一次完整重探(最坏约 41 秒的请求)并可能弹出一条并无其事的咨询性告警。现在已有 IPv4 地址的网卡只用 IPv4 标识自己;真实的切换仍然会被发现——换网卡会改变接口集合,重连到别的网络会改变 IPv4 地址。只有 IPv6 地址的网卡(IPv6-only 网络)继续用 IPv6 标识,因为否则它就没有任何身份可用。
  • 修复物理网络变化瞬间可能发布旧网络结论的问题。网络变化此前既不递增观察世代也不清空旧告警,切换网络时已经在飞的那次观察完成后仍被判定为“当前”,可以把旧网络的结论贴到新网络上(最长约 41 秒才被覆盖)。现在网络变化与路由变化共用同一套失效语义:递增世代、清空旧告警并立即重探,清掉的告警会一并通知到界面。
  • 自动恢复期间首页显示持续的“正在自动恢复连接…”,取代可能被错过的一闪而过提示。
  • 代理组健康检查补齐参数:tolerance: 50 避免因微小延迟差异反复切换节点而重置连接,lazy: true 停止对空闲节点的持续探测,检查间隔由 300 秒缩短到 120 秒。tolerance 只写给「自动选择」(url-test):核心只为该类型解析这个字段,「故障转移」(fallback)上写它会被静默忽略,读起来像是一份并不存在的容差保护,因此不再写入。默认 PROXY 仍是手动 select 组,需要自动转移请选择「自动选择」或「故障转移」。
  • 外部网络探测的失败原因不再一律记为 UNKNOWN。探测抛出的 TimeoutException 与 http.ClientException 都不含既有分类器依赖的传输关键词,此前会落到兜底分支,日志只剩 cause=UNKNOWN,无法区分超时、连接被关闭还是本地代理不可达;现在先按异常类型判定,分别报出 NETWORKTIMEOUT 与 NETWORKUNAVAILABLE。
  • 三端错误码分类收敛为唯一实现。Android 曾自带一份只做字符串匹配的同名助手(18 处调用),其中 notifyVpnStateChanged、stopCore 等 .timeout() 自身的 catch 分支会把超时写成 cause=UNKNOWN,与上一项同一病根。现删除该复制品,三端共用共享层的 safeRuntimeErrorCode,并新增护栏禁止平台侧再声明本地错误码助手。
  • 三端探测预算统一为共享常量(6 次尝试 / 1 秒间隔)。此前 Windows 与 macOS 显式传该值,Android 沿用方法默认值(3 次 / 2 秒),同一网络状况下 Android 的误报概率约为桌面的两倍。该值必须写在调用点上:Dart 的默认参数由被调用实现决定,任何覆写都会静默改掉它。另需注意 6 是内部硬上限(verifyUserConnectivity 会 clamp(1, 6),因为单轮最坏约 41 秒必须留在 60 秒的观察上限内),调大不会报错但会被静默截断。

文档

  • 修正硬性规则清单的编号重号、漏编与错位:#53 曾被两条规则占用,两条规则错位在「规则

变更流程」之后,第 3 节开头还有一条无编号的完整规则。现为 1..57 连续编号,并新增
门禁守卫要求该清单严格连续递增。

  • 新增硬规则 #57:三端随包内核必须始终是带 SSRVPN 流量统计扩展的定制构建,任何正式

发版不得以官方原版内核替代(流量统计、私家车流量展示、设备数展示依赖其
GET /ssrvpn/traffic 端点)。

其他

  • 外部网络验证失败提示精简为一行短文案,并且只描述实际发生的事:有 HTTP 响应时说「外部网络验证未通过(端点 HTTP 502),仅供参考」,全程无响应时说「外部网络验证未通过(连接无响应),仅供参考」。此前桌面端把两层文案直接拼接成 83 字,撑满首页单行并顶掉公网 IPv4 读数;完整原因仍保留在运行日志中。
  • 诊断页「节点与外部网络」的结论会标出观察时间(如「最近一次观察 12 秒前」)。诊断读的是缓存告警而不是重新探测——完整探测最坏约 41 秒,超出诊断检查 10 秒的预算——此前不说明新鲜度,用户无法判断该结论是当前状态还是几十秒前的旧状态。
  • 设置页「动态背景」开关的显示值与实际效果一致:非「壁纸」背景、以及系统开启「减少动态效果」时,开关显示为关闭并禁用,副标题说明原因,不再出现“看起来已开启却点不动、也没有解释”的矛盾。
  • 静止壁纸固定使用 t = 0 相位取景(外层 1.16 倍缩放覆盖平移范围,无黑边)。此前壁纸停在随机相位,升级后构图最多相差约 5.5% 宽 / 4% 高。
  • 移除 Android 上不可达的 Dart 侧恢复路径。Android 的核心重启由原生存活监控与恢复预算统一负责,保留第二条路径只会在将来与原生恢复相互竞争。