【ZeroRange WebRTC】STUN srflx 与 ICE 连通性检查
STUN srflx 与 ICE 连通性检查
本文围绕“STUN 发现的 server‑reflexive 地址(srflx)如何用于与客户端建立通信”进行系统说明,涵盖:srflx 的定义与获取、候选交换与双向检查(UDP 打洞)、不同 NAT 下的成功与失败、TURN 回退策略,以及与 KVS WebRTC C SDK 的对应关系。附图展示双向打洞机制。
一、srflx 是什么
- 定义:
srflx(server‑reflexive)是“客户端在 STUN 服务器看到的公网映射地址与端口”。 - 获取过程:客户端向 STUN 发送请求,NAT 为这次外连创建映射(私网IP:本地端口 → 公网IP:映射端口);STUN回包中携带该映射地址,SDK据此生成
srflx候选。 - 注意:srflx 只是“你在外面的样子”,并不保证外部主机直接向它发包立即可达;真正能通要靠 ICE 的“双向连通性检查”。
二、ICE 候选交换与双向检查(打洞)

- 候选收集:双方生成
host/srflx/relay候选,并通过信令交换。 - 连通性检查:
- 双端将“本地候选”与“远端候选”两两配对;对每个候选对,同时向对方地址发送 STUN Binding Request。
- 由于“双方主动发包”,各自 NAT 会为“指向对方真实地址”的外连建立匹配的会话状态(五元组:源/目的IP与端口、协议),从而允许返回包进入内网,这就是“打洞”。
- 收到对方的 Binding Response(并通过消息完整性校验)即判定这条候选对“真打通”;ICE 控制/被控角色随后提名(nominate)最佳候选对作为传输路径。
- 会话维持:后续周期性发送 STUN(consent freshness/keepalive)以维持 NAT 映射不过期。
三、不同 NAT 下的效果
- Full Cone NAT:最容易打洞,只要地址正确即可通;成功率高。
- Restricted/Port‑Restricted Cone NAT:要求返回包来自“先前外连过的远端 IP(甚至端口)”;双向检查正是为了满足这一匹配条件。
- Symmetric NAT:针对不同外部目的地使用不同映射;面向 STUN 的 srflx 映射未必适用于面向对端的流量,直连成功率低,常需 TURN 中继。
四、为什么必须双向发送
- NAT 通常只允许“从内到外主动建立”的会话返回数据通过,外部直打内网端口常被拒。
- 双向检查通过“双方同时发包”在各自 NAT 表内留下匹配条目,使得随后从对端来的返回流量满足 NAT 的允许规则。
五、失败与回退:TURN 中继
- 典型失败场景:企业网络阻断 UDP、对称 NAT、DPI/代理拦截。
- 回退路径:
- 优先 TURN/UDP(
transport=udp),保持实时性; - 若 UDP 全阻,则使用 TURN/TCP 或 TURN/TLS(
transport=tcp),牺牲时延但保证可达性。
- 优先 TURN/UDP(
六、与 KVS WebRTC C SDK 的对应
- srflx 生成:SDK通过 STUN 获取 srflx;STUN 地址由 SDK 根据 Region 本地构造并解析。
- 候选交换:通过 KVS 信令(WSS)交换
host/srflx/relay候选。 - 连通性检查:ICE Agent 自动执行 Binding Request/Response 检查,依据优先级选择最佳候选对并提名。
- 日志与工具:样例程序可看到 NAT 行为与候选选择;
samples/discoverNatBehavior.c可用于识别 NAT 类型与行为。
七、总结
- srflx 提供“外部可见的映射地址”,但能否打通取决于 ICE 的“双向连通性检查”。
- 圆锥型 NAT 成功率高;对称 NAT 下常需 TURN 中继。ICE 会自动选择“可达且代价最优”的路径。
