[转]ICE介绍 (RFC 5245)
[转]ICE介绍 (RFC 5245)
http://blog.csdn.net/dxpqxb/article/details/22040017
1关于ICE的10个事实
1 ICE使用STUN和TURN
2 ICE是一种P2P的NAT穿越方式
3 ICE只需要网络提供STUN或TURN服务器
4 ICE允许在很复杂的网路环境下传输媒体流
5 ICE只在确定媒体流可到达情况下才让电话进行振铃
6 ICE动态发现终端间媒体流的最短路径
7 ICE可以附带消除DoS攻击
8 ICE可以几乎和任意类型的NAT和防火墙设备一起工作
9 ICE不需要终端去发现NAT类型以及它们的存在
10 ICE只有在最坏的情况下才只用中继(两边都在对称NAT之后)
2 ICE的步骤
ICE 是一种探索、学习和更新式的解决方案。在ICE 算法的开始,通信的2 个代理并不知道自己的拓扑部署——在NAT 后还是不在NAT 后。
2.1 初始请求的发送
为了探索本地拓扑,代理 A 执行如下操作,收集 3 类候选地址(Candidates):
(1)A 从本地接口上获得主机候选地址(Host Candidates)192.168.1.22: 8484;
(2)发送STUN 绑定请求到STUN 服务器获得服务器反射候选地址(Server Reflexive Candidates)202.199.112.102: 61866;
(3)发送TURN 分配请求到TURN 服务器获得中继候选地址(Relay Candidates)202.199.112.105: 5006,同时也获得了服务器反射候选地址202.199.112.102: 62072。
这些候选地址是随后可能用于接收媒体流的地址。
计算候选的优先级。设置主机候选的类型优先参数为最高值126,服务器反射候选的类型优先参数为100,中继候选的类型优先参数为最低值0。本地参
数设为65 535,分组ID为1。经计算,主机候选的优先级为2 130 706 431,服务器反射候选的优先级为1 694 498
815,中继候选的优先级为16 777
215。按候选优先级高低排序。分配主机候选的基础(Foundation)属性为1,服务器反射候选的基础属性为2,中继候选的基础属性为3。
按中继候选、服务器反射候选、主机候选次序选择默认候选(该候选包含了默认用于接收媒体流的地址和端口),由于A 获得了中继候选,因此优先选择连通概率较大的中继候选202.199.112.105:5006 作为默认候选。
将默认候选的 IP 地址和端口编辑进SDP 的c 行和m 行,并添加收集到的3 个候选地址到a 属性,形成发送请求Offer,通过信令信道传给B,请求消息内容如下所示,修改的参数和添加的属性值用粗体显示。
v=0
o=UserA 2890844526 2890842807 IN IP4 192.168.1.22
s=
c=IN IP4 202.199.112.105
t=0 0
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=ice-ufrag:8hhY
m=audio 5006 RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 192.168.1.22 8484 typ host
a=candidate:2 1 UDP 1694498815 202.199.112.102 61866 typ
srflx raddr 192.168.1.22 rport 8484
a=candidate:3 1 UDP 16777215 202.199.112.105 5006 typ relay
raddr 202.199.112.102 rport 62072
2.2 应答的发送
当 B 收到请求,就知道了A 所处的拓扑环境(反射候选和主机候选地址不同,说明A 处于NAT 后)。B 执行和A
相同的操作,收集候选,计算候选优先级,设置基础(Foundation)属性,选择默认候选,进行SDP 编码,并发送应答消息Answer
给A。这样A 也知道B 所处的拓扑环境了,反射候选和主机候选地址不同,说明B 也处于NAT 后。应答消息内容如下所示:
v=0
o=UserB 2808849004 2808849004 IN IP4 172.16.10.102
s=
c=IN IP4 202.199.112.105
t=0 0
a=ice-pwd:YH75Fviy6338Vbrhrlp8Yh
a=ice-ufrag:9uB6
m=audio 49152 RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 172.16.10.102 8484 typ host
a=candidate:2 1 UDP 1694498815 202.199.112.87 63756 typ srflx
raddr 172.16.10.102 rport 8484
a=candidate:3 1 UDP 16777215 202.199.112.105 49152 typ relay
raddr 202.199.112.87 rport 63768
决定代理角色。由于A 和B 都是Full 型代理,且A 是请求的发起端,因此A 充当控制代理(Controlling Agent),B
为被控制代理(Controlled Agent)。A和B 开始对候选进行配对。A, B 各有3 个候选,A, B 各选1 个候选组成对,共有9
个对。由于不能从服务器反射选和中继候选发送请求,因此剪掉冗余对,A, B 每一方只剩下3
个对,即从主机候选分别到对端的主机候选、服务器反射候选、中继候选。
计算候选对的优先权并对候选对排序。对于控制代理A而言,按优先级排序候选对,形成检查列表所示。
对于被控制代理B,同样也计算候选对的优先级,并按优先级排序,形成自己的检查列表。
检查列表的次序决定了将来连通性检查的次序。设置检查列表中最高优先级对的状态为等待态,其余对为冻结态。
2.3 连通性检查
B 开始它的连通性检查。B
依次从检查列表移出最高优先级对,对的状态由等待态迁移为进行态(这同时会触发次高优先级对转换为最高优先级对,状态由冻结态变为等待态),开始连通性检
查。对第1 个对从本地候选172.16.10.102: 8484到远程候选192.168.1.22: 8484
发送STUN绑定请求([RFC5389]),由于远程候选处于NAT 后是私有的,不能被路由,检查失败。对第2
个对执行连通性检查,当数据包抵达NAT A 时,NAT 会发现传输地址202.199.112.102: 61866
已经映射202.199.112.108: 3478 了。而此时STUN请求的源地址并非202.199.112.108:
3478,所以数据包必然会被NAT A 丢弃。
对第 3 个对执行连通性检查。由于远程候选等于中继候选,为了有效利用带宽,应从本地候选172.16.10.102: 8484
向远程候选202.199.112.105: 5006 发送信道绑定请求[5]。请求中指出了信道号0x4001 及通信对端A
的地址,请求到达TURN 服务器,绑定成功。该绑定的成功,激励其学习对端反射候选202.199.112.102:
62072,经该反射候选到达对端A,然后产生了一个成功的响应,A 的检查终于成功。B 产生了一个新的对(202.199.112.105:
49152,202.199.112.105:
5006),该对被增加到有效列表,媒体流分组的ICE 处理迁移到完成态。至此B 可以利用信道0x4001发送媒体流分组到A 了。
当 A 收到应答后,也按照候选对的优先级次序开始自己的连通性检查。和B 类似,也失败了。当A 一收到B
检查成功的消息,马上开始触发检查,在信道绑定请求中指定信道号0x4002 以及对端B 的地址。由于A
是控制代理,在检查里可包含USE-CANDIDATE 属性执行强制提名算法,结果检查也成功了。代理A
产生了一个新的对(202.199.112.105:5006,
202.199.112.105:49152),该对被增加到有效列表,并设置提名标志(nominated flag)为TRUE,媒体流分组的ICE
处理迁移到完成态。A 可以通过信道0x4002 发送媒体流到B。
至此,通过该算法最终找到了媒体流传输的有效候选对,对应的最优路径也就随之确定了。由于有效候选是公网地址,因此通过该路径媒体流可顺利穿越NAT。
参考文献
[1] 魏立峰等。 一种媒体流穿越 NAT 的算法设计与实现, 《计算机工程》, 2009 年12 月
[2]RFC5245: Interactive Connectivity Establishment (ICE): A Protocol
for Network Address Translator (NAT) Traversal for Offer/Answer
Protocols, 2010 April
[转]ICE介绍 (RFC 5245)的更多相关文章
- ICE学习笔记 -- RFC 5245
RFC 5245 ICE 1, offer/answer model 2, ICE Step: 1) 产生候选地址(1.公网 2.NAT反射 3.Relay转发地址) Generate ca ...
- ice介绍 z
什么是ICE(Internet Communications Engine)呢,它是由Zeroc公司开 发的一套开源中间件系统,与DCOM,CORBA,WEB SERVICEDcom类似,支持RPC( ...
- ICE 介绍及实现
.ICE是什么? ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,使我们能够 ...
- 高性能分布式应用开发中间件ICE介绍
作为一个技术人员,你是否在为不断增长的数据量和日益复杂的业务逻辑而头疼不已,杂乱堆砌在一起的庞大业务让系统越来越脆弱,于是你想到了网格,想到了利用分布式来重组一个健壮的系统架构. 随后,RMI,EJB ...
- STUN, TURN, ICE介绍
STUN STUN协议为终端提供一种方式能够获知自己经过NAT映射后的地址,从而替代位于应用层中的私网地址,达到NAT穿透的目的.STUN协议是典型的Client-Server协议,各种具体应用通过嵌 ...
- webrtc教程
cdsn博客不支持word文件,所以这里显示不完全.可到本人资源中下载word文档: v0.3:http://download.csdn.net/detail/kl222/6961491 v0.1:h ...
- 转:WebRTC技术及应用2 – NAT穿越技术的使用
评:webrtc自带的打洞,穿透协议. 转: http://www.unclekevin.org/?p=924 959 views WebRTC技术及应用2 – NAT穿越技术的使用 发表回复 (题图 ...
- Zeroc Ice原理介绍
Ice介绍 Ice(Internet Communications Engine)是ZeroC公司的杰作,继承了CORBA的血统,是新一代的面向对象的分布式系统中间件.Ice是RPC通 ...
- 转:SIP相关的RFC文档索引
索引来源于http://www.packetizer.com/ipmc/sip/standards.html SIP Standards Core SIP Documents RFC Document ...
随机推荐
- js中的isNaN()函数
<html> <head> <script type="text/javascript" src="function.js"> ...
- toString 方法在数组中的使用
对于一个一维数组,他在转换成字符串的时候应该调用Arrays.toString(); 对于一个多维数组,他在转换成字符串的时候应该调用Arrays.deepToString(); 实例: packag ...
- 高性能JavaScript读书笔记
零.组织结构 根据引言,作者将全书划分为四个部分: 一.页面加载js的最佳方式(开发前准备) 二.改善js代码的编程技巧(开发中) 三.构建与部署(发布) 四.发布后性能检测与问题追踪(线上问题优化) ...
- EmguCV中图像类型进行转换
1. Bitmap:类型不在 Emgucv命名空间中 2. Image<TColor, TDepth> 3. Mat: 4. UMat: 高 ...
- nyoj222 整数中的1 数位DP
从a枚举到b是一定会超时的.此题应该考虑数位dp,也可以理解为递推,假设给定数n,就能在O(32)复杂度算出所有小于等于n的数中1出现的次数,那么给定区间[a, b],solve(b) - solve ...
- 【转载】一行代码加载网络图片到ImageView——Android Picasso
原文链接:一句代码加载网络图片到ImageView——Android Picasso 注意:此处使用下面代码需要先配置一下gradle,下载所需包. 具体操作如下图: compile 'com.sq ...
- 从零开始学习前端JAVASCRIPT — 14、闭包与继承
一.闭包 1 . 概念:闭包就是能够读取其他函数内部变量的函数.在JS中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解为”定义在一个函数内部的函数”. 2 . 闭包的特点 1)可以读取 ...
- JavaScript的预编译和执行
JavaScript引擎,不是逐条解释执行javascript代码,而是按照代码块一段段解释执行.所谓代码块就是使用<script>标签分隔的代码段. 整个代码块共有两个阶段,预编译阶段和 ...
- 关于chrom开发者工具priview和respons 数据内容不一致问题
在昨天晚上2017年8月24日,深夜升级的时候发现你了一个问题:简单的把问题描述一下:新增的一个付款单中的金额为最大值9999999999999999 ,但是保存后返回来的却是100000000000 ...
- dm642的中断
void fifoint_isr(); extern far void vectors(); void int_init() { IRQ_resetAll(); IRQ_se ...