3.3 ICE 候选搜集与连通性检查 协商谈妥了合同,本节解决最后一个现实问题:线路从哪来。候选搜集把可达路径一条条找出来,连通性检查把它们成对试一遍并选出最优——这是整个建连流程里最依赖网络环境、也最考验排错功夫的环节。 三类候选:线路的三种来路 候选搜集按成本从低到高产出三类地址。本机候选来自网卡直接配置的地址,局域网内直连用它,出了局域网就是废纸。映射候选由引擎向探测服务器发一个询问包获得——服务器看到询问从哪个公网地址来,就原样告知,这个地址就是本机在出口设备上的映射。多数家用路由器的映射对固定目标稳定,对端直接往这个地址发包就能进来,这就是所谓打洞成功。中转候选则由中继服务器分配:本机先与中继建立通道,中继给出一个代理地址,任何发到这个地址的数据都会被转到本机。
协商谈妥了合同,本节解决最后一个现实问题:线路从哪来。候选搜集把可达路径一条条找出来,连通性检查把它们成对试一遍并选出最优——这是整个建连流程里最依赖网络环境、也最考验排错功夫的环节。
候选搜集按成本从低到高产出三类地址。本机候选来自网卡直接配置的地址,局域网内直连用它,出了局域网就是废纸。映射候选由引擎向探测服务器发一个询问包获得——服务器看到询问从哪个公网地址来,就原样告知,这个地址就是本机在出口设备上的映射。多数家用路由器的映射对固定目标稳定,对端直接往这个地址发包就能进来,这就是所谓打洞成功。中转候选则由中继服务器分配:本机先与中继建立通道,中继给出一个代理地址,任何发到这个地址的数据都会被转到本机。它最贵——流量全部绕行服务器——但最可靠,再刁钻的网络环境也几乎总能通。
| 候选类型 | 来路 | 成本 | 可达性 |
|---|---|---|---|
| 本机候选 | 网卡地址 | 零 | 仅限同网 |
| 映射候选 | 探测服务器告知 | 低 | 视出口设备类型 |
| 中转候选 | 中继服务器分配 | 高 | 几乎必通 |
搜集完成后,本端把全部候选连同优先级写进会话描述发给对端;对端同样办事。两边各自把己方候选与对方候选两两配对,剔除地址族与传输方式不匹配的组合后,进入检查阶段。

连通性检查复用了探测协议的请求应答报文,内容简单到只有一句"我在这,你能回我吗",但带着三样安全附件:短期凭证、消息完整性校验、随机的交易标识。凭证由协商阶段双方在会话描述里交换的线路用户名与密码派生而来,因此检查报文无法伪造——这也是第三章安全设计的一环。逐字节看一个检查请求的关键字段,对排错极有用:
报文类型 0x0001 绑定请求 交易标识 随机十六字节,应答原样带回 用户名属性 对端名冒号本端名,顺序不能反 完整性属性 用协商密码计算的消息摘要 优先级属性 本候选的优先级数值
检查由一方主导,称为控制方。控制方按优先级从高到低逐对发起探测,同时在收到对端探测时礼貌回以应答——双向的请求与应答共同构成确认。某对线路的探测往返成功后,控制方再发出带提名标志的确认包,宣告"就用这条",双方随即把媒体切上这条线路。两处细节值得记住:其一,检查是持续的,建连成功后周期性保活仍在进行,线路劣化时引擎可以重新提名另一对候选,业务几乎无感——这就是"连接断了又自己好了"的机制来源;其二,非控制方也会主动发探测,双方相向而行的探测在 NAT 场景下互相"打开"对方的映射,很多场景正是靠这种对发才打得通。
候选的优先级不是拍脑袋给的整数,而是一个组合运算:线路形态占大头(本机最高、映射居中、中转垫底),其次看地址族的现代性(新协议优先),最后才是同类内的序号。这样设计有一个明确的取向:在一切相等的前提下优先选择不经服务器的路径,把成本与延迟同时压到最低。理解这个取向,就能解释很多配置现象——比如明明配了中转、打洞也通,流量却始终不走中转:那是优先级机制在省钱,是特性不是故障。
保活纪律也常被低估。线路选定后,引擎按周期对在用线路发送保活探测,间隔落在服务端映射的老化窗口之内——一旦停发,出口设备的映射过期,线路会在无感知中悄悄失效。因此排查"通话一段时间后静默断开"类问题时,除了查网络波动,还要核对保活间隔与路径上各类设备的老化策略是否匹配。NAT 与防火墙的映射老化时间从数十秒到数分钟不等,引擎的缺省周期取的是保守值,自建中转时按实际环境调整即可。
穿越成功率取决于两端的出口设备组合,同一办公室里的设备可能分属不同网段、不同映射策略,甚至有的走了代理。遇到"同环境结果不一致",先逐台确认候选构成,再谈环境结论。
先确认是坏事吗——多数时候是好事:打洞成功,中转作为兜底未被启用。验证方法是对该会话禁用直连重测,若中转能接住,兜底链路就是健康的。
线路通与线路好是两回事。检查只验证可达性,不保证容量;断续说明带宽或抖动不达标,转到第七章的预算与调度体系去看。
背景。一次内训作业:给学员一份真实建连的抓包文件,要求还原候选构成与选线过程,并指出为什么最终选中的不是优先级最高的那对。
操作。先过滤出探测报文:按报文类型绑定请求与应答分列,统计请求的目标地址分布。看到三类目标——局域网地址、公网探测服务器、对端地址;对端地址里又分公网映射地址与中转地址。再看时间轴:搜集阶段先出现询问探测服务器的包,随后对端之间开始互发检查请求;前期大量请求无应答(对端还没拿到本端候选),候选互通后应答率迅速上升。最后找带提名标志的请求,锁定被选中的那对。
结果。还原出的结论:局域网候选对全部探测失败——两端不在同一网络;映射候选对中,高优先级的一对超时无应答,低优先级的一对在数百毫秒后通了;中转候选对也通了但未获提名。最终引擎提名了唯一走通的映射候选对。
解读。为什么高优先级对失败:那一对的出口映射方式随目标变化,探测的回包到不了对端,典型的对称映射环境。为什么选通了也不换:提名一旦完成且线路健康,引擎不会为了理论最优而频繁切换,稳定性优先于纸面优先级。学员最常见的误判是把"探测成功"当成"会被选用"——探测成功只是入场券,提名才是终审。
变式。若这份抓包里没有任何成功的探测,第一步永远是检查中转候选是否存在:双方都配了中转还全不通的概率极低,多半是服务端凭证或防火墙问题;双方都没配中转,则直接对照第 8.2 节的部署要求补齐。这个分流判断能在排错的第一分钟就定下方向。
本节要点:候选三类的成本与可达性构成互补,中转是兜底不是装饰;候选成对检查、按优先级排序、由控制方提名定线;检查报文带协商派生的凭证,防伪造;线路健康状态下引擎可无感切换;抓包排错先看候选构成,再看应答率,最后找提名包。至此第三章的建连主线走完,下一章起进入媒体内容本身,先从最娇贵的音频开始。