Files
crossdesk/docs/p2p-uu-comparison-test-plan.md
T

304 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UU 与 CrossDesk 直连差异:双端对照测试
日期:2026-09-14。状态:U01 和 X01 已收到部分双端证据并完成机制分析;尚未形成
符合原始固定条件的完整首次连接/重连对照。X02/U02 待执行。用户确认必须保留 UU
管理连接来操作对端,后续按第 9 节调整条件,不要求断开唯一操作通道。
目标是定位 UU 在当前网络中更容易直连的原因:端口选择、双端发包时序、失败重试,
还是重连时保留了可用通道。本轮先做 8 次连接;只检查连接路径与协议证据,画面、
声音、控制和切换质量按用户要求免验。它不是正式成功率评估,不替代原方案 P5。
## 1. 固定条件
- 使用此前异网组合:Mac 本机与 Windows `10.15.73.245` 所在网络;不要换成同
局域网的 Windows。每批保存实际地址、网关、网卡,地址变化后按新环境另记。
- 统一由 Mac 控制 Windows;固定软件版本,CrossDesk 使用同一套编译产物和
STUN/TURN 配置。UU 使用自己的服务,记录抓包可见的服务器,不假设服务相同。
- clumsy 点击 Stop 并退出;本轮不注入丢包、断网或带宽限制。两端关闭代理/TUN/
VPN 后保持不变;如不能关闭,标记为另一种网络条件,不混合比较。
- 每批只测试一种软件,另一种软件退出;暂停其他远控、下载。Windows 需由本地
人员操作,不能依赖即将退出的 UU 会话完成进程重启。这是原始隔离条件;若依赖
UU 管理通道操作对端,按第 9 节执行,不要求终止该通道,不声称满足完全隔离。
- CrossDesk 双端默认请求 SRTP,运行默认 `pool-wide` 并设置 `TRACE=1`;每批固定实验参数。
原 U01/X01 批次为 64 个端点、512 个随机顺序目标、100 PPS;后续按第 10 节
使用 128 个端点、1024 个离散递增目标、128 PPS,两批均为 10 秒探索与 3 秒
检查收尾。记录实际协商参数,禁止把不同版本与预算混成同一批结果。
- 保留系统已有时间设置,记录带时区时间;分析时通过同一报文关联两端,不能直接
相减 Mac/Windows 的墙钟得到单程延迟。
## 2. 批次与“冷启动”的含义
| 顺序 | 批次 | 软件 | 同一抓包中的两次连接 |
| --- | --- | --- | --- |
| 1 | U01 | UU | 进程重启后首次连接 → 保留进程重连 |
| 2 | X01 | CrossDesk | 进程重启后首次连接 → 保留进程重连 |
| 3 | X02 | CrossDesk | 进程重启后首次连接 → 保留进程重连 |
| 4 | U02 | UU | 进程重启后首次连接 → 保留进程重连 |
这四批合计 8 次连接,每种软件首次连接 2 次、保留进程重连 2 次。顺序反转用于
减少先后偏差,数量只够诊断线索;若结果混杂,再追加完整对照块,保留全部失败。
本轮用 U/X 命名,不占用原方案 A/off、B/wide-only、C/pool-wide 的分组含义。
“进程重启”要求两端真正退出相关前台和网络后台进程,重新启动后确认 PID。
关闭窗口不一定退出后台。如果 UU 的网络服务仍运行、无法通过正常方式退出,
将该批标为“前台重启、后台常驻”,不要当作完全进程重启,不盲目终止未知服务。
即使进程全部退出并安静 30 秒,也不能保证路由器/运营商 NAT 映射已经过期,
因此本轮不声称是“NAT 状态完全清空的冷启动”。不为此重启路由器或改变公网 IP。
若首次连接失败,第二次应标为“保留进程重试”,不能宣称复用了已成功的直连。
## 3. 每批固定操作
一批一对抓包,覆盖两次连接及中间空闲期,不在断开时停止抓包。
1. 两端先启动本批抓包;退出相关应用并核对后台/PID/端口,记录 `process_exit`。
2. 保持两款软件不发测试流量至少 30 秒,记录 `quiet_end`。若后台仍发包如实记录。
3. 只启动本批软件,记录 `app_start`,保存版本、PID、端口快照。
4. Mac 点击连接前记录 `first_connect_click`;从点击起观察 60 秒。无论最终为
直连、中继、失败或仍连接中,都保留结果,不仅留下成功样本。
5. 记录 `first_disconnect` 并断开远控会话,保持软件和后台运行 30 秒;在第
15 秒保存端口快照,观察是否仍有原直连 tuple 的保活或数据报。
6. 不重启进程,记录 `reconnect_click`,再次连接同一对端并观察 60 秒。
7. 记录 `second_disconnect` 并断开,继续抓包 15 秒,保存最后端口快照;随后
停止抓包、保存计数与日志,再正常退出软件。
每次观察期间保持有桌面数据传输;无需人工评价质量。记录应用显示的直连/中继
及其变化时间,但最终路径以双端物理抓包核验为准。长时间仍在连接中应单独分类。
先完成 U01/X01 四次连接即可检查取证是否齐全,再继续 X02/U02。
## 4. 抓包命令
本轮采集 UDP、TCP、ICMP 和 IPv6 ICMP,避免遗漏 UU 可能选择的其他传输路径。
不沿用历史公网端口过滤器。两端都抓当前实际联网的物理接口;每批使用新目录。
### Mac:抓包终端
当前本机 `en1` 为 `192.168.31.125`;先用 `ifconfig en1` 核对。每批修改 U01
为对应批次,复制终端打印的实际目录,避免把后续文件误认为仍在上一次路径。
```sh
umask 077
punch_batch=U01
punch_run_dir="$(mktemp -d "/private/tmp/crossdesk-uu-${punch_batch}.XXXXXX")"
printf '本批目录:%s\n' "$punch_run_dir"
sudo tcpdump -i en1 -nn -s 0 -U -Z dijunkun \
-w "$punch_run_dir/mac.pcap" \
'udp or tcp or icmp or icmp6' 2>&1 | tee -i "$punch_run_dir/mac-capture.log"
```
完成整批后 Ctrl+C;等待 tcpdump 输出 captured/received/dropped 统计并返回
提示符。`tee -i` 让 tee 不先被 Ctrl+C 中断,便于保存最终统计;仍应检查日志。
### Windows:管理员 PowerShell 抓包终端
```powershell
$punchDumpcap = 'C:\Program Files\Wireshark\dumpcap.exe'
& $punchDumpcap -D
$punchNic = Read-Host '输入上方实际联网的以太网接口编号'
$punchBatch = 'U01'
$punchRunDir = Join-Path $env:USERPROFILE ("Desktop\CrossDesk-UU-Compare\{0}-{1}" -f $punchBatch, (Get-Date -Format 'yyyyMMdd-HHmmss-fff'))
if (Test-Path $punchRunDir) { throw '本批目录已存在,请换新目录' }
New-Item -ItemType Directory -Path $punchRunDir -ErrorAction Stop | Out-Null
Write-Host "本批目录:$punchRunDir"
& $punchDumpcap -i $punchNic -s 0 -B 16 -f 'udp or tcp or icmp or icmp6' -w (Join-Path $punchRunDir 'windows.pcapng') 2> (Join-Path $punchRunDir 'windows-capture.log')
```
另开终端查看 `windows-capture.log` 确认成功启动;完成整批后 Ctrl+C,等待文件
关闭。保存 pcapng 接口统计和日志;统计缺失记为缺测,不填零。`-D` 用于列接口,
`-i` 选择接口,dumpcap 默认输出 pcapng,详见 [Wireshark 官方说明](https://www.wireshark.org/docs/man-pages/dumpcap.html)。
## 5. 操作时间、端口和版本
在各端另开一个记录终端,把目录变量设置为本批抓包终端打印的实际目录。每个
关键操作前记录时间,事件名采用第 3 节的名称;如点击晚于记录,应说明大致延迟。
Mac 示例(将路径替换为真实值,后续事件只改最后一行的事件名):
```sh
punch_run_dir='/private/tmp/替换为本批实际目录'
date '+%Y-%m-%dT%H:%M:%S%z first_connect_click' >> "$punch_run_dir/events-mac.txt"
```
在退出后、启动后、首次连接中、断开后第 15 秒、重连中及最终断开后分别执行快照;
阶段名依次用 `after_exit`、`after_start`、`first_connected`、`idle_15s`、
`reconnected`、`after_disconnect`。替换 `punch_stage`,不要覆盖同名快照:
```sh
punch_stage=after_start
date '+%Y-%m-%dT%H:%M:%S%z' > "$punch_run_dir/$punch_stage-time.txt"
ps -axo pid,ppid,comm > "$punch_run_dir/$punch_stage-processes.txt"
sudo lsof -nP +c 0 -iUDP -iTCP > "$punch_run_dir/$punch_stage-sockets.txt"
```
Windows 记录终端:
```powershell
$punchRunDir = '替换为本批实际目录'
"$(Get-Date -Format o) first_connect_click" | Add-Content (Join-Path $punchRunDir 'events-windows.txt')
$punchStage = 'after_start'
Get-Date -Format o | Set-Content (Join-Path $punchRunDir "$punchStage-time.txt")
Get-CimInstance Win32_Process | Select-Object ProcessId, ParentProcessId, Name, ExecutablePath | Export-Csv (Join-Path $punchRunDir "$punchStage-processes.csv") -NoTypeInformation -Encoding UTF8
Get-NetUDPEndpoint | Select-Object LocalAddress, LocalPort, OwningProcess, CreationTime | Export-Csv (Join-Path $punchRunDir "$punchStage-udp.csv") -NoTypeInformation -Encoding UTF8
Get-NetTCPConnection | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess | Export-Csv (Join-Path $punchRunDir "$punchStage-tcp.csv") -NoTypeInformation -Encoding UTF8
```
UDP 的 `OwningProcess` 用于关联所属 PID,见 [Microsoft 文档](https://learn.microsoft.com/en-us/powershell/module/nettcpip/get-netudpendpoint?view=windowsserver2025-ps)。
快照不是无遗漏的 socket 跟踪;相同 PID/端口也不能独立证明同一个 OS socket。
结合空闲期持续报文和下一次连接的外层端点,只对实际可见的通道复用作结论。
每批记录两端应用版本;CrossDesk 保存主仓库及 MiniRTC 提交、EXE SHA-256,UU
保存版本和实际网络进程对应可执行文件 SHA-256。Mac 可用 `shasum -a 256 <路径>`,
Windows 可用 `Get-FileHash -Algorithm SHA256 <路径>`;进程快照帮助定位后台程序。
不要导出命令行、账号密码或完整配置文件。日志和抓包放在私有目录,不提交到 Git。
CrossDesk 两端启动命令(X01/X02):
```sh
cd /Users/dijunkun/crossdesk
MINIRTC_UDP_PUNCH_TRACE=1 xmake r crossdesk
```
```powershell
Set-Location E:\SourceCode\crossdesk
$env:MINIRTC_UDP_PUNCH_TRACE = '1'
.\build\windows\x64\debug\crossdesk.exe
```
如果之前设置过其他 `MINIRTC_UDP_PUNCH_*` 调参变量,先只清除这一前缀的实验
变量,再设置模式和 TRACE;两端保持相同默认参数。旧版 Windows 不用于这组对照。
运行目录如与示例不同,以本轮已核对的构建位置为准;测试中不重编译或换版本。
## 6. 交付材料与判定
每批提交一份 Mac 抓包、一份 Windows 抓包、操作时间和上述快照。X 批次另附
两端 MiniRTC 日志;Mac 通常在 `~/Library/Logs/CrossDesk`,Windows 通常在
`%LOCALAPPDATA%\CrossDesk\logs`,便携构建也检查程序目录的 logs。按时间匹配,
不要把前一次日志拼入本轮;UU 若可正常导出连接诊断日志则一并提供,没有也记录。
逐次记录:首次/重连、前次路径、后台是否退出、连接开始时刻、应用显示路径、
最终抓包确认路径、首次直接探测、首个直接接收、首次持续直连数据、端口数、
目标端口集合与顺序、每端口重试次数、失败/跳过原因,以及抓包与版本缺测项。
分析采用以下规则:
- 通过双端地址转换前后的同一载荷、时序及所属进程核对真实直连。仅 UI 标记、
低 RTT、单个短包或与某服务器交换数据,均不足以证明直连。空闲保活不能当作
新远控会话的数据;需关联连接后的持续传输。
- CrossDesk 分开统计普通 ICE 直连、增强直连、中继、协商未启动、探测未命中、
命中后验证失败;命中成功仍使用仓库 wire 核验。UU 的内部日志契约与密钥未知,
不直接套用 `verify_punch_wire.py`,不把无法解读的包伪装为认证检查成功。
- 若 UU 重连沿用空闲期持续存活的直连端点,首次连接却要重新探测,优先检查通道
保持/复用差异。若进程重启后也稳定优于 CrossDesk,则重点对比目标端口分布、
双端发包相对顺序、重复探索与失败后的后续尝试;不能只比较 231/49 和 512/64。
- UU 若选择 IPv6/TCP,单独报告该路径成功;不混为 CrossDesk v1 的 IPv4 UDP
穿透成功,也不从结果中删除。判断某类协议完全没有流量前,先核对抓包覆盖。
- 本轮结束后先形成有证据的差异和待验证假设,再决定单因素改动。不同端口策略、
重试策略和通道保持应分别验证;不通过延长原 ICE 窗口、强制选路或重启 DTLS
绕过接入。需要更改既定资源/协议边界时先修订对应方案。
正式收益评估仍使用 [v1 实验步骤](../deps/submodules/minirtc/tests/ice/lab/punch-v1-experiments.md)
的 A/B/C 各至少 30 次;本轮保留进程的重连样本存在关联,不当作独立冷启动样本
计算普遍成功率。若要量化 UU 与 CrossDesk 差距,还需另行制定双方启动条件一致、
覆盖多组网络的对照样本,不由这 8 次诊断推导百分比结论。
## 7. U01 已收证据(2026-09-14)
Windows 附件覆盖 14:52:55–14:53:53;Mac 有 14:46:37–14:52:10、
14:52:51–14:53:49 两段,只有后半段具有对应 Windows 抓包。时间为 Asia/Shanghai,
两端墙钟约差 1.36 秒,耗时使用单端时钟或同载荷校准。
后半段确认 UU 新建直连:Mac 复用同一本地 UDP 端点探测 475 个不同公网端口,
按端口数值递增发送;Windows 使用 150 个不同本地端口向 Mac 固定公网端点探测,
共 303 个请求,按首次发包排序的第 59 个端点命中。命中后同一端点继续进行 STUN
检查和提名,并持续承载双端能够匹配的实际数据。Mac 的 UU 日志也记录 relay →
直连候选对切换。从 Mac 增强探测开始到首次直接入站约 5.14 秒,到 RTP 形状数据
约 5.23 秒;不是从用户点击连接开始计时。
较早一次 UU 连接仅有 Mac 侧证据:223 个不同探测目标,约 2.39 秒首次命中。
两次的 Mac 本地/公网端点及远端公网端点不同,日志显示分别创建 transport 并重新
探测。后半段没有沿用前一次成功的传输 tuple,但未证明两端进程已经完全退出。
上述端口数量均为这次观测值,不是固定配置或最优参数。
同时间 CrossDesk 日志及抓包显示还有活动远控连接,UU 也枚举了 TUN 候选;缺少
完整操作事件、Windows 较早抓包和进程生命周期证据。因此本批作为机制诊断样本,
不判为严格 U01 首次/重连对照通过,不计算正式成功率,也不据此修改资源预算。
本次命中端点排名 59,不能仅以 150 与 64 的数量差归因 CrossDesk 的失败。
已用独立 tcpdump 过滤复核三份抓包的探测计数;后半段双端载荷匹配为 Mac →
Windows 698/698、Windows → Mac 4284/4286,另两份为命中前短探测。52 个直接
STUN 包的 FINGERPRINT 校验通过,含提名的请求有匹配成功响应;没有将此等同于
UU MESSAGE-INTEGRITY HMAC 已验证。原始日志与抓包未写入仓库。
本机私有报告与可复现脚本位于
`/private/tmp/crossdesk-uu-U01-analysis-3mz4000c/`。U02 补齐连续首次/重连过程;
用户后来确认需要 UU 管理通道,后续按第 9 节调整后台条件。若已有较早 Windows
文件,可补入 U01;本次已经确认的探测和传输证据继续保留。
## 8. X01 已收证据(2026-09-14)
Mac 同次日志包含五次连接,Windows `cd9.pcapng` 覆盖前四次。前三次双方均按
预算发包:Mac 同一端点向 512 个随机离散目标发送,Windows 64 个本地端点各
探测 3 次,共 192 个请求。双方均未见探测到达,10 秒探索与 3 秒收尾后保持
中继;这些结果属于未命中,不是命中后 ICE 接入失败。
第四次 Mac 第 498 个目标命中 Windows 第 19 个端点;同一端点回复 ACK、继续
完成 STUN 提名并传输。Mac 在 START 后 5.023 秒选择增强直连,最终发送 509 个
探测后停止。双端匹配到 Mac → Windows 2574 个、反向 456 个 RTP 形状数据包;
直接 tuple 未见 DTLS 重握手。Windows 发完三轮探测后约 2.31 秒,命中端点仍能
接收探测并应答,说明主动发包结束没有使它提前关闭。
第五次在探索开始约 9.16 秒后断开;Windows 没有覆盖,Mac 只捕获前 159 个请求,
日志记录 512 个,单独保留为取消且抓包不全,不当作完整失败。Mac 末尾抓包
丢包计数缺失,Windows ifdrop=0。前三次失败也不能仅由内侧抓包唯一归因到 NAT
映射或过滤规则。
四次完整会话的 Mac 探测均与运行时 trace 逐项匹配;系统 tcpdump 独立计数与
解析器一致。后补 Windows `minirtc-20260914-150934.log` 覆盖第 4、5 次,第四次
已通过仓库 `verify_punch_wire.py` 严格核验(1/1):双方认证接收 trace、各 6 个
STUN 检查包的 MESSAGE-INTEGRITY/FINGERPRINT、提名和直接传输相互对应。
Windows 的同一 handle 在 probe-rx 后 promote,再被 enhanced selected;停止
探索时只保留选中端点,继续传输至断开。关闭后抓包未见原基础及池端点再出站。
第五次取消时 Windows 日志确认额外端点计数归零,仍无对应的完整抓包。前三次
Windows 运行日志缺测,不将第四次门禁通过扩展为全部会话的完整核验。
用户确认此次保留 UU 连接是操作对端所需。UU 服务日志及物理流量确认已有管理
直连贯穿测试,应与 CrossDesk 新连接分开。此次控制方向为 Windows → Mac,
与已分析 U01 新会话方向不同;连接间等待约 2–8 秒,未按原计划观察 60 秒、
等待 30 秒。因此记为快速重复连接诊断,保留三次未命中、一次成功和一次不完整
取消,不计算正式成功率。私有报告位于 `/private/tmp/crossdesk-X01-analysis-5r9xbi9i/`。
## 9. 保留 UU 管理通道时的后续约定
用户在 X01 后确认必须使用 UU 操作对端。后续优先采用可执行的条件:
- 保留必要的 UU 管理连接,不终止相关服务或进行会中断唯一操作通道的进程重启。
第 3 节完全退出与安静期的步骤不适用于这种情况;标记为“管理连接保持开启的
新会话/保留进程重连”,不标为全部进程重启,也不标为 NAT 状态已清空。
- X02/U02 两款软件保持相同的管理连接背景。记录管理连接的端点和持续时间,
它不计入被测新会话的成功样本。若 UU 无法在保留管理连接时建立独立测试会话,
应标为缺测;不把原管理通道已经直连当作一次新的 UU 打洞成功。
- 被测新会话固定控制方向。每次连接观察 60 秒,断开被测会话后保留进程等待
30 秒,再重连观察 60 秒;两端持续抓包,最后断开被测会话后再等 15 秒停止。
抓包需要新目录并记录实际路径,避免提前停止或覆盖文件。
- X01 第 4 次成功样本的认证和端点生命周期证据已补齐,不要求为此重做网络过程。
第 1–3 次 Windows 日志及第 5 次完整抓包的缺测状态继续保留。
这是根据操作条件对实验方法的调整,没有改变功能开关、探测预算或 ICE 接入
规则。与完全退出后台的原始批次分开记录,不将两类条件混成一个成功率。
## 10. U01/X01 后的新参数批次
用户要求 CrossDesk 改用离散递增目标并提高数量。当前默认 pool=128、目标=1024、
128 PPS;目的端口仍在 1024–65535 无重复随机抽取,仅发送顺序改为递增。本地
pool 端口由系统分配,不假设本地递增能使 NAT 公网端口递增。
两端同步 MiniRTC 源码并重新构建、重启 CrossDesk,记录二进制 SHA 与 HELLO/START
实际预算;显式旧环境变量和旧 manifest 会覆盖新默认值,旧参数对端协商也会降低
预算。新批次保持第 9 节的 UU 管理通道,抓包使用新目录。核对 anchor 未命中时
目标端口是否严格递增、pool 是否分配 128 个端点;最多 1024 次 PROBE/ACK 共享
预算与原截止仍有效,命中后实际发送数量可以减少。
命中仍需关联同一 handle 的标准 ICE 检查、提名与后续传输;未命中保留中继和
清理记录。此批同时修改数量、速率和顺序,不能单独归因排序带来的收益,也不将
X01 的旧样本追溯计为新参数的验证。画面、声音、控制及切换质量继续按用户要求免验。