From 0b1328eeee2dfe86fceeaae70ca5a855a33c8b81 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Mon, 14 Sep 2026 09:42:04 +0800 Subject: [PATCH] [feat] pin coordinated UDP punching and validation tooling --- deps/submodules/minirtc | 2 +- docs/p2p-punching-implementation-plan.md | 151 ++++++++++++++++++++++- 2 files changed, 146 insertions(+), 7 deletions(-) diff --git a/deps/submodules/minirtc b/deps/submodules/minirtc index 8fe1d7df..29f5031b 160000 --- a/deps/submodules/minirtc +++ b/deps/submodules/minirtc @@ -1 +1 @@ -Subproject commit 8fe1d7dfc78f22477f6f39483d3a3ebfdd55d680 +Subproject commit 29f5031b42d0ed070b99b105a95f7cf45fa11bb5 diff --git a/docs/p2p-punching-implementation-plan.md b/docs/p2p-punching-implementation-plan.md index 345936c3..1778f4d0 100644 --- a/docs/p2p-punching-implementation-plan.md +++ b/docs/p2p-punching-implementation-plan.md @@ -1,10 +1,10 @@ # CrossDesk 双端 UDP 打洞增强实现方案 -状态:设计基线保留;已实现 P0 单端点后端与实验工具,macOS 本机机制验证通过,P0 双平台/双端抓包总验收尚未完成。P1–P5 尚未启动。日期:2026-09-13。 +状态:P0 门槛已通过;P1–P4 默认关闭原型、受控运行与跨平台构建已实现;P5 实验工具已交付,真实未知 NAT 对照和最终双端应用切换验收待执行。日期:2026-09-14。第 15 节保留 P0 历史记录,最新进展与边界见第 16 节。 源码基线:CrossDesk `73e3bf709d7c054df7bd75cfafceda0721c6cda1`;MiniRTC 子模块 `f169a696cb4e6cb59037ec02e85532e30d3c1262`;libnice `0.1.24` 加仓库已有补丁。 -本文规定第一版的范围、接口职责、协议、资源预算、开发顺序和验收条件。新增名称、配置、接口和测试目标均为拟实现内容;现有代码位置另外标明。本文不代表功能已经实现或成功率已得到验证。 +本文规定第一版的范围、接口职责、协议、资源预算、开发顺序和验收条件。第 1–14 节保留设计基线,实际接口及完成情况以第 15–16 节和所链接的执行报告为准。实现和受控测试不代表真实 NAT 成功率已得到验证。 ## 1. 目标与取证依据 @@ -407,7 +407,7 @@ P0 工具只能使用实验提供的明确对端地址,不含广范围探测 交付:A/B/C 配置、自动汇总脚本、双端抓包复核和实验结论。 - A:现有策略,增强关闭。 -- B:相同新协议与固定角色,一侧单端点,另一侧扩大目的端口。 +- B:相同新协议与相同的自动角色判定规则,一侧单端点,另一侧扩大目的端口;角色必须由有效观测支持。 - C:与 B 相同,但使用端口池。 按交错顺序重复 A/B/C,第一轮每组至少 30 次;保持网络、版本、STUN/TURN 和其余配置相同,记录每次启动间隔和真实端点。观察到一次成功不等于方案验收完成。 @@ -493,7 +493,7 @@ P0 工具只能使用实验提供的明确对端地址,不含广范围探测 MiniRTC 实施提交:`7f0e666216891c9b79bd4a8f75b63741fe1fabf2`。 本机最终检查为 22/22 通过,包括 en1 实际 IPv4 与内核接口绑定读回;这不是跨 NAT 成功率。详情见 [P0 测试记录](../deps/submodules/minirtc/tests/ice/lab/p0-validation-2026-09-13.md) -与 [构建、双机执行和抓包步骤](../deps/submodules/minirtc/tests/ice/lab/README.md)。 +与 [构建、双机执行和抓包步骤](../deps/submodules/minirtc/tests/ice/lab/p0-experiments.md)。 本节是执行记录,不改变 P0→P5 的依赖门槛。**本轮没有完成可启用的“双端 UDP 打洞增强”产品功能。** P0 的本机机制已可运行;Windows、双端物理网卡抓包 @@ -509,7 +509,7 @@ UDP 打洞增强”产品功能。** P0 的本机机制已可运行;Windows、 - `tests/ice/punch_peer_test.cpp`:两个独立进程/两台 LAN 主机的 P0 实验入口, 私有共享目录提供测试信令,便于 Windows/macOS 后续配合;不是生产控制协议。 - `tests/ice/lab/run_p0.py`:临时 coturn、STUN 就绪检查、场景矩阵、二进制 SHA、 - 结构化结果与清理;`tests/ice/lab/README.md` 给出准确构建、双机操作和抓包清单。 + 结构化结果与清理;`tests/ice/lab/p0-experiments.md` 给出准确构建、双机操作和抓包清单。 - `src/ice/ice_agent.*`:明确 `dtls_peer_verified_`,统一两个握手完成入口的指纹 验证;导出 SRTP 前要求验证成功;有界保留早于本端 READY 的 DTLS flight。 @@ -557,7 +557,7 @@ P1 的生产认证上下文、P2 速率公平预算、P3 广范围组合探测 ### 15.3 验收和下一步 当前可运行的构建与实验步骤见子模块 -`tests/ice/lab/README.md`;可公开的测试摘要保存在同目录的结果记录中。 +`tests/ice/lab/p0-experiments.md`;可公开的测试摘要保存在同目录的结果记录中。 成功意味着本机真实中继 → 验证过的 DTLS → 新 socket 的认证入站 → 正常 STUN/ nomination → 同一 socket 的双向 SRTP,不能将编译、短包 ACK 或一次局域网成功 当作 P0 总验收或 P5 的真实网络收益。 @@ -565,3 +565,142 @@ nomination → 同一 socket 的双向 SRTP,不能将编译、短包 ACK 或 P0 总门槛仍需 Windows x64 编译/执行、Windows/macOS 双端抓包、两个 ICE 角色、 实际桌面媒体连续性及退出检查。完成这些后再冻结生产后端接口并进入 P1,沿用本文 其余协议、预算和 P1–P5 验收要求。此处没有通过降低验收要求提前启动广范围探索。 + +2026-09-13 后续进展:用户报告同步后的 Windows 构建成功,尚未取得 Windows +网络测试日志或二进制哈希;不能将构建成功记为 P0 运行验收。两端实际不在同一 +局域网,当前双机夹具要求明确且互相可达的 UDP 地址,因此不能直接使用两端 +私网 IP 运行该夹具。`run_p0.py` 新增外部实验 TURN 模式,使 Windows 可以先 +独立完成本机双 ICE 角色、SRTP 和资源清理矩阵,无需本机安装 coturn。外部 TURN +不等于双机直连拓扑,此调整不改变 P0 门槛、原升级窗口或后续阶段依赖。 + +### 15.4 两台 Mac 局域网实测 + +用户提供同局域网的第二台 arm64 Mac 后,已在 `192.168.31.125/en1` 与 +`192.168.31.102/en0` 执行真实双机 P0;双方系统均为 macOS 26.6.2。 +`run_p0_ssh.py` 仅用 SSH 传递实验 JSON 信令,探测、STUN 和 SRTP 仍通过真实 +LAN UDP socket 与原受控门控转发。没有改用 SSH 隧道承载被测传输。 + +四种 ICE/端口池角色组合的媒体断言均通过。首轮严格双端逐包核对为 3/4 通过, +另一组有一个 SRTP 包只出现在发送端抓包中,原始失败记录已保留,未改判为成功。 +该组以新端口、新 run ID 复测后通过,两端均取得零内核丢包统计。四种组合现均有 +探测 HMAC → 认证 STUN/提名 → 命中 socket 上双向 SRTP 的双机报文证据。 + +双机夹具增加开池前至少 10 个中继 SRTP、停止探测后至少 10 个直连 SRTP、 +selected socket 的物理接口绑定读回;全部仍在原升级窗口内。仓库新增 +`verify_p0_capture.py`,核对实际 pcapng、ICE MESSAGE-INTEGRITY、提名 TID 和 +门控两侧的相同报文,私有密钥和原始抓包不入库。 + +完整次数、哈希、例外、复现和清理记录见 +[双 Mac P0 实测记录](../deps/submodules/minirtc/tests/ice/lab/p0-lan-validation-2026-09-13.md)。 +本轮完成 Mac 双机机制与抓包验证,**没有替代 Windows 运行、跨平台及实际应用 +媒体验收**。P0 总验收仍未完成,P1–P5 继续保持未启动,生产功能默认关闭。 + +### 15.5 Windows 局域网验收准备(2026-09-14) + +用户另提供同局域网 Windows:WLAN `192.168.31.220/24`,仓库 +`D:\SourceCode\crossdesk`,账户 `desktop-ri1qfbe\kunkundi`。用户输出确认 +Python 3.13.5 可用,MiniRTC 为 `7f0e666`,两个 P0 测试 EXE 文件存在。 +这些信息不代表测试已运行;升级后的双机媒体断言需要同步并重新构建 peer 目标。 + +实验驱动增加 `--remote-shell powershell`,通过编码命令传入 Windows 的字面路径, +仍仅使用 SSH 管道传递私有信令。抓包核验器允许显式指定两端物理和本地回环接口名, +以适配 Npcap 的命名;未将虚拟网卡或回环流量当作物理网卡交付证据。 +README 补充 Windows SSH 驱动、两接口抓包和精确接口名核验步骤。 + +本机已检查 Python 语法、带空格/单引号/中文路径的命令编码、POSIX 参数兼容, +并用原 Mac 抓包回归默认和显式接口选择;改写接口名后的同一份 Mac 报文也能核验, +错误物理接口或 anchor 回环接口会被拒绝。这只是工具回归,**未执行 Windows +PowerShell 启动、Windows 网络矩阵或 Npcap 验证**。当前等待 Windows SSH 接入, +后续使用本机临时 TURN 开展单机矩阵和四种跨平台角色组合,保持原 P0 门槛。 + +### 15.6 Windows/macOS P0 验收完成(2026-09-14) + +Windows 真实单机矩阵 20/20 通过,包含两个 ICE 角色、100 次生命周期、取消、 +未命中、错误指纹和原截止时间。跨平台四角色均已取得命中端口上的认证 STUN、 +提名及双向 SRTP 的严格双端抓包证据。完整结果、二进制和抓包 SHA、失败样本及 +边界见 [Windows/macOS P0 记录](../deps/submodules/minirtc/tests/ice/lab/p0-windows-validation-2026-09-14.md)。 + +本轮没有把全部尝试改判为通过:初次双机抓包为 3/4,修正夹具收尾后为 4/5。 +最终普通 Mac pool/controlling 一组有中段一个 SRTP 包只出现在 Mac 抓包;同角色 +的单向通知延迟 1 秒组严格通过,因此四种角色均已有最终版本证据。另一次 Windows +开池前 TURN 媒体基线失败,针对两种角色复测均通过,原失败仍保留且原因未确立。 +Windows 抓包统计包含 16 个 flushed,pcap/dumpcap/接口丢包为 0;未声称总丢包为 0。 + +经源码和最小实验确认两处夹具修正:Windows `IP_UNICAST_IF` GET 已为主机序, +去掉重复转换;旧夹具等待对端完成消息时仍发媒体,另一端可先销毁 gate,单向 +延迟实验复现最后 13 包未转发。新增停止发送、交换最终序号、双端认证接收确认后 +再销毁的屏障;没有修改标准 ICE、原窗口、DTLS 或降低媒体门槛。 + +完整 CrossDesk 两端编译成功,Mac 使用 `xmake r crossdesk` 提供 Slint 运行环境。 +用户对双向画面、声音、鼠标键盘和三次重连请求回复已完成,未报告异常;此项作为 +用户报告的普通应用回归,不能声称独立测量了 pool 切换时的实际编解码连续性。 +命中 socket 的切换与认证媒体由 P0 真实 SRTP 夹具验证。 + +P0 后端接口、所有权与取消语义按 15.2 冻结,允许进入 P1。P0 仍是每 component +一个实验端点;P3 扩展数量时必须继续遵守同一 socket、标准检查和选中资源所有权。 +生产能力、广范围探索和默认启用尚未交付,P5 真实未知 NAT 的收益仍需后续对照。 + +## 16. P1–P4 实现与 P5 实验入口(2026-09-14) + +本节更新当前状态;第 15 节“未开始 P1–P5”等文字是对应时间点的历史记录。 +在 P0 跨平台门槛通过后依次完成 P1/P2 基础、P3 多端点接入和 P4 生命周期/构建, +没有在 P0 前放大探索范围。源码及实验工具由主仓库当前 gitlink 固定。完整证据见 +[P1–P4 验证记录](../deps/submodules/minirtc/tests/ice/lab/punch-runtime-validation-2026-09-14.md), +准确命令见 [v1 实验步骤](../deps/submodules/minirtc/tests/ice/lab/punch-v1-experiments.md)。 + +| 阶段 | 当前交付及边界 | +| --- | --- | +| P0 | 已通过原门槛,保持单端点 ABI 1 与原始失败记录 | +| P1 | 配置/能力、指纹验证后 exporter、认证协议与协商完成;默认关闭,新旧/未知能力纯逻辑及实际生成能力检查通过 | +| P2 | 同源观测、角色、CSPRNG 采样、本地与进程预算完成;首次实现时 Mac/Windows/Linux 各 2,952 个单元断言通过,后续清理回归见验证记录 | +| P3 | 独立 ABI 2、64/128 端点、同 socket 提升/标准检查/提名/媒体闭环实现;三个平台受控 runtime 各 12/12 | +| P4 | owner context 清理、DRAINING、取消、重连身份和接口/base 检查实现;百次 source/agent 生命周期、Mac/Windows 完整应用、Linux ICE smoke、iOS 静态库已验证。物理网卡真实切换和最终应用互连仍待双端验证 | +| P5 | 90 次交错清单与核验工具已准备;有 1 次增强成功双端日志但无该轮物理抓包。后续双端抓包取得 A/off 的 3 个完整窗口样本(均中继),B/wide-only 的 2 次已启动未命中和 1 次启动前跳过。跳过暴露的 READY 重查时序问题已修复,真实双端修复后复测及正式随机 A/B/C 仍待进行;保留先前 SDP 失败,不作收益或默认开启决定 | + +### 16.1 对实际源码的必要调整 + +- 保留已验收的 `punch_pool_0.1.24.patch`,追加 `punch_v1_0.1.24.patch`。 + `nice_agent_punch_get_v1_abi/open_v1` 与 P0 API 区分;v1 每池最多 128、进程 256, + 提升最多 8。补丁 SHA 与包身份版本进入 MiniRTC 配方,不依赖本机缓存改动。 +- `PunchRuntime` 由 IceAgent 持有,在同一 GMainContext 使用真实句柄,直接收包 + 与 TURN 控制分流,认证命中后由 pool 提升。实际 selected pair 才报告结果, + 各自的原始截止不会因 HELLO/重传/START 被延长。 +- SDP 指纹最小实验发现原解析吞并 fingerprint 之后所有行并截断 SDP,导致新增 + 候选/能力位于其后时 DTLS 校验失败。改为逐行解析、保留其余 SDP、拒绝冲突指纹, + 并加入真实握手与位置测试;没有通过禁用指纹校验绕过失败。 +- 通用 DEBUG 日志在现有项目中编译关闭,因此添加独立、默认关闭的 + `MINIRTC_UDP_PUNCH_TRACE=1`,只记录有界探测元数据。应用原有 SDP 日志包含 ICE + 密码,原始实验文件必须保持私有;新代码不记录 exporter 或完整 tag。 +- 首次启用后的真实应用试跑发现 eligibility 日志读取未赋值的旧 ufrag 指针, + 在接收 SDP 时崩溃;最小实验复现后,eligibility/skip 与 exporter 统一从当前 + libnice stream 读取 generation 凭据。补充双角色真实 SDP 接收/重建及自动 skip + 的 TURN/SRTP 回归,详情见验证记录。此修复不改变协议或绕过探测前置条件。 +- Mac off 试跑发现传输层复制指纹行后缺少 LF,追加原能力时产生 CR CR LF, + 无 v1 能力的 SDP 被严格校验拒绝。完整 IceTransport 实验复现后在拼接处补齐 + LF;三种运行模式各 36 个组合及错误指纹拒绝通过,证书校验和默认关闭不变。 +- B 组一次启动遇到 READY → CONNECTED → READY 的正常候选重查。后端截止时间 + 查询只在 READY 有效,旧入口把暂时返回 0 当作最终跳过。保存首次 READY 时 + 后端提供的真实截止时间;在该时间内等待 CONNECTED 恢复,随后重新让后端验证 + 是否可探测。不在 CONNECTED 开池,不从恢复时间重新计算窗口;新增真实 TURN + 的 `auto-recheck` 夹具,覆盖两个角色、原截止不变和单次 DTLS/认证中继媒体。 +- 第 10 节 B 组原“固定角色”明确为**固定自动判定规则**,与第 4 节生产禁用强制 + 角色保持一致。受控夹具仍可固定角色;真实实验记录观测/角色变化及跳过,不把 + 它们隐藏为成功或擅自在生产中绕过适用条件。 + +### 16.2 验收边界与下一步 + +已验证 DRAINING 后真实 STUN 重传仍能提名并传输、认证 CANCEL 保留 relay、 +TURN 内层同形载荷不会产生直接命中,以及选中 socket 的实际存活和配额保持。 +Windows 64 端点百次压力测试在单一窗口到期后拒绝分配;工具通过多个新连接分批, +最终两角色合计 20/20,各累计 100 次分配/停止/端口重绑定,没有扩大 ICE 窗口。 +分批首轮 15/20 暴露开池前基线只按发送次数判断的问题;改为原截止前等待双方 +各实际收到至少 10 个认证 SRTP 包后才开池。所有初次失败和修正理由保存在报告中, +不追溯认定所有历史媒体缺包原因相同。 + +用户已报告完成的普通画面/声音/控制/三次重连回归属于 P0 时点,不代表后续原型 +已通过真实应用切换验收。后续已有异网配对的双端成功日志,下一步补齐物理抓包, +并在同步接收端修复后,用同一版本、同一信令 +与 STUN/TURN 配置,按文档交错执行 A/B/C;首先确认新鲜多 STUN 观测符合一侧稳定、 +另一侧目的相关。每个增强成功必须核验双端物理报文、标准提名、同一命中 socket、 +同一 DTLS/SRTP 会话以及实际画面/声音/控制。至少每组 30 次、保留全部失败/缺测。 +在这些工作完成前,原型仍默认关闭,不能声称已提高真实网络成功率。