ICE是使用STUN/TURN工具性质的最主要协议之一,其中TURN一开始也被设计为ICE协议的一部分,本文只是对这几种协议作概述性的说明
”
ICE的全称为Interactive Connec-tivi ty Establishment,即交互式连接建立.初学者可能会将其与网络编程的ICE 弄混,其实那是不一样的东西,在网络编程中,如C++的ICE库,都是指Inter-nate Communications Engine, 是一种用于分布式程序设计的网络通信中间件.我们这里说的只是交互式连接建立.
01
ICE简介
ICE是一个用于在offer/answ-er模式下的NAT传输协议,主要用于UDP下多媒体会话的建立,其使用了STUN协议以及TURN 协议,同时也能被其他实现了offer/answer模型的的其他程序所使用,比如SIP(Se-ssi on Initiation Protocol).
使用offer/answer模型(RFC3264)的协议通常很难在NAT之间穿透,因为其目的一般是建立多媒体数据流,而且在报文中还 携带了数据的源IP和端口信息,这在通过NAT时是有问题的.RFC3264还尝试在客户端之间建立直接的通路,因此中间就缺少 了应用层的封装.这样设计是为了减少媒体数据延迟,减少丢包率以及减少程序部署的负担.然而这一切都很难通过NAT而完成. 有很多解决方案可以使得这些协议运行于NAT环境之中,包括应用层网关(ALGs),Cla ssic STUN以及Realm Specific IP+SDP 协同工作等方法.不幸的是,这些技术都是在某些网络拓扑下工作很好,而在另一些环境下表现又很差,因此我们需要一个单一的, 可自由定制的解决方案,以便能在所有环境中都能较好工作.
01
ICE工作流程
一个典型的ICE工作环境如下,有两个端点L和R,都运行在各自的NAT之后(他们自己也许并不知道),NAT的类型和性质也是未知的. L和R通过交换SDP信息在彼此之间建立多媒体会话,通常交换通过一个SIP服务器完成:
ICE的基本思路是,每个终端都有一系列传输地址(包括传输协议,IP地址和端口)的候选,可以用来和其他端点进行通信. 其中可能包括:
直接和网络接口联系的传输地址(host address)
经过NAT转换的传输地址,即反射地址(server reflective address)
TURN服务器分配的中继地址(relay address)
虽然潜在要求任意一个L的候选地址都能用来和R的候选地址进行通信.但是实际中发现有许多组合是无法工作的.举例来说, 如果L和R都在NAT之后而且不处于同一内网,他们的直接地址就无法进行通信.ICE的目的就是为了发现哪一对候选地址的 组合可以工作,并且通过系统的方法对所有组合进行测试(用一种精心挑选的顺序).
为了执行ICE,客户端必须要识别出其所有的地址候选,ICE中定义了三种候选类型,有些是从物理地址或者逻辑网络接口继承 而来,其他则是从STUN或者TURN服务器发现的.很自然,一个可用的地址为和本地网络接口直接联系的地址,通常是内网地址, 称为HOST CANDIDATE,如果客户端有多个网络接口,比如既连接了WiFi又插着网线,那么就可能有多个内网地址候选.
其次,客户端通过STUN或者TURN来获得更多的候选传输地址,即SERV-ER REFLEXIVE CANDIDATES和R-ELAYED CANDIDATES, 如果TURN服务器是标准化的,那么两种地址都可以通过TURN服务器获得.当L获得所有的自己的候选地址之后,会将其 按优先级排序,然后通过signaling通道发送到R.候选地址被存储在SDP offer报文的属性部分.当R接收到offer之后, 就会进行同样的获选地址收集过程,并返回给L.
这一步骤之后,两个对等端都拥有了若干自己和对方的候选地址,并将其配对,组成CANDIDATE PAIRS.为了查看哪对组合 可以工作,每个终端都进行一系列的检查.每个检查都是一次STUN request/response传输,将request从候选地址对的本地 地址发送到远端地址. 连接性检查的基本原则很简单:
以一定的优先级将候选地址对进行排序.
以该优先级顺序发送checks请求
从其他终端接收到checks的确认信息
两端连接性测试,结果是一个4次握手过程:
值的一提的是,STUN request的发送和接收地址都是接下来进多媒体传输(如RTP和RTCP)的地址和端口,所以, 客户端实际上是将STUN协议与RTP/RTCP协议在数据包中进行复用(而不是在端口上复用).
由于STUN Binding request用来进行连接性测试,因此STUN Binding respons e中会包含终端的实际地址, 如果这个地址和之前学习的所有地址都不匹配,发送方就会生成一个新的candidate,称为PEER RE FLEXIVE CANDIDATE, 和其他candida te一样,也要通过ICE的检查测试.
01
连接性检查
所有的ICE实现都要求与STUN(R-FC5 389)兼容,并且废弃Classic STU-N(RFC3 489).ICE的完整实现既生成checks(作为STUN client), 也接收checks(作为STUN server),而lite实现则只负责接收checks.这里只介绍完整实现情况下的检查过程.
1. 为中继候选地址生成许可(Permissions).
2. 从本地候选往远端候选发送Binding Request.
在Binding请求中通常需要包含一些特殊的属性,以在ICE进行连接性检查的时候提供必要信息:
PRIORITY 和 USE-CANDIDATE
终端必须在其request中包含PRIORITY属性,指明其优先级,优先级由公式计算而得. 如果有需要也可以给出特别指定的候选(即USE-CANDIDATE属性).
ICE-CONTROLLED和ICE-CONTROLLING
在每次会话中,每个终端都有一个身份,有两种身份,即受控方(con-trolled role)和主控方(control-ling role). 主控方负责选择最终用来通讯的候选地址对,受控方被告知哪个候选地址对用来进行哪次媒体流传输, 并且不生成更新过的offer来提示此次告知.发起ICE处理进程(即生成offer)的一方必须是主控方,而另一方则是受控方. 如果终端是受控方,那么在request中就必须加上ICE-CONTROLL-ED属性,同样,如果终端是主控方,就需要ICE-CONTROLLING属性.
生成Credential
作为连接性检查的Binding Request必须使用STUN的短期身份验证.验证的用户名被格式化为一系列username段 的联结,包含了发送请求的所有对等端的用户名,以冒号隔开;密码就是对等端的密码.
3. 处理Response.
当收到Binding Response时,终端会将其与Binding Request相联系,通常通过事务ID.随后将会将此事务ID与 候选地址对进行绑定。
失败响应
如果STUN传输返回487(Role Conflict)错误响应,终端首先会检查其是否包含了ICE-CONTROLLED或ICE-CONTROLLING 属性.如果有ICE-CONTROLLED,终端必须切换为controlling role;如果请求包含ICE-CONTROLLING属性, 则必须切换为controlled role.切换好之后,终端必须使产生487错误的候选地址对进入检查队列中, 并将此地址对的状态设置为Waiting.
成功响应,一次连接检查在满足下列所有情况时候就被认为成功:
STUN传输产生一个Success Response
response的源IP和端口等于Binding Request的目的IP和端口
response的目的IP和端口等于Binding Request的源IP和端口
终端收到成功响应之后,先检查其map ped address是否与本地记录的地址对有匹配,如果没有则生成一个新的候选地址. 即对等端的反射地址.如果有匹配,则终端会构造一个可用候选地址对(valid pair).通常很可能地址对不存在于任何 检查列表中,检索检查列表中没有被服务器反射的本地地址,这些地址把它们的本地候选转换成服务器反射地址的基地址, 并把冗余的地址去除掉.
本文中具体工作过程和详细的属性描述都未包含,如果需要根据协议来实现具体的应用程序,还需要对RFC的文档进行仔细阅读
网友评论