| 使用ICE技术穿越NAT/FW的设计和实现 |
当使用诸如SIP、H.323协议等构建VoIP系统时,由于协议设计上的原因,带来了NAT/FW穿越问题。目前解决NAT/FW穿越的方法有很多,例如:STUN(Simple Traversal of UDP through NAT)、TURN(Traversal Using Relay NAT)、RSIP(Realm Specific IP)和symmetric RTP等,但是这些方法都有其局限性,每种方法只适用特定的网络环境。为此,ICE作为一种综合方法被提出来,它集成了已有的一些协议,在一个统一的框架下采用动态和交互方式在会话的双方间建立连通的传输路径,并且在有多条传输路径可选择时,可按照用户指定的优先级选择传输路径。本文详细介绍了ICE在VoIP终端中的实现,设计了一种较好的结构。采用这种设计实现ICE功能的VoIP终端能够适应各种NAT环境,能够动态选择媒体流传输路径,在一定情况下可降低媒体流传输时延,从而提高媒体播放质量。
1 NAT/FW问题的产生和客户端的解决方法 1.1 问题的产生多媒体会话信令协议是在准备建立媒体流传输的代理之间交换信息的协议,例如SIP、RTSP、H.323等。媒体流与信令流截然不同,它们所采用的网络通道也不一致。由于一些协议中使用地址作为媒体流的接收和发送地址,会话中处于NAT/FW内部的一些参与者,可能会使用不可直接路由的地址作为媒体流接收地址进行交换,使得媒体流无法直接穿透网络地址转换/防火墙(NAT/FW)。
NAT本身的多样性使NAT问题更加复杂。不同的NAT设备在关闭不活动连接的时间上有很大不同,NAT设备处理端口映射的方式与NAT外主机通信方式也不同。按照这两种方式可以分为Full Cone NAT、Restricted Cone NAT、Port Restricted Cone NAT和Symmetric NAT[1]。以上这些因素都增加了解决NAT/FW穿越的复杂性。
1.2 客户端的常用解决方法和限制目前已有很多NAT穿越方法,其中包括IETF的标准和草案以及一些厂商的私有协议,如STUN、TURN等。但是这些方法都有其局限性,即它们只能适应特定的网络环境。
STUN是一个轻量级的协议,允许多媒体会话的参与者探测它是否处于NAT、防火墙之后以及它们的类型,并且具备探测NAT所分配的公网地址和端口的能力。但是,STUN只能工作在全通NAT、地址限制NAT以及端口限制NAT的网络环境下,在对称性NAT的情况下,STUN请求得到的映射地址是无效的。通常只在全通NAT和地址限制NAT的情况下才使用STUN。
TURN协议在语法和操作上均与STUN相似,处在公网的TURN服务器为客户端提供本身的一个外部IP地址和端口,并且负责中转通信双方的媒体流。TURN协议可以工作在所有类型的NAT下,但是TURN的缺陷在于它需要中转通信双方的媒体流,这可能会增加媒体数据包的延迟和丢包的可能性。同时,完全使用TURN方式需要大量的TURN服务器,在有大量用户时,TURN服务器会成为系统瓶颈[2]。
2 使用ICE穿越NAT和防火墙 2.1 ICE的特点ICE(Interactive Connectivity Establishment)并不是一种新的协议,它利用STUN、TURN等任何符合UNSAF的协议来提供一个通用的解决方案。ICE的特点包括:
1) ICE是一种客户端技术,无需改变VoIP系统中的其他网络元素;
2) ICE可以保持客户端的向后兼容,即实现ICE的客户端依然可以和不支持ICE的客户端建立多媒体会话;
3) 具有最大的互操作性,不对网络拓扑进行任何假设,可以适应各种网络环境;
4) 通过交互方式建立端到端连接,可以按照用户指定的优先顺序选用用户最期望使用的传输路径。
2.2 ICE的原理正如ICE的名称一样(交互式连通性建立),ICE采用交互的方法来使会话双方穿越NAT。ICE的方法是考虑到以下情况而提出的:
1) 要建立会话的双方无法完全了解整个网络环境(拓扑结构等);
2) 虽然出现了STUN、TURN等NAT穿越的方法,但是各种方法都有其局限性,在仅使用其中一种时无法保证在各种网络环境下均能正常工作;
3) 正是由于上述两个原因,需要将各种方法综合起来,并形成一种新的NAT穿越技术,它可以适应各种网络环境,并尽可能不改变现有的会话建立过程和网络中的各个节点。
现以SIP协议建立的VoIP系统为例,以一个会话的建立过程为基础,分析ICE的原理。采用ICE方法建立会话的连通性过程如图 1所示。
![]() |
| 图 1 采用ICE方法的会话建立过程 |
过程中的各步骤详细描述如下:
1) 地址收集
在ICE中传输地址分为很多类,首先介绍以下这些地址种类。
① 传输地址:IP地址和端口的组合;
② 本地传输地址:由主机的操作系统分配的传输地址,通常通过绑定NIC获得;
③ 可用本地传输地址:用于公布给远端会话参与者的本地传输地址;
④ 关联本地传输地址:仅仅用于得到派生传输地址的本地传输地址,它们不公布给远端会话参与者;
⑤ 派生传输地址:在关联本地传输地址上,通过UNSAF类协议如STUN、TURN获得的传输地址,用于公布给远端会话参与者;
⑥ 公布传输地址:包括可用本地传输地址和派生传输地址,用于公布给远端会话参与者;
⑦ 对端派生传输地址:通过运行在远端会话参与者系统上的STUN服务器得到的传输地址;
⑧ TURN派生传输地址:通过TURN服务得到的地址;
⑨ STUN派生传输地址:通过STUN服务得到的地址,但不包括对端派生传输地址;
⑩ 单向地址分配:通过查询提供UNSAF服务的网络服务器得到地址;
⑪ 双向地址分配:地址分配是通过查询运行在会话对端上的UNSAF服务而得到,对端派生传输地址就是通过双向地址分配得到的。
在地址收集阶段,会话发起者收集其所有可用的地址和端口,这些地址和端口都是潜在的媒体接收地址。发起者可以使用任何可提供给它地址和端口号的方法或协议,包括绑定本地地址、通过STUN或TURN服务得到的地址等等,甚至可以包括VPN地址、IPv4和IPv6双协议栈地址[3]。
地址收集后要指定每个公布传输地址的优先级,用于表示在多个传输地址可以传输媒体流时路径的选择顺序。ICE中没有规定哪种类型的地址应该具有更高的优先级,这通常是由应用指定的。
然后会话发起者在每个本地传输地址上运行STUN服务器,并在这些地址上等待接收STUN消息和媒体包。
2) 发送会话发起消息
会话发起者一旦完成地址收集后,就可以发送会话初始消息给远端会话参与者,在SIP中,这通常是一个Invite消息,并且会在消息体内携带可用于媒体传输的地址。会话的媒体描述信息的构建方法如下:会话发起者将公布传输地址编码等一系列的候选元素,每个候选元素可以携带2个STUN用户名和密码、2个地址、该候选元素的ID号以及它的优先级,作为RTP和RTCP的传输地址[4]。
3) 地址收集
会话应答者收到要求建立会话的消息后,会有两种可能:第一,此UA不支持ICE,按照RFC3264,它会忽略所有的ICE信息,而以下列出的步骤不会执行,UA按照通常的方式进行会话协商;第二,此UA支持ICE,则进行下面所述的步骤。我们仅探讨上述第二种情况。该UA在得到对方的地址信息后,立即进行地址收集工作,所做工作与(1)中相同,不再赘述。
4) 发送会话应答消息
会话应答者完成地址收集后,创建回复消息,并回复会话发起者。在SIP中,这通常是一个200消息,并且在消息体内携带所有可用地址信息。回复SDP即Answer消息的创建与(2)中相同。
5) STUN检测
在会话应答者发送接收会话的应答后,它对会话发起者公布传输地址并发送STUN绑定请求。与标准的STUN绑定请求不同的是,在ICE的STUN绑定请求中,禁止包含CHANGE-REQUEST或者RESPONSE-ADDRESS选项,此时的绑定请求只是起连通性检测的作用。
6) STUN检测
会话发起者收到应答消息后,根据消息体中携带的地址信息进行与(5)中相同的STUN检测。
7) 媒体数据发送
经过STUN检测后,一旦发现对方可以连通,即可向对方地址发送媒体数据。如果有多个地址可以连通,则根据各地址的优先级向高优先级的地址发送媒体数据。如果在媒体的发送过程中,有新的更高优先级的地址连通检测成功,则媒体流切换到这个新的地址。ICE正是通过这种动态机制来保证媒体流使用用户指定的最优路径传输[5]。
8) 媒体数据发送
与上述(7)过程相同。
2SIPUA的ICE设计与实现
在原有的SIPUA的基础上增加ICE的功能,将ICE功能进行划分,无需对原有系统进行大的调整,即可实现ICE功能。
1) 地址收集
地址收集负责地址的收集工作,并保存所有的地址列表和地址间的对应关系。UA可以在启动时进行地址收集工作,每一个本地传输地址对应一个Address类的实例。一旦完成地址收集后,以后的通话就可以直接使用,这样可以减少会话的建立时间。
2) Address
Address是一个纯虚类,从Address继承的UdpAddress和TcpAddress分别对应UDP传输地址和TCP传输地址。每个Address的子类的实例对应一个本地的传输地址,并维持这个传输地址的所有信息,包括地址类型、与本地传输地址对应的产生地址、网络包的处理者列表等。并且对于由STUN协议得到的派生传输地址,地址还要负责保持激活。因此我们在设计时,每个这样的对象也作为一个执行体,即对应一个线程。当收到网络上到来的数据包后,首先判断包的类型,然后将此数据包投递给订阅该类包的消息处理者,由消息的处理者处理数据。
3) MsgHandler
MsgHandler是一个虚类,它是所有网络数据包处理类的父类。每个要处理特定类型数据包的类继承这个类,并实现ProcessMsg方法以处理网络上的数据包。例如,对接收到的STUN查询消息,则由ICEMHSTUNServ进行处理,该类的实例按照STUN协议处理STUN消息,而对于RTP数据,则由ICEMHRtp处理,该类实例接收RTP包后,可以进行播放等操作[6]。
在我们的设计和实现中,充分考虑了ICE的特点。首先Address作为虚类来实现,可以保证在多协议和多IP栈的情况下,使用统一的架构来实现ICE功能,并且便于扩展添加新的地址。其次,考虑到在每个传输地址上可能有多种类型的数据包到达,因此设计了MsgHandler作为网络消息处理类的基类,所有MsgHandler的子类都可以通过Address的RegisterMsgHandler方法来注册自己,并指定要处理的消息类型。当有数据包到达时,Address将分析数据包的类型,然后投递给对该类型数据包感兴趣的消息处理对象。再次,为了减少每次呼叫时的准备时间,提前准备好了ICE中的所有地址,并且对UASAF类协议使用了保持激活机制来保证其中的派生传输地址随时可用。
3 结论在讨论了VoIP终端的NAT和防火墙穿越问题后,着重讨论了ICE方式的穿越,剖析了ICE的原理,并给出了一种实现方式。使用ICE方式穿越NAT和防火墙的优势是消除了现有UNSAF机制的许多脆弱性,最大程度上保证了服务的可靠性和灵活性。经测试,这种结构在各种NAT环境下工作良好,对端口限制NAT或会话双方位于同一NAT后等使用STUN无法穿越的网络环境,ICE工作良好,可以实现会话双方的媒体流的端到端传输,最大限度地减少了媒体流中继,进而提高了VoIP系统的扩展性,在某些情况下也可以降低传输时延,提高媒体播放质量。
| [1] |
郭薇.基于P2P-SIP的VoIP系统的研究与设计[D].北京: 北京邮电大学, 2007. http://www.wanfangdata.com.cn/details/detail.do?_type=degree&id=Y1158332
|
| [2] |
王峰, 邵家玉. 基于SIP多媒体业务穿越NAT和防火墙的方案设计[J]. 哈尔滨商业大学学报(自然科学版), 2006(6): 79. |
| [3] |
饶翔, 张顺颐. 基于软交换的下一代网络体系结构[J]. 电信科学, 2001(8): 112. |
| [4] |
张健, 李恒文, 魏绍亮. SIP协议应用研究[J]. 现代电子技术, 2006(5): 45. DOI:10.3969/j.issn.1004-373X.2006.05.025 |
| [5] |
王盛邦. 计算机网络实验教程(第2版)[M]. 北京: 清华大学出版社, 2017.
|
| [6] |
吴许俊. 计算机网络综合实训[M]. 北京: 清华大学出版社, 2017.
|
2019, Vol. 33


