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

20 KiB
Raw Blame History

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 为对应批次,复制终端打印的实际目录,避免把后续文件误认为仍在上一次路径。

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 抓包终端

$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 官方说明。

5. 操作时间、端口和版本

在各端另开一个记录终端,把目录变量设置为本批抓包终端打印的实际目录。每个 关键操作前记录时间,事件名采用第 3 节的名称;如点击晚于记录,应说明大致延迟。

Mac 示例(将路径替换为真实值,后续事件只改最后一行的事件名):

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,不要覆盖同名快照:

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 记录终端:

$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 文档。 快照不是无遗漏的 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):

cd /Users/dijunkun/crossdesk
MINIRTC_UDP_PUNCH_TRACE=1 xmake r crossdesk
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 实验步骤 的 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 的旧样本追溯计为新参数的验证。画面、声音、控制及切换质量继续按用户要求免验。