1 问题背景
多媒体会话信令协议是在准备建立媒体流传输的代理之间交换信息的协议,例如
sip
、
rtsp
、
h.323
等。媒体流与信令流截然不同,它们所采用的网络通道也不一致。由于协议自身设计上的原因,使得媒体流无法直接穿透网络地址转换
/
防火墙
(nat/fw)
。因为它们生存期的目标只是为了建立一个在信息中携带
ip
地址的分组流,这在遇到
nat/fw
时会带来许多问题。而且这些协议的目标是通过建立
p2p(peer to peer)
媒体流以减小时延,而协议本身很多方面却与
nat
存在兼容性问题,这也是穿透
nat/fw
的困难所在。
而
nat
仍是解决当前公用
ip
地址紧缺和网络安全问题的最有力手段,它主要有四种类型:完全圆锥型
nat(full cone nat)
,地址限制圆锥型
nat (address restricted cone nat)
,端口限制圆锥型
nat (port restricted cone nat)
,对称型
nat (symmetric nat)
。前三种
nat
,映射与目的地址无关,只要源地址相同,映射就相同,而对称型
nat
的映射则同时关联源地址和目的地址,所以穿透问题最为复杂。
不少方案已经被应用于解决穿透
nat
问题,例如:
algs(application layer gateways)
、
middlebox control protocol
、
stun (simple traversal of udp through nat)
、
turn(traversal using relay nat)
、
rsip(realm specific ip)
、
symmetric rtp
等。然而,当这些技术应用于不同的网络拓扑时都有着显著的利弊,以至于我们只能根据不同的接入方式来应用不同的方案,所以未能很好地解决
all-nat
与
efficiency
的问题,同时还会给系统引入了许多复杂性和脆弱性因素。所以我们目前需要一种综合的足够灵活的方法,使之能在各种情况下对
nat/fw
的信令穿透问题提供最优解。事实上,
ice
正是符合这样要求的一种良好的解决方案。
2 ice技术
2.1 ice简介
交互式连通建立方式
ice(interactive connectivity establishment)
并非一种新的协议,它不需要对
stun
、
turn
或
rsip
进行扩展就可适用于各种
nat
。
ice
是通过综合运用上面某几种协议,使之在最适合的情况下工作,以弥补单独使用其中任何一种所带来的固有缺陷。对于
sip
来说,
ice
只需要定义一些
sdp(session description protocol)
附加属性即可,对于别的多媒体信令协议也需要制定一些相应的机制来实现。本文仅就
sip
2.2 多媒体信令
媒体流穿透
nat
的过程是独立于某种具体的信令协议的。通信发生在两个客户端-会话发起者和会话响应者。初始化信息
(initiate message)
包含了描述会话发起者媒体流的配置与特征,并经过信令调停者
(
也叫信令中继
)
,最后到达会话响应者。假设会话响应者同意通信,接受信息
(accept message)
将产生并反馈至会话初始者,媒体流建立成功。此外,信令协议还对媒体流参数修改以及会话终止消息等提供支持。对于
sip
,会话发起者即
uac(user agent client)
,会话响应者即
uas(user agent server)
,初始化消息对应
sdp
请求里面的
invite
,接受消息对应于
sdp
应答里面的
200 ok
,终止消息对应于
bye
。
2.3 算法流程
2.3.1 收集传输地址
会话发起者需要收集的对象包括本地传输地址
(local transport address)
和来源传输地址
(derived transport address)
。本地传输地址通常由主机上一个物理
(
或虚拟
)
接口绑定一个端口而获得。会话发起者还将访问提供
unsaf(unilateral self-address fixing)
的服务器,例如
stun
、
turn
或
teredo
。对于每一个本地传输地址,会话者都可以从服务器上获得一组来源传输地址。
显然,实现物理或虚拟连通方式越多,
ice
将工作得越好。但为了建立对等通信,
ice
通常要求至少有一个来源地址由位于公网上的中继服务器
(
如
turn)
所提供的,而且需要知道具体是哪一个来源传输地址。
2.3.2 启动stun
会话发起者获得一组传输地址后,将在本地传输地址启动
stun
服务器,这意味着发送到来源地址的
stun
服务将是可达的。与传统的
stun
不同,客户端不需要在任何其它
ip
或端口上提供
stun
服务,也不必支持
tls
,
ice
用户名和密码已经通过信令协议进行交换。
客户端将在每个本地传输地址上同时接受
stun
请求包和媒体包,所以发起者需要消除
stun
消息与媒体流协议之间的歧义。在
rtp
和
rtcp
中实现这个并不难,因为
rtp
与
rtcp
包总是以
0b10(v=2)
打头,而
stun
是
0b00
。对于每个运行
stun
服务器的本地传输地址,客户端都必须选择相应的用户名和密码。用户名要求必须是全局唯一的,用户名和密码将被包含在初始化消息里传至响应者,由响应者对
stun
请求进行鉴别。
2.3.3 确定传输地址的优先级
stun
服务器启动后,下一步就是确定传输地址的优先级。优先级反映了
ua
在该地址上接收媒体流的优先级别,取值范围在
0
到
1
之间,通常优先级按照被传输媒体流量来确定。流量小者优先,而且对于相同流量者的
ipv6
地址比
ipv4
地址具有更高优先级。因此物理接口产生的本地
ipv6
传输地址具有最高的优先级,然后是本地
ipv4
传输地址,然后是
stun
、
rsip
、
teredo
来源地址,最后是通过
vpn
接口获得的本地传输地址。
2.3.4 构建初始化信息(initiate message)
初始化消息由一系列媒体流组成,每个媒体流都有一个缺省地址和候选地址列表。缺省地址通常被
initiate
消息映射到
sip
信令消息传递地址上,而候选地址列表用于提供一些额外的地址。对于每个媒体流来说,任意
peer
之间实现最大连通可能性的传输地址是由公网上转发服务器
(
如
turn)
提供的地址,通常这也是优先级最低的传输地址。客户端将可用的传输地址编成一个候选地址列表
(
包括一个缺省地址
)
,并且为每个候选元素分配一个会话中唯一的标识符。该标识符以及上述的优先级都被编码在候选元素的
id
属性中。一旦初始化信息生成后即可被发送。
.3.5 响应处理:连通性检查和地址收集
会话应答方接收到初始化信息
initiate message
后,会同时做几个事情:首先,执行
2.3.1
中描述的地址收集过程。这些地址可以在呼叫到达前预收集,这样可以避免增加呼叫建立的时间。当获得来源地址以后,应答方会发送
stun bind
请求,该请求要求必须包含
username
属性和
password
属性,属性值为从
“alt”
中得到的用户名和密码。
stun bind
请求还应包括一个
message-integrity
属性,它是由
initiate message
中候选元素的用户名和密码计算得来的。此外,
stun bind
请求不应有
change-request
或
response-address
属性。
当一个客户端收到
initiate message
时,它将通过其中缺省地址和端口发送媒体流。如果
stun bind
请求消息引起错误应答,则需要检查错误代码。如果是
401
,
430
,
432
或
500
,说明客户端应该重新发送请求。如果错误代码是
400
,
431
和
600
,那么客户端不必重试,直接按超时处理即可。
2.3.6 生成接受信息(accept message)
应答者可以决定是接受或拒绝该通信,若拒绝则
ice
过程终止,若接受则发送
accept
消息。
accept
消息的构造过程与
initiate message
类似。
2.3.7 接受信息处理
接受过程有两种可能。如果
initiate message
的接受者不支持
ice
,则
accept message
将只包含缺省的地址信息,这样发起方就知道它不用执行连通性检查了。然而如果本地配置信息要求发起者通过
turn
服务器发包来进行连通性检查,这将意味着那些直接发给响应者的包会被对方防火墙丢弃。为解决这个问题,发起者需要重新分配一个
turn
来源地址,然后使用
send
命令。一旦
send
命令被接受,发起者将发送所有的媒体包到
turn
服务器,由服务器转发至响应者。如果
accept message
包含候选项,则发起方处理
accept message
的过程就与响应方处理
initiate message
很相似了。
.3.8 附加ice过程
initiate
或
accept
消息交换过程结束后,双方可能仍将继续收集传输地址,这通常是由于某些
stun
事务过长而未结束引起,另一种可能是由于
initiate/accept
消息交换时提供了新的地址。
2.3.9 ice到sip的映射
使用
ice
方式穿透
nat
,必须映射
ice
定义的参数到
sip
消息格式中,同时对其
sdp
属性进行简单扩展
—
在
sdp
的
media
块中定义一个新的属性“
alt
”来支持
ice
。它包含一个候选
ip
地址和端口,
sdp
的接受端可以用该地址来替换
m
和
c
中的地址。
media
块中可能会有多个
alt
属性,这时每个
alt
应该包括不重复的
ip
地址和端口。语法属性如下:
alt-attribute = "alt" ":" id sp qvalue sp derived-from sp
username sp password sp
unicast-address sp port [unicast-address sp port]
;qvalue from rfc 3261
;unicast-address, port from rfc 2327
username = non-ws-string
password = non-ws-string
id = token
derived-from = ":" / id
3 实例设计
3.1 symmetric nat/fw
下面设计一个简化的基于
ice
的对称式网络地址转换
/
防火墙
(symmetric nat/fw)
的穿透实例,进一步说明
ice
的工作流程。
假设通信双方同时处于对称式nat/fw内部,现在sip终端a要与b进行voip通信。a所在的内部地址是10.0.1.9,外部地址是211.35.29.30;b的内部地址是192.168.1.6,外部地址是202.205.80.130;stun/turn服务器的地址是218.65.228.110。
首先a发起请求,进行地址收集,如图所示。生成a的initiate message如下:
v=0
o=dodo 2890844730 2890844731 in ip4 host.example.com
s=
c=in ip4 218.65.228.110
t=0 0
m=audio 8076 rtp/avp 0
a=alt:1 1.0 : user 9kksj== 10.0.1.9 1010
a=alt:2 0.8 : user1 9kksk== 211.35.29.30 9988
a=alt:3 0.4 : user2 9kksl== 218.65.228.110 8076
其中本地地址的优先级为1.0,stun地址的优先级为0.8,turn地址优先级为0.4。
当
b
收到消息后,也进行地址收集,过程和
a
类似。然后
b
开始执行连通性检查,可是我们不难发现,到
10.0.1.9:1010
的
stun
请求和到
211.35.29.30:9988
的
stun
请求都将不可避免地失败。因为前者是一个不可路由的保留地址;而后者由于
symmetric nat
会对于每一个
stun/turn
请求都将分配不同的
binding
,当数据包抵达
a
的
nat
时,
nat
会发现传输地址
211.35.29.30:9988
已经映射
218.65.228.110:3478
了。而此时
stun
请求的源地址并非
218.65.228.110:3478
,所以数据包必然会被
a
的
nat/fw
所丢弃。然而,到
218.65.228.110:8076
的
stun
请求却是成功的,因为
turn
服务器用它收集到的原始地址来发送
turn
请求。
图2 :a的地址收集过程时序图 图3 :b的地址收集过程时序图
图4 :b的连通性检查
完成连通性检查后,b产生的应答消息如下:
v=0
o= vincent 2890844730 289084871 in ip4 host2.example.com
s=
c=in ip4 218.65.228.110
t=0 0
m=audio 8078 rtp/avp 0
a=alt:4 1.0 : peer as88jl 192.168.1.6 23766
a=alt:5 0.8 : peer1 as88kl 202.205.80.130 10892
a=alt:6 0.4 : peer2 as88ll 218.65.228.110 8078
a=alt:7 0.4 3 peer3 as88ml 218.65.228.110 5556
当a收到应答后,它也执行连通性检查,如图所示:
图5: a的连通性检查
和前面一样,对于b的私有地址和stun来源地址的连通性检查结果均为失败,而到b的turn来源地址和到b的peer-derived地址成功(本例中它们都具有相同的优先级0.4)。相同优先级下我们通常采用peer-derived地址,所以a发送到b的媒体流将使用218.65.228.110:5556地址,而b到a的媒体流将发送至218.65.228.110:8076地址。以上
为基于
ice
方式
解决symmetric nat/fw穿透问题的一个简化后的典型实例。
3.2 其它类型nat/fw
基于
ice
实现其它类型的
nat/fw
穿透问题,其过程比
symmetric nat
还要简单,见参考文献
[1] [2] [6]
。
4 结束语
ice
方式的优势是显而易见的,它消除了现有的
unsaf
机制的许多脆弱性。例如传统的
stun
有几个脆弱点,其中一个就是发现过程需要客户端自己去判断所在
nat
类型,这实际上不是一个可取的做法。而应用
ice
之后,这个发现过程已经不需要了。另一点脆弱性在于
stun
、
turn
等机制都完全依赖于一个附加的服务器,而
ice
利用服务器分配单边地址的同时,还允许客户端直接相连,因此即使
stun
或
trun
服务器中有任何一个失败了,
ice
方式仍可让呼叫过程继续下去。此外,传统的
stun
最大的缺陷在于它不能保证在所有网络拓扑结构中都正常工作,最典型的问题就是
symmetric nat
。对于
turn
或类似转发方式工作的协议来说,由于服务器的负担过重,很容易出现丢包或者延迟情况。而
ice
方式正好提供了一种负载均衡的解决方案,它将转发服务作为优先级最低的服务,从而在最大程度上保证了服务的可靠性和灵活性。此外,
ice
的优势还在于对
ipv6
的支持,目前
cisco
等公司正在设计基于
ice
方式的
nat/fw
解决方案。由于广泛的适应能力以及对未来网络的支持,
ice
作为一种综合的解决方案将有着非常广阔的应用前景。