mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-01-28 16:41:52 +08:00
feat: 添加 RustDesk 协议支持和项目文档
- 新增 RustDesk 模块,支持与 RustDesk 客户端连接 - 实现会合服务器协议和 P2P 连接 - 支持 NaCl 加密和密钥交换 - 添加视频帧和 HID 事件适配器 - 添加 Protobuf 协议定义 (message.proto, rendezvous.proto) - 新增完整项目文档 - 各功能模块文档 (video, hid, msd, otg, webrtc 等) - hwcodec 和 RustDesk 协议技术报告 - 系统架构和技术栈文档 - 更新 Web 前端 RustDesk 配置界面和 API
This commit is contained in:
401
docs/report/rustdesk/08-onekvm-comparison.md
Normal file
401
docs/report/rustdesk/08-onekvm-comparison.md
Normal file
@@ -0,0 +1,401 @@
|
||||
# RustDesk 协议 vs One-KVM 实现对比分析
|
||||
|
||||
本文档对比分析 RustDesk 原始协议与 One-KVM 的实现差异。
|
||||
|
||||
## 1. 概述
|
||||
|
||||
One-KVM 作为 IP-KVM 解决方案,只实现了 RustDesk 协议的**被控端(Controlled)** 功能,不实现控制端(Controller)功能。这是设计决策,因为 KVM 设备只需要接收远程控制,不需要控制其他设备。
|
||||
|
||||
### 架构差异
|
||||
|
||||
| 方面 | RustDesk 原版 | One-KVM |
|
||||
|------|---------------|---------|
|
||||
| 角色 | 双向(控制端+被控端) | 单向(仅被控端) |
|
||||
| 连接方式 | P2P + Relay | 仅 Relay (TCP) |
|
||||
| NAT 穿透 | UDP/TCP 打洞 + TURN | 不支持 |
|
||||
| 传输协议 | UDP/TCP | 仅 TCP |
|
||||
|
||||
## 2. 已实现功能
|
||||
|
||||
### 2.1 Rendezvous 协议 (hbbs 通信)
|
||||
|
||||
| 消息类型 | 实现状态 | 备注 |
|
||||
|----------|----------|------|
|
||||
| RegisterPeer | ✅ 已实现 | 注册设备到服务器 |
|
||||
| RegisterPeerResponse | ✅ 已实现 | 处理注册响应 |
|
||||
| RegisterPk | ✅ 已实现 | 注册公钥 |
|
||||
| RegisterPkResponse | ✅ 已实现 | 处理公钥注册响应 |
|
||||
| PunchHoleSent | ✅ 已实现 | 响应打洞请求 |
|
||||
| FetchLocalAddr | ✅ 已实现 | 获取本地地址 |
|
||||
| LocalAddr | ✅ 已实现 | 返回本地地址 |
|
||||
| RequestRelay | ✅ 已实现 | 请求中继连接 |
|
||||
| RelayResponse | ✅ 已实现 | 处理中继响应 |
|
||||
| ConfigUpdate | ✅ 已实现 | 接收配置更新 |
|
||||
|
||||
**实现文件**: `src/rustdesk/rendezvous.rs` (~829 行)
|
||||
|
||||
```rust
|
||||
// 核心结构
|
||||
pub struct RendezvousMediator {
|
||||
config: RustDeskConfig,
|
||||
key_pair: KeyPair,
|
||||
signing_key: SigningKeyPair,
|
||||
socket: UdpSocket,
|
||||
status: Arc<RwLock<RendezvousStatus>>,
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 连接协议 (客户端连接)
|
||||
|
||||
| 消息类型 | 实现状态 | 备注 |
|
||||
|----------|----------|------|
|
||||
| SignedId | ✅ 已实现 | 签名身份验证 |
|
||||
| PublicKey | ✅ 已实现 | 公钥交换 |
|
||||
| Hash | ✅ 已实现 | 哈希挑战响应 |
|
||||
| LoginRequest | ✅ 已实现 | 登录认证 |
|
||||
| LoginResponse | ✅ 已实现 | 登录响应 |
|
||||
| TestDelay | ✅ 已实现 | 延迟测试 |
|
||||
| VideoFrame | ✅ 已实现 | 视频帧发送 |
|
||||
| AudioFrame | ✅ 已实现 | 音频帧发送 |
|
||||
| CursorData | ✅ 已实现 | 光标图像 |
|
||||
| CursorPosition | ✅ 已实现 | 光标位置 |
|
||||
| MouseEvent | ✅ 已实现 | 鼠标事件接收 |
|
||||
| KeyEvent | ✅ 已实现 | 键盘事件接收 |
|
||||
|
||||
**实现文件**: `src/rustdesk/connection.rs` (~1349 行)
|
||||
|
||||
```rust
|
||||
// 连接状态机
|
||||
pub enum ConnectionState {
|
||||
WaitingForSignedId,
|
||||
WaitingForPublicKey,
|
||||
WaitingForHash,
|
||||
WaitingForLogin,
|
||||
Authenticated,
|
||||
Streaming,
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 加密模块
|
||||
|
||||
| 功能 | 实现状态 | 备注 |
|
||||
|------|----------|------|
|
||||
| Curve25519 密钥对 | ✅ 已实现 | 用于加密 |
|
||||
| Ed25519 签名密钥对 | ✅ 已实现 | 用于签名 |
|
||||
| Ed25519 → Curve25519 转换 | ✅ 已实现 | 密钥派生 |
|
||||
| XSalsa20-Poly1305 | ✅ 已实现 | 会话加密 (secretbox) |
|
||||
| 密码哈希 | ✅ 已实现 | 单重/双重 SHA256 |
|
||||
| 会话密钥协商 | ✅ 已实现 | 对称密钥派生 |
|
||||
|
||||
**实现文件**: `src/rustdesk/crypto.rs` (~468 行)
|
||||
|
||||
```rust
|
||||
// 密钥对结构
|
||||
pub struct KeyPair {
|
||||
secret_key: [u8; 32], // Curve25519 私钥
|
||||
public_key: [u8; 32], // Curve25519 公钥
|
||||
}
|
||||
|
||||
pub struct SigningKeyPair {
|
||||
secret_key: [u8; 64], // Ed25519 私钥
|
||||
public_key: [u8; 32], // Ed25519 公钥
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 视频/音频流
|
||||
|
||||
| 编码格式 | 实现状态 | 备注 |
|
||||
|----------|----------|------|
|
||||
| H.264 | ✅ 已实现 | 主要格式 |
|
||||
| H.265/HEVC | ✅ 已实现 | 高效编码 |
|
||||
| VP8 | ✅ 已实现 | WebRTC 兼容 |
|
||||
| VP9 | ✅ 已实现 | 高质量 |
|
||||
| AV1 | ✅ 已实现 | 新一代编码 |
|
||||
| Opus 音频 | ✅ 已实现 | 低延迟音频 |
|
||||
|
||||
**实现文件**: `src/rustdesk/frame_adapters.rs` (~316 行)
|
||||
|
||||
### 2.5 HID 事件
|
||||
|
||||
| 功能 | 实现状态 | 备注 |
|
||||
|------|----------|------|
|
||||
| 鼠标移动 | ✅ 已实现 | 绝对/相对坐标 |
|
||||
| 鼠标按键 | ✅ 已实现 | 左/中/右键 |
|
||||
| 鼠标滚轮 | ✅ 已实现 | 垂直滚动 |
|
||||
| 键盘按键 | ✅ 已实现 | 按下/释放 |
|
||||
| 控制键映射 | ✅ 已实现 | ControlKey → USB HID |
|
||||
| X11 键码映射 | ✅ 已实现 | X11 → USB HID |
|
||||
|
||||
**实现文件**: `src/rustdesk/hid_adapter.rs` (~386 行)
|
||||
|
||||
### 2.6 协议帧编码
|
||||
|
||||
| 功能 | 实现状态 | 备注 |
|
||||
|------|----------|------|
|
||||
| BytesCodec | ✅ 已实现 | 变长帧编码 |
|
||||
| 1-4 字节头 | ✅ 已实现 | 根据长度自动选择 |
|
||||
| 最大 1GB 消息 | ✅ 已实现 | 与原版一致 |
|
||||
|
||||
**实现文件**: `src/rustdesk/bytes_codec.rs` (~253 行)
|
||||
|
||||
## 3. 未实现功能
|
||||
|
||||
### 3.1 NAT 穿透相关
|
||||
|
||||
| 功能 | 原因 |
|
||||
|------|------|
|
||||
| UDP 打洞 | One-KVM 仅使用 TCP 中继 |
|
||||
| TCP 打洞 | 同上 |
|
||||
| STUN/TURN | 不需要 NAT 类型检测 |
|
||||
| TestNat | 同上 |
|
||||
| P2P 直连 | 设计简化,仅支持中继 |
|
||||
|
||||
### 3.2 客户端发起功能
|
||||
|
||||
| 功能 | 原因 |
|
||||
|------|------|
|
||||
| PunchHole (发起) | KVM 只接收连接 |
|
||||
| RelayRequest | 同上 |
|
||||
| ConnectPeer | 同上 |
|
||||
| OnlineRequest | 不需要查询其他设备 |
|
||||
|
||||
### 3.3 文件传输
|
||||
|
||||
| 功能 | 原因 |
|
||||
|------|------|
|
||||
| FileTransfer | 超出 KVM 功能范围 |
|
||||
| FileAction | 同上 |
|
||||
| FileResponse | 同上 |
|
||||
| FileTransferBlock | 同上 |
|
||||
|
||||
### 3.4 高级功能
|
||||
|
||||
| 功能 | 原因 |
|
||||
|------|------|
|
||||
| 剪贴板同步 | 超出 KVM 功能范围 |
|
||||
| 多显示器切换 | One-KVM 使用单一视频源 |
|
||||
| 虚拟显示器 | 不适用 |
|
||||
| 端口转发 | 超出 KVM 功能范围 |
|
||||
| 语音通话 | 不需要 |
|
||||
| RDP 输入 | 不需要 |
|
||||
| 插件系统 | 不支持 |
|
||||
| 软件更新 | One-KVM 有自己的更新机制 |
|
||||
|
||||
### 3.5 权限协商
|
||||
|
||||
| 功能 | 原因 |
|
||||
|------|------|
|
||||
| Option 消息 | One-KVM 假设完全控制权限 |
|
||||
| 权限请求 | 同上 |
|
||||
| PermissionInfo | 同上 |
|
||||
|
||||
## 4. 实现差异
|
||||
|
||||
### 4.1 连接模式
|
||||
|
||||
**RustDesk 原版:**
|
||||
```
|
||||
客户端 ──UDP打洞──> 被控端 (P2P 优先)
|
||||
└──Relay──> 被控端 (回退)
|
||||
```
|
||||
|
||||
**One-KVM:**
|
||||
```
|
||||
RustDesk客户端 ──TCP中继──> hbbr服务器 ──> One-KVM设备
|
||||
```
|
||||
|
||||
One-KVM 只支持 TCP 中继连接,不支持 P2P 直连。这简化了实现,但可能增加延迟。
|
||||
|
||||
### 4.2 会话加密
|
||||
|
||||
**RustDesk 原版:**
|
||||
- 支持 ChaCha20-Poly1305 (流式)
|
||||
- 支持 XSalsa20-Poly1305 (secretbox)
|
||||
- 动态协商加密方式
|
||||
|
||||
**One-KVM:**
|
||||
- 仅支持 XSalsa20-Poly1305 (secretbox)
|
||||
- 使用序列号作为 nonce
|
||||
|
||||
```rust
|
||||
// One-KVM 的加密实现
|
||||
fn encrypt_message(&mut self, plaintext: &[u8]) -> Vec<u8> {
|
||||
let nonce = make_nonce(&self.send_nonce);
|
||||
self.send_nonce = self.send_nonce.wrapping_add(1);
|
||||
secretbox::seal(plaintext, &nonce, &self.session_key)
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 视频流方向
|
||||
|
||||
**RustDesk 原版:**
|
||||
- 双向视频流(可控制和被控制)
|
||||
- 远程桌面捕获
|
||||
|
||||
**One-KVM:**
|
||||
- 单向视频流(仅发送)
|
||||
- 从 V4L2 设备捕获
|
||||
- 集成到 One-KVM 的 VideoStreamManager
|
||||
|
||||
```rust
|
||||
// One-KVM 视频流集成
|
||||
pub async fn start_video_stream(&self, state: &AppState) {
|
||||
let stream_manager = &state.video_stream_manager;
|
||||
// 从 One-KVM 的视频管理器获取帧
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 HID 事件处理
|
||||
|
||||
**RustDesk 原版:**
|
||||
- 转发到远程系统的输入子系统
|
||||
- 使用 enigo 或 uinput
|
||||
|
||||
**One-KVM:**
|
||||
- 转发到 USB OTG/HID 设备
|
||||
- 控制物理 KVM 目标机器
|
||||
|
||||
```rust
|
||||
// One-KVM HID 适配
|
||||
pub fn convert_mouse_event(event: &RustDeskMouseEvent) -> Option<OneKvmMouseEvent> {
|
||||
// 转换 RustDesk 鼠标事件到 One-KVM HID 事件
|
||||
}
|
||||
|
||||
pub fn convert_key_event(event: &RustDeskKeyEvent) -> Option<OneKvmKeyEvent> {
|
||||
// 转换 RustDesk 键盘事件到 One-KVM HID 事件
|
||||
}
|
||||
```
|
||||
|
||||
### 4.5 配置管理
|
||||
|
||||
**RustDesk 原版:**
|
||||
- 使用 TOML/JSON 配置文件
|
||||
- 硬编码默认值
|
||||
|
||||
**One-KVM:**
|
||||
- 集成到 SQLite 配置系统
|
||||
- Web UI 管理
|
||||
- 使用 typeshare 生成 TypeScript 类型
|
||||
|
||||
```rust
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RustDeskConfig {
|
||||
pub enabled: bool,
|
||||
pub rendezvous_server: String,
|
||||
pub device_id: String,
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 4.6 设备 ID 生成
|
||||
|
||||
**RustDesk 原版:**
|
||||
- 基于 MAC 地址和硬件信息
|
||||
- 固定便携式 ID
|
||||
|
||||
**One-KVM:**
|
||||
- 随机生成 9 位数字
|
||||
- 存储在配置中
|
||||
|
||||
```rust
|
||||
pub fn generate_device_id() -> String {
|
||||
let mut rng = rand::thread_rng();
|
||||
let id: u32 = rng.gen_range(100_000_000..999_999_999);
|
||||
id.to_string()
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 协议兼容性
|
||||
|
||||
### 5.1 完全兼容
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| Rendezvous 注册 | 可与官方 hbbs 服务器通信 |
|
||||
| 中继连接 | 可通过官方 hbbr 服务器中继 |
|
||||
| 加密握手 | 与 RustDesk 客户端兼容 |
|
||||
| 视频编码 | 支持所有主流编码格式 |
|
||||
| HID 事件 | 接收标准 RustDesk 输入事件 |
|
||||
|
||||
### 5.2 部分兼容
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| 密码认证 | 仅支持设备密码,不支持一次性密码 |
|
||||
| 会话加密 | 仅 XSalsa20-Poly1305 |
|
||||
|
||||
### 5.3 不兼容
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| P2P 连接 | 客户端必须通过中继连接 |
|
||||
| 文件传输 | 不支持 |
|
||||
| 剪贴板 | 不支持 |
|
||||
|
||||
## 6. 代码结构对比
|
||||
|
||||
### RustDesk 原版结构
|
||||
|
||||
```
|
||||
rustdesk/
|
||||
├── libs/hbb_common/ # 公共库
|
||||
│ ├── protos/ # Protobuf 定义
|
||||
│ └── src/
|
||||
├── src/
|
||||
│ ├── server/ # 被控端服务
|
||||
│ ├── client/ # 控制端
|
||||
│ ├── ui/ # 用户界面
|
||||
│ └── rendezvous_mediator.rs
|
||||
```
|
||||
|
||||
### One-KVM 结构
|
||||
|
||||
```
|
||||
src/rustdesk/
|
||||
├── mod.rs # 模块导出
|
||||
├── config.rs # 配置类型 (~164 行)
|
||||
├── crypto.rs # 加密模块 (~468 行)
|
||||
├── bytes_codec.rs # 帧编码 (~253 行)
|
||||
├── protocol.rs # 消息辅助 (~170 行)
|
||||
├── rendezvous.rs # Rendezvous 中介 (~829 行)
|
||||
├── connection.rs # 连接处理 (~1349 行)
|
||||
├── hid_adapter.rs # HID 转换 (~386 行)
|
||||
└── frame_adapters.rs # 视频/音频适配 (~316 行)
|
||||
```
|
||||
|
||||
**总计**: ~3935 行代码
|
||||
|
||||
## 7. 总结
|
||||
|
||||
### 实现率统计
|
||||
|
||||
| 类别 | RustDesk 功能数 | One-KVM 实现数 | 实现率 |
|
||||
|------|-----------------|----------------|--------|
|
||||
| Rendezvous 协议 | 15+ | 10 | ~67% |
|
||||
| 连接协议 | 30+ | 12 | ~40% |
|
||||
| 加密功能 | 8 | 6 | 75% |
|
||||
| 视频/音频 | 6 | 6 | 100% |
|
||||
| HID 功能 | 6 | 6 | 100% |
|
||||
|
||||
### 设计理念
|
||||
|
||||
One-KVM 的 RustDesk 实现专注于 **IP-KVM 核心功能**:
|
||||
|
||||
1. **精简**: 只实现必要的被控端功能
|
||||
2. **可靠**: 使用 TCP 中继保证连接稳定性
|
||||
3. **集成**: 与 One-KVM 现有视频/HID 系统无缝集成
|
||||
4. **安全**: 完整实现加密和认证机制
|
||||
|
||||
### 客户端兼容性
|
||||
|
||||
One-KVM 可与标准 RustDesk 客户端配合使用:
|
||||
- RustDesk 桌面客户端 (Windows/macOS/Linux)
|
||||
- RustDesk 移动客户端 (Android/iOS)
|
||||
- RustDesk Web 客户端
|
||||
|
||||
只需确保:
|
||||
1. 配置相同的 Rendezvous 服务器
|
||||
2. 使用设备 ID 和密码连接
|
||||
3. 客户端支持中继连接
|
||||
Reference in New Issue
Block a user