mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-02 00:04:46 +00:00
- 受管插件静态事实表(v2ray-plugin v1.3.2,来源/许可证/版本/重签)与 BundleManagedPluginProvider:受管集内且 bundle 内可执行文件在位才返回 绝对路径;与 Vendor 清单双向锚定(D6/D10) - 服务器编辑器插件区:受管选择器(无 + 受管列表),选中受管项才显示 供应链事实与参数输入;集外引用显式「本版本未提供」并原样保留 - updateServer 插件落盘语义:「无」整体清除、参数写删钥匙串、集外不漂移 - wrapper 监听建立判定:3 秒未建立本地监听记 error 日志,监管继续(D10) - 诊断导出新增受管插件清单(名称/版本/提供状态,无参数) - 功能级兼容实测记录(docs/research/plugin-compat-record.md)与端到端 冒烟:契约插件路径 → sslocal 拉起 → v2ray-plugin 进程建立 → 停止链
65 lines
5.4 KiB
Markdown
65 lines
5.4 KiB
Markdown
# 受管插件功能级兼容实测记录(spec #21 Further Notes #6,issue #38)
|
||
|
||
- 实测日期:2026-09-21
|
||
- 实测人:Qiu Yuzhou(agent 辅助执行)
|
||
- 环境:macOS 26(Darwin 27.0.0)arm64;Xcode DerivedData Debug 构建;sslocal v1.25.0(`aarch64-apple-darwin`,归档 SHA-256 `58e0caf0…`);v2ray-plugin v1.3.2(`darwin-arm64`,归档 SHA-256 `35747669…`),均为 Vendor 清单固定版本,构建期哈希复验 + Developer ID 重签(插件 identifier `com.qiuyuzhou.ShadowsocksX-NG.plugin.v2ray-plugin`,hardened runtime)。
|
||
- 证据规则:以下每一条都对应可重复执行的测试或本记录中的命令输出摘要;未实测的系统行为不写成事实。
|
||
|
||
## 已实测闭环
|
||
|
||
### 1. 配置生成 → sslocal 拉起 → 插件进程建立(端到端边界)
|
||
|
||
生产组合根已接线:`CatalogViewModel` / `ProxyRuntimeController` 的默认受管插件提供均为 `BundleManagedPluginProvider`(宿主 app bundle),激活派生、编辑器提供事实与诊断清单读同一事实源;`BundleManagedPluginProviderTests.testHostAppBundleProvidesManagedPlugin` 固化「bundle 内插件在位」防打包回归。
|
||
|
||
`Tests/RealSslocalSmokeTests.testRealSslocalLaunchesManagedV2rayPluginProcess`:
|
||
|
||
- 契约 `servers[0]` 携带 bundle 内插件绝对路径(`Contents/Helpers/Plugins/v2ray-plugin`)与 `plugin_opts: "mode=websocket"`;
|
||
- wrapper 以真实 sslocal 拉起,SIP003 插件进程建立(`pgrep -f` 按完整路径确认,进程存活);
|
||
- 本地 SOCKS 端口完成监听绑定;
|
||
- SIGTERM 停止链:wrapper 干净退出(0),插件进程随 sslocal 一并结束。
|
||
|
||
无插件基线 `testRealSslocalBindsSOCKSAndHTTPPortsAndCompletesHandshake` 在同一套件中保持通过(SOCKS5 完整握手)。
|
||
|
||
实测观察(补充两条对后续票有用的行为事实):
|
||
|
||
- **sslocal 在插件进程就绪前不绑定本地监听**。插件冷启动(首次 exec 触发签名校验)时,从 sslocal spawn 到端口可用可能明显超过 3 秒(本机 xcodebuild 冷环境实测出现过 6 秒级)。D10 的「3 秒未建立监听 → error 日志」在此场景是真实告警而非误报,GUI 健康门(15 秒)不受影响。
|
||
- shadowsocks-rust 按 SIP003 以 `SS_LOCAL_HOST/SS_LOCAL_PORT` 环境变量让插件监听管道口;插件进程先于本地端口出现。
|
||
|
||
### 2. 选择器全语义与保存语义
|
||
|
||
`Tests/CatalogViewModelPluginTests`(9 例)与 `Tests/BundleManagedPluginProviderTests`(6 例):
|
||
|
||
- 「无 / 受管 / 集外」三态呈现;受管选中显示供应链事实(来源项目、许可证 MIT、固定版本 v1.3.2、重签标识)且只有受管选中出现参数输入;
|
||
- 受管选择落盘:程序名入目录、参数入钥匙串(引用形态);空参数删除引用与秘密;「无」整体清除;
|
||
- 集外引用(如 Legacy/订阅带入的 `obfs-local`)显式渲染「本版本未提供」、原样保留引用与参数秘密,连接字段照常可编辑;
|
||
- 受管集外程序名一律 `executablePath == nil`(含路径形态引用,绝不拼接用户输入),经状态机以 `pluginNotProvided` 原子拒绝;文件缺失/降级同语义。
|
||
|
||
### 3. 激活失效路径接 #26 语义
|
||
|
||
`Tests/ActivationStateMachineTests`(存量)+ `BundleManagedPluginProviderTests`(新增,以真实文件存在性驱动 provider):
|
||
|
||
- 组内一叶引用未提供插件 → 整组原子拒绝并点名;
|
||
- 活动目标插件变为不可用(`catalogDidCommit` / `resyncOnLaunch`)→ 清除目标、停止代理、点名原因(`ProxyRuntimeControllerTests` 存量覆盖)。
|
||
|
||
### 4. ss URI 往返
|
||
|
||
`Tests/SsUriTests`(存量,逐字节同构语料)+ `CatalogViewModelPluginTests.testSharedSsUriRoundTripsThroughEditorEdit`(经编辑面保存 → 分享 → 再导入,`plugin=name;opts` 同构,与 #32 编解码一致)。
|
||
|
||
### 5. 诊断页/导出
|
||
|
||
`Tests/DiagnosticReportTests`(新增 2 例):导出含「受管插件」清单(程序名 + 版本 + 提供/缺失),投毒夹具确认插件参数不进导出。
|
||
|
||
### 6. wrapper 监听判定
|
||
|
||
`Tests/AgentLifecycleTests.testListenNotEstablishedWithinDeadlineIsLoggedAndSupervisionContinues`:stub sslocal 不监听 → 拉起 3 秒后 `agent.log` 出现 `listen not established within deadline: <端点>`,监管循环继续,后续 SIGTERM 停止链不受影响(D10「运行期失败以 sslocal 信号为准,GUI 不猜测」)。插件进程退出不经 wrapper 直接观测——插件死亡连带 sslocal 退出(实测行为),由既有的 `sslocalExitedUnexpectedly` error 日志承接,与「以 sslocal 信号为准」一致。
|
||
|
||
## 仍属发布门槛人工项(不能在本机自动化闭环)
|
||
|
||
1. **真实服务器功能验证**:经 v2ray-plugin websocket 隧道访问真实远端的协议行为与性能(无真实服务器夹具;本记录只闭环到「插件进程建立 + 本地监听」边界)。
|
||
2. **真实公证对嵌套重签插件的接受度**(Further Notes #3,需 notarytool 凭据,#39)。
|
||
3. **Gatekeeper 首启/quarantine 实机弹窗形态**(Further Notes #1)与 Hardened Runtime 下两级子进程签名链在陌生机器上的表现(Further Notes #2 的实机部分)。
|
||
|
||
## 结论
|
||
|
||
#38 验收标准中「stub 边界验证或真实夹具」档位的功能级兼容实测已闭环并固化为本仓库测试;真实服务器配合、公证与陌生机器 Gatekeeper 行为按规格保留为发版前人工检查项。
|