Files

182 lines
11 KiB
Markdown
Raw Permalink 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.
# RemoteDesk 开发指南
## 1. 环境
- Rust stable,包含 rustfmt 和 Clippy。
- Windows 管理界面使用 Rust `winit``wgpu``egui`;仓库不需要 Node.js、npm、JavaScript、C# 编译器或 WebView 构建链。
- Linux PipeWire、Portal、DRI3 与硬件编码器必须在对应 Linux 测试机执行 M0 Spike。
- Drone CI 的 Linux/Windows 打包流水线、Runner 前置条件和产物留存约定见 [Drone CI 打包](ci-drone.md)。
## 1.1 Windows Headless compatibility 验收
无 GPU 兼容模式必须覆盖仅 WARP、Microsoft Basic Display Adapter、Intel 核显和虚拟 GPU 环境;验证 DDA 的 DuplicateOutput/AcquireNextFrame 成功与失败、硬件编码器不可用时的软件编码选择、自动降到 1080p30/60 或更低档位、输入延迟不受软件编码阻塞、视频丢帧和关键帧恢复。诊断必须明确显示 software、cpu_upload、degraded 和不支持 4K/120。
兼容模式只在用户显式选择时启用。没有可复制的 DXGI Output 时应返回结构化 capture unavailableWARP 或 Basic Display Adapter 不得被报告为硬件 GPU 或硬件编码。
## 2. Rust workspace
```powershell
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```
当前 crate
- `remotedesk-protocol`required features、显示拓扑/选择、协商摘要、双端内存路径报告和严格聚合。
- `remotedesk-agent-core`:Linux 单/多屏捕获能力、逐屏 GPU import probe、编码器选择和分辨率/布局重验证。
- `remotedesk-agent-runtime`Linux `agentd`、用户会话 IPC、设备配对/WSS 认证、PAM/PTY 终端 helper,以及 Edge Presence、设备签名 poll/ack 和本地 Session Intent 授权。
- `remotedesk-client-core`:会话状态、helper 身份验证、RDP 凭据引用、多屏布局、GPU 计划和本地呈现报告。
- `remotedesk-control-service`:仅监听回环地址,提供静态界面、RDP 探测和三种 RDP 启动方式编排。
- `remotedesk-rdp-session`:独立的无凭据 IronRDP 协议与 TLS 证书探针,只从 stdin 接受目标和超时。
- `remotedesk-rdp-viewer`:独立 IronRDP 原生窗口;Windows 优先使用 D3D11 swap chain CPU 上传呈现,失败时回退 software framebuffer,不经过 React IPC。
- `remotedesk-native-video`:输出 D3D11 管线计划,并可在 Windows 真实创建硬件 device/immediate context。
- `remotedesk-edge-service`:独立 Edge Presence、有界签名 Session Intent 队列、Allocator/coturn credential 服务和限额透明 TCP byte relay;不随控制端或 Agent 进程启动。
- `remotedesk-update-manifest`:读取 Ed25519 PKCS#8 PEM 私钥,为最终 MSI 生成有界、不可覆盖的签名升级清单。
运行 native-video 规划:
```powershell
cargo run -p remotedesk-native-video -- --dry-run --window-adapter gpu-0
```
`--dry-run` 输出中的 `d3d11_created=false` 仅表示该规划命令不创建设备。真实设备探针使用:
```powershell
cargo run -p remotedesk-native-video -- --probe-d3d11
```
创建真实 H.264/DXVA decoder 对象、NV12 texture array 和 output view(仍不提交样本,也不证明零拷贝):
```powershell
cargo run -p remotedesk-native-video -- --probe-h264-decoder
```
使用本地 H.264 MP4/M4V/MOV 文件验证首个解码样本必须以同一 device 上的 NV12 DXGI texture 返回:
```powershell
cargo run -p remotedesk-native-video -- --probe-h264-file C:\samples\baseline.mp4
```
在原生窗口按媒体时间戳播放同一受限 H.264 文件,并通过同 device D3D11 VideoProcessor 呈现 NV12 surface
```powershell
cargo run -p remotedesk-native-video -- --play-h264-file C:\samples\baseline.mp4
```
窗口按启动配置进入全屏;按 `Ctrl+Alt+F` 在全屏与窗口模式之间切换,其余键盘输入直接转发到远端。该入口不映射 CPU frame,但在 ETW/GPUView 验证前仍不声明硬解或零拷贝。
输入必须是本地常规文件且不超过 512 MiB;UNC、空文件、非 H.264 video stream、CPU media buffer、错误 subresource 或不同 D3D11 device 均失败。成功只证明样本进入 DXGI surface,正式 `hardware_decode`/`zero_copy` 仍要求 ETW/GPUView 和完整呈现链验证。
成功时必须输出 `d3d11_created=true`、hardware driver type 和实际 feature level;这仍不代表解码器或端到端零拷贝已经接入。IronRDP viewer 的 swap chain 是独立 CPU 上传呈现路径。
控制服务还提供 `GET /api/v1/capabilities`。新增实际能力时,应同时更新 [实现状态](implementation-status.md) 和接口测试。
## 3. 原生管理界面
```powershell
cargo run --locked -p remotedesk-native-gui
```
该入口直接启动 `winit`/`wgpu`/`egui` 窗口,不启动浏览器、WebView 或 JavaScript 开发服务器。
## 4. M0 Windows 预览包
```powershell
.\packaging\windows\package-preview.ps1
```
输出位于 `artifacts/RemoteDesk-Portable-M0-<version>-windows-<arch>.zip`,并生成外部 `SHA256SUMS.txt`。解压后直接运行原生入口 `bin/remotedesk.exe`
该压缩包不是 MSI,也不包含 Linux Agent。Windows 提供 Rust 原生管理界面、`mstsc`、独立 IronRDP viewer 和 Windows Credential Manager 凭据适配器;viewer 支持固定/自定义初始尺寸、窗口动态分辨率、全屏和主动退出,协议探针会确认服务端 RDP 协商与 TLS 证书,但不会尝试账号登录。
生成按当前用户安装的 MSI
```powershell
.\packaging\windows\package-installer.ps1
```
输出位于 `artifacts/RemoteDesk-M0-<version>-<culture>-windows-<arch>.msi`,其中 `culture` 支持 `zh-cn``en-us`,默认是 `zh-cn`;校验文件为 `artifacts/INSTALLER-SHA256SUMS.txt`。安装目录是 `%LOCALAPPDATA%\Programs\RemoteDesk`,安装器创建开始菜单快捷方式并注册 Windows 卸载入口,不要求管理员权限。
使用统一脚本选择安装器语言:
```powershell
.\packaging\build-all.ps1 -Culture zh-cn
.\packaging\build-all.ps1 -Culture en-us
# 只构建客户端或只构建 Host
.\packaging\build-all.ps1 -SkipHost
.\packaging\build-all.ps1 -SkipClient
# 重新生成全部产物前清空 artifacts
.\packaging\build-all.ps1 -CleanArtifacts -Culture zh-cn
```
脚本下载固定版本和 SHA256 的 WiX 4.0.6 到忽略提交的 `target/tools`,WiX 不进入 MSI。当前没有切换到附带额外维护条款的 WiX 6 预编译发行包。无签名参数时脚本生成明确标记的开发包;正式环境先把具有私钥和 Code Signing EKU 的证书导入 `Cert:\CurrentUser\My`,再运行:
```powershell
./packaging/windows/package-installer.ps1 `
-SigningCertificateThumbprint <40位SHA1指纹> `
-TimestampUrl https://timestamp.digicert.com `
-ReleaseChannel stable
```
该路径在 payload 哈希之前签署并验证内部 EXE 和 PowerShell,在最终 MSI 哈希之前签署并验证 MSI。生产自动化及密钥要求见 [在线升级](online-updates.md)。
## 5. 被控端安装包
Windows 被控端 MSI
```powershell
.\packaging\windows-host\package-host.ps1
```
输出 `artifacts/RemoteDesk-Host-<version>-<culture>-windows-x64.msi`。这是 per-machine 包,但安装过程不自动修改 RDP;用户从开始菜单显式配置时才提权、备份并启用。脚本支持 `-Culture zh-cn|en-us`,并接受与控制端相同的 `-SigningCertificateThumbprint``-TimestampUrl`,正式发布时先签署 PowerShell payload,再签署最终 MSI。当前脚本继续使用固定哈希的 WiX 4.0.6,不引入 WiX 6 预编译包的额外维护协议。
Ubuntu/Fedora 构建机生成 Linux DEB/RPM
```sh
sh ./packaging/linux/package-deb.sh
sh ./packaging/linux/package-rpm.sh
```
Windows 开发机如已安装 Rust musl target、Android NDK LLVM 和 Git for Windows,可生成静态 x64 便携包与 musl DEB
```powershell
.\packaging\linux\package-musl.ps1
```
Linux 包的 `/etc/remotedesk/agent.env` 包含默认监听地址和可选 Edge Presence 注释模板。Presence 配置必须四项同时存在;测试只能使用专用的非生产令牌,公网 URL 必须为 HTTPS。`remotedesk-agentd status --json` 可检查持久化的非敏感健康状态,SIGINT/SIGTERM 会触发限时 connection-bound 注销。
Ubuntu 22.04 CI 会对 Linux 目标执行测试和 Clippy,再构建原生 DEB/RPM。Windows 上的 musl 交叉构建只验证静态 ELF 和包结构,不能替代 systemd、PAM、PTY 和发行版安装测试。
独立 Edge 服务在 Ubuntu 构建原生 DEB
```sh
sh ./packaging/edge/package-deb.sh
```
Windows 开发机生成静态 Edge TAR 和 musl DEB
```powershell
.\packaging\edge\package-musl.ps1
```
输出为 `artifacts/RemoteDesk-Edge-<version>-linux-x64.tar.gz``artifacts/remotedesk-edge_<version>_amd64-musl.deb`。配置与部署边界见 `packaging/edge/README.md`HTTP API 只能监听 loopback 并经 HTTPS reverse proxy 发布,TCP relay 应经 TLS/L4 入口发布,安装包不生成密钥且不会自动启动服务。CI 对 Edge crate 单独执行测试、Clippy 和 DEB 构建。
本地联合验证可让 Agent 使用 Presence 专用令牌注册,再在 Windows 控制端“全局设置 > Edge 会话授权”填写 HTTPS Origin。Client 的 Session Intent 提交和状态查询由 Client Ed25519 key 认证,不要把 `REMOTEDESK_EDGE_API_TOKEN` 写入 Windows 设置。首次配对时录入 Agent 本地 `pairing-code` 命令输出的设备公钥和证书指纹;只要 Agent 已在线且本机配对窗口仍有效,未配对 Client 即可提交独立 `pairing` Intent,经角色票据和 opaque relay 完成证书固定 TLS/WSS、Agent 公钥核对、Client challenge 签名及一次性码验证,无需连接 Agent listener。成功后 Agent 公钥按证书指纹保存在 `RemoteDesk/Linux/agent/<certificate-sha256>` Windows Credential Manager 条目;缺少 Edge 或设备公钥时保留直连配对回退。后续已知设备同样直接向 Edge 建立,控制端可检查或显式删除身份映射。自动化联合测试连续覆盖远程首次配对、已知设备重连、双向 TLS/WebSocket 字节和两类票据重放;另一组联合 API 测试覆盖接受会话内签名 SDP/ICE mailbox 的双向 offer/answer、伪造、重放和顺序/代际冲突。这些测试仍不能替代端点 WebRTC、真实 TURN POP 或跨网络媒体验证。
## 6. 实现边界
首轮代码只实现可测试的策略和状态模型。以下能力仍必须由 M0 实验验证:
- PipeWire DMA-BUF 到硬件编码器无 CPU 回读。
- Xorg 捕获后端;Portal/PipeWire 优先,DRI3 只能按环境验证。
- GStreamer D3D11 decoder、allocator、sink 和 Adapter LUID 一致。
- IronRDP NLA、动态分辨率服务端兼容性、UDP multitransport 和图形 surface 的真实 Windows 主机验证。
- TWCC/GCC、RTX/FEC 与硬件编码器码率动态更新。
- RDP viewer Named Pipe/Job Object 尚需 Windows 实机完成 ACL、PID/创建时间、镜像 hash、challenge MAC、控制服务崩溃回收和 helper 失败诊断验收;Tauri 壳需完成依赖解析、Windows 编译、随机端口导航限制、控制服务异常退出和升级重启验收,native-video 管道仍未接入。
- Windows Credential Manager 与 RDP NLA 凭据交付的真实远端登录验收。
- RDP Display Control 与 Linux Portal/XRandR 多显示器平台适配、热插拔和混合 DPI 实测。
- Linux WSS 配对、`SO_PEERCRED` IPC、PAM/PTY 和 systemd 在真实发行版的端到端实测。