附录A. 与常规ICE的交互 (Interaction with Regular ICE)
ICE协议设计得足够灵活,可以在尽可能多的网络环境中工作并适应这些环境。尽管具有这种灵活性,但 [RFC8445] 中指定的ICE本身并不支持Trickle ICE。本节描述了候选地址逐步传递如何与ICE交互。
[RFC8445] 描述了在ICE代理处于运行状态 (Running state) 时更新检查列表和定时器状态所需的条件。这些条件在事务完成时进行验证,其中一个条件规定:
如果与检查列表关联的数据流的每个组件在有效列表 (valid list) 中都没有有效的候选地址对,则检查列表的状态设置为失败 (Failed)。
这可能是一个问题,并在许多情况下导致ICE处理过早失败。考虑以下情况:
- Alice和Bob都位于具有网络地址转换 (Network Address Translation, NAT) 的不同网络中。Alice和Bob本身具有不同的地址,但两个网络都使用相同的专用互联网块 (例如,[RFC1918] 中指定的"20位块"172.16/12)。
- Alice向Bob传递候选地址172.16.0.1,这也恰好对应于Bob网络上的现有主机。
- Bob从其主机候选地址和172.16.0.1创建候选地址对,将这一个候选地址对放入检查列表,并开始检查。
- 这些检查到达Bob网络中172.16.0.1的主机,该主机使用ICMP"端口不可达"错误响应; 根据 [RFC8445],Bob将事务标记为失败 (Failed)。
此时,检查列表仅包含一个失败的候选地址对,并且有效列表为空。这会导致数据流以及可能所有ICE处理失败,即使Trickle ICE代理随后可以传递可以成功的候选地址。
如果来自Alice的初始ICE描述仅包含可以从Bob收集的任何候选地址确定为无法到达的候选地址,也会出现类似的竞争条件 (例如,如果Bob的候选地址仅包含IPv4地址,并且他从Alice收到的第一个候选地址是IPv6地址,则会出现这种情况)。
当非Trickle ICE实现发起与Trickle ICE实现的交互时,可能会出现另一个潜在问题。考虑以下情况:
- Alice的客户端具有非Trickle ICE实现。
- Bob的客户端支持Trickle ICE。
- Alice和Bob都在具有地址相关过滤 [RFC4787] 的NAT后面。
- Bob有两个STUN服务器,但其中一个当前无法到达。
在Bob的代理收到Alice的初始ICE描述后,它将立即开始连接性检查。它还将开始收集候选地址,这将花费很长时间,因为无法到达的STUN服务器。当Bob的应答准备好并传递给Alice时,Bob的连接性检查可能已经失败: 在Alice收到Bob的应答之前,她将无法开始连接性检查并在她的NAT中打孔。因此,NAT将过滤Bob的检查,因为它们来自未知端点。