Type 0 节点互联协议¶
历史兼容文档:本页只适用于
edge分支保留的无数据库边缘运行时。dev不启动 Type 0/TLS 节点控制面,也不解析边缘节点配置;当前中心到中心互联请阅读多中心群组互联设计。
普通设备和第三方客户端只应使用公开的 DraARLv1 Type 1-5;Type 0 只允许已认证的 edge 分支节点会话使用。edge 分支由独立的边缘配置和中心节点服务管理,不能把本页字段加入 dev 的中心配置。
1. 拓扑与端口¶
dev分支的draarl二进制只运行中心模式;需要启动无数据库边缘进程时,使用edge分支。- 中心负责 HTTP、MySQL、Redis、完整路由和权限;边缘负责普通设备接入、本地转发和节点互联。
- 边缘节点控制面使用其分支内的 TLS 配置;该控制面不属于
dev的中心互联端口。 edge分支的 Type 0 数据面与其普通设备流量共用边缘 UDP socket;中心到中心音频则使用dev的共享主 UDP 端口。GET /api/access-points在dev当前只返回配置的主中心入口。
本页后续章节描述的路由投影、节点心跳、设备下发和 Type 0 信封,均为 edge 分支兼容协议。
2. 数据路径¶
设备 -> 来源边缘 -> 本地 fan-out
-> 一份 RelayUpstream -> 中心
-> 中心本地 fan-out
-> 每个目标边缘一份 RelayDownstream
-> 本地 fan-out
中心按 SessionID + SessionEpoch 校验来源所有权,并从权威路由重新确定通信域和收发权限。中心不会把 Downstream 发回来源边缘;目标边缘也不会再次上传 Downstream。
Type 4 文本直接转发。Type 5 语音必须先通过 TLS 控制面的 SpeakerLease 取得中心话权,同一通信域同时只允许一个有效说话人。
边缘来源的 Type 4/5 只有在中心完成节点会话、设备所有权、路由权限、inner packet 身份和话权校验后才写入通信记录。该上行验收点是唯一记录入口;来源边缘本地 fan-out、中心本地投递和 RelayDownstream 都不重复记录。中心直连设备仍使用普通 UDP/WS 入口原有的记录流程。
3. Type 0 UDP 信封¶
UDP 信封最大 1400 字节。整数均使用网络字节序。
| 偏移 | 长度 | 字段 |
|---|---|---|
| 0 | 4 | DraA |
| 4 | 2 | 完整包长 |
| 6 | 32 | SourceNodeID,零填充 |
| 48 | 1 | Type,固定为 0 |
| 86 | 4 | NOD0 |
| 90 | 1 | 节点协议版本 |
| 91 | 1 | 子类型 |
| 92 | 2 | Flags |
| 94 | 8 | ClusterEpoch |
| 102 | 8 | ProjectionVersion |
| 110 | 8 | NodeSessionID |
| 118 | 8 | MessageID |
| 126 | 8 | SentAtMillis |
| 134 | 1 | HopCount |
| 135 | 4 | KeyEpoch |
| 139 | 4 | Payload 长度 |
| 143 | 可变 | Payload |
| 末尾 | 32 | HMAC-SHA256 |
HMAC 覆盖信封头和 Payload。会话密钥、NodeSessionID 和 KeyEpoch 由已认证 TLS 控制连接建立;普通设备字段不参与节点身份判断。
节点在 TLS 握手中同时提交支持的最小/最大协议版本、功能位和必需功能位。中心
选择双方共同支持的最高版本,并只启用功能位交集;版本区间不相交,或任一方的
必需功能不在交集中时,凭据校验前即拒绝连接。当前协议范围为 1..1,功能位为:
| 位 | 能力 |
|---|---|
0 |
路由快照、增量与 ACK |
1 |
Type 0 UDP Relay |
2 |
边缘设备短期会话 |
3 |
Type 3 配置上下发 |
4 |
跨节点 Speaker Lease |
5 |
节点运行指标 |
6 |
在线节点凭据轮换与持久化确认 |
7 |
中心重启后的边缘设备会话重新确认 |
8 |
幽灵设备实例身份、多 Session 路由、多 RX domain 与来源频道 |
9 |
幽灵 Session 短期恢复票据与续租轮换 |
前 3 位是当前运行所必需的能力。功能协商结果绑定到本次随机
NodeSessionID,断线重连后必须重新协商。
4. 子类型¶
| 值 | 名称 | 通道 | 方向 |
|---|---|---|---|
0x01 |
NodeEnroll | TLS | 边缘与中心 |
0x03 |
NodeAuth | TLS | 边缘与中心 |
0x05 |
NodeHeartbeat | TLS | 双向状态与指标 |
0x06 |
NodeDataBind | TLS 挑战、UDP 证明 | 双向 |
0x07 |
NodeCredential | TLS | 中心下发轮换凭据、边缘持久化后确认 |
0x10 |
RouteSnapshotBegin | TLS | 中心到边缘 |
0x11 |
RouteSnapshotChunk | TLS | 中心到边缘 |
0x12 |
RouteSnapshotCommit | TLS | 中心到边缘 |
0x13 |
RouteDelta | TLS | 中心到边缘 |
0x14 |
RouteAck | TLS | 边缘到中心 |
0x15 |
RouteResyncRequest | TLS | 边缘到中心 |
0x20 |
DeviceAuth | TLS | 双向 |
0x21 |
DeviceSessionRenew | TLS | 双向 |
0x22 |
DeviceSessionReport | TLS | 边缘到中心 |
0x23 |
DeviceSessionRevoke | TLS | 中心到边缘 |
0x24 |
DeviceConfig | TLS | 双向 Type 3 配置 |
0x25 |
DeviceSessionConfirm | TLS | 边缘到中心批量确认,中心返回新短期授权 |
0x28 |
SpeakerLease | TLS | 双向 Type 5 话权 |
0x30 |
RelayUpstream | UDP | 边缘到中心 |
0x31 |
RelayDownstream | UDP | 中心到边缘 |
控制面使用 4 字节长度前缀的 JSON 帧承载握手消息和经过 HMAC 的 Type 0 控制信封,单个 Type 0 控制信封最大 65535 字节。路由快照最多 64 MiB,按 32 KiB 原始块分片。接收方要求分块数与声明总长度一致,每块长度必须精确匹配所在位置,内容冲突的重复块会被拒绝;全部分块通过总长度和 SHA-256 校验后才原子提交。
Flags 的 0x0010 位表示关键扩展。接收方遇到未知的非关键子类型时只丢弃该帧;
遇到未知关键子类型时必须返回通用协议错误并关闭节点会话。错误响应不回显原始
Payload、凭据或密钥。
5. 路由版本与帧龄¶
ClusterEpoch在中心世代变化后失效旧状态。- 每个边缘拥有独立、连续的
ProjectionVersion,无关节点变化不会制造版本空洞。 - Downstream 携带目标边缘所需版本;边缘落后时最多等待 1024 帧和 200 ms,追上版本后释放,否则丢弃。
MessageID在节点会话内经过固定 4096 位重放窗口检查。
中心重启会生成新的 ClusterEpoch、节点控制会话和设备短期会话。边缘在
node_ready 前按每批最多 128 个设备发送 DeviceSessionConfirm,携带旧设备
会话、设备/所有者/SSID 和旧控制会话证明。标准实体设备必须与数据库中的入口
NodeID、旧控制会话和设备身份一致。幽灵设备必须额外提交中心签发的短期 HMAC
恢复票据;中心验证票据绑定的 NodeID、旧控制会话、幽灵 Session UUID、tag、
客户端实例、Owner、SSID、DevModel 和有效期,再重新查询当前用户状态与频道
权限。任一种证明失败都不得签发新授权。边缘先
原子替换本地 session ID,再应用新 epoch 的最终全量投影;确认期间收到的增量
或重同步快照只能缓存和 ACK,不能用新 ID 投影裁剪仍使用旧 ID 的本地会话,
也不能提前解除 fail closed。未协商能力、证明不匹配或超过恢复窗口的会话必须
删除并回到普通设备认证流程。
时间限制分为两层:
- UDP 入口使用
SentAtMillis做±2 s的粗粒度会话新鲜度检查,用于拒绝明显陈旧或未来的包。节点应启用系统时间同步,但不要求服务器时钟精确到实时帧队列的毫秒级。 - 包到达边缘后记录本机单调时间。200 ms 只限制本地投影等待和队列积压,不把国内外公网 RTT 或两台服务器的墙上时钟偏差算作本地排队。
因此 150 ms 等正常跨地域网络延迟不会被 200 ms 本地队列时限直接拒绝。若需要观测跨地域延迟,应在 TLS 控制面增加 RTT/时钟偏差指标,而不是把跨主机墙上时钟作为实时转发的硬条件。
6. 幽灵设备多 Session 扩展¶
功能位 8(NodeFeatureGhostMultiSession)和功能位 9(NodeFeatureGhostRecoveryTicket)都是幽灵 Session 的必需能力,不属于前三个实体设备基础位。新中心可以与旧边缘连接,但缺少任一能力的边缘只能继续承载标准实体设备;幽灵认证明确返回 node_ghost_multi_session_unsupported,不得静默降级身份或进入无票据恢复路径。
6.1 身份与路由字段¶
标准实体设备继续使用原身份编码。幽灵 DeviceGrant 和 DeviceRoute 额外携带:
| 字段 | 用途 |
|---|---|
ghost_session_id |
HTTP/客户端层临时 Session 的不可预测 ID |
client_instance_id |
同账号同平台下的稳定安装实例 UUID |
session_tag |
UDP 热路径短标识 |
ghost_protocol_version |
幽灵认证 payload 版本 |
rx_group_ids |
直接接收订阅,供状态和路由更新使用 |
rx_domain_ids |
由中心拓扑解析出的接收通信域集合 |
source_group_v1 |
目标端能否解释 DraARLv1 Reserved 来源频道 |
recovery_ticket |
仅在 TLS 控制面传递的短期 HMAC 恢复证明;不进入客户端 UDP 包或公开 API |
中心在线身份对现代幽灵使用 owner_id + ssid + client_instance_id,不会因同账号第二个手机上线而迁移第一个。节点转发和撤销使用中心签发的全局 SessionID + SessionEpoch;ghost_session_id 用于把 HTTP routing 更新精确映射到该在线入口。
group_id/domain_id 是唯一发送路由。下行目标按 rx_domain_ids 建立投影;同一 Session 因多个订阅或互联路径命中时只投递一次。来源排除使用精确 Session ID,同用户名、同 SSID 的其他客户端实例仍正常接收。disable_send 和 disable_recv 在更新多接收路由时必须保留。
6.2 Relay 与来源频道¶
中心只接受当前边缘控制会话拥有的 SessionID + SessionEpoch 上行,并从权威 Route 重写 DomainID 和来源群组。向协商功能位 8 的目标边缘发送 Downstream 时,inner Type 4/5 的 DraARLv1 Reserved 携带 source_group_id;发往旧节点前必须清零,避免旧客户端误解保留字段。
边缘本地 fan-out 同样按 Session 去重,并按接收客户端能力分别发送带来源字段或 Reserved 为 0 的帧。一个已认证 UDP 端点不能安装两个不同 Session;边缘拒绝冲突 grant 后会通过 DeviceSessionReport 通知中心撤销刚签发的入口。
6.3 切换与恢复¶
路由增量必须原子替换 group_id/domain_id/rx_group_ids/rx_domain_ids。节点切换时只迁移目标现代实例,其他同账号 Session 保持原节点。控制链重连的 DeviceSessionConfirmItem 必须同时证明 ghost_session_id、client_instance_id、Owner、SSID、DevModel、旧 Session、旧控制会话和 recovery_ticket;另一个 NodeID 不能冒领该幽灵 Session。
恢复票据使用部署中稳定的 JWT 密钥做域分离 HMAC,只包含恢复所需身份,不包含 JWT 或设备密码。票据与两分钟短期授权同时到期,并在每次 Session 续租、重确认后轮换。中心重启后用票据恢复同一个 ghost_session_id 和 session_tag,但路由、用户启用状态和审核状态始终从当前数据库重新读取;票据不能保留后来已撤销的频道权限。
中心永久失去边缘后会移除实时路由,并在 SessionRecoveryWindowSeconds 内等待同一节点重新确认。窗口到期才调用幽灵 Session 清理;成功确认会取消对应清理任务,不影响同账号兄弟 Session。
反复控制链抖动后,中心的 Session 所有权、幽灵索引、节点计数和路由投影必须收敛到当前控制会话,旧断连回调与旧恢复计时器不得撤销新 Session。网络分区超过边缘本地 grace 后,边缘必须清空 Session、身份/tag 索引和未完成控制请求;控制链恢复时不得无认证复活已过期 Session,客户端重新认证后才建立新的短期授权。
7. 滚动升级与回滚¶
推荐顺序:
- 备份 MySQL,执行兼容数据库迁移;新增字段和表不会破坏旧服务端读取。
- 先升级中心。新中心与旧边缘只协商功能位交集;旧边缘仅继续承载实体设备。
- 逐个升级边缘并确认节点详情中的协议版本、功能位、投影 ACK 和 UDP data bind 正常。
- 最后发布 Web 和原生客户端。只有连接到已同时协商功能位 8、9 的边缘时才发送版本化幽灵认证。
- 观察 Session 数、路由 ACK、会话确认拒绝、无效 session tag、fan-out 去重和写队列指标后再扩大客户端覆盖。
回滚时先关闭幽灵功能入口,再回滚边缘,最后回滚中心。不要删除 ghost_client_preferences、订阅关系、消息字段或复合索引,保留它们可避免再次升级时丢失客户端路由。若只有单个边缘异常,可将其回滚为旧版;该节点会拒绝所有幽灵 Session,但仍可承载标准实体设备。
8. 安全与资源隔离¶
- 首次注册 token 只用于换取长期节点身份;identity 文件不得写入日志或公开接口。
- 管理员轮换凭据时,中心先原子安装新凭据并在有限宽限期内保留旧凭据哈希。在线边缘通过 TLS 收到新凭据,必须先原子写入 identity 文件再确认;中心只有收到确认才报告在线下发成功。离线节点需使用仅显示一次的响应手工更新 identity。
- 吊销操作同时清除注册、当前和宽限期凭据并递增凭据世代,随后断开当前会话;单独的强制下线只重置连接,不吊销仍有效的凭据。
- 数据地址只能通过 TLS 下发的随机挑战和 UDP HMAC 证明绑定或重绑,普通中继包不能改变地址。
- 有效 Type 0 绕过普通设备 IP 限速,但仍受独立的每节点 PPS、带宽、队列、会话数和全局节点数上限约束。
- HMAC 失败、身份不符、过期、重放、未绑定地址、绑定拒绝、队列满和硬限额分别计数。
- inner packet 只允许规范化后的 Type 4/5,设备密码和 JWT 不进入 UDP 中继载荷;Type 3 只走 TLS 控制面。
- 幽灵恢复票据只在已认证 TLS 控制面流转,不进入 UDP Relay、日志、指标标签或管理 API;篡改、过期、跨 NodeID 和跨旧控制会话的票据全部拒绝。
相关配置见部署与配置,性能数据见UDP 转发压力测试。