前言

ICE全称Interactive Connectivity Establishment:交互式连通建立方式。

ICE参照RFC5245建议实现,是一组基于offer/answer模式解决NAT穿越的协议集合。
它综合利用现有的STUN,TURN等协议,以更有效的方式来建立会话。

客户端侧无需关心所处网络的位置以及NAT类型,并且能够动态的发现最优的传输路径。

Classic STUN(RFC3489)的劣势:

Classic STUN 有着诸多局限性,例如:

  1. 不能确定获得的公网映射地址能否用于P2P通信
  2. 没有加密方法
  3. 不支持TCP穿越
  4. 不支持对称型NAT的穿越
  5. 不支持IPV6

STUN(RFC5389)协议

RFC5389是RFC3489的升级版

  1. 支持UDP/TCP/TLS协议
  2. 支持安全认证

ICE利用STUN(RFC5389)
Binding Request和Response,来获取公网映射地址和进行连通性检查。同时扩展了STUN的相关属性:

  1. PRIORITY:在计算candidate pair优先级中使用
  2. USE-CANDIDATE:ICE提名时使用
  3. tie-breaker:在角色冲突时使用

TURN协议

ICE使用TURN(RFC
5766)协议作为STUN的辅助,在点对点穿越失败的情况下,借助于TURN服务的转发功能,来实现互通。端口与STUN保持一致

TURN消息都遵循 STUN 的消息格式,除了ChannelData消息。

  1. 支持UDP/TCP/TLS协议,适用于UDP被限制的网络。
  2. 支持IPV6。

TURN的流程:

创建Allocation

client 使用allocation
transaction创建relay 端口,并在allocation的响应中回复给client。

当allocation创建后需要使用refresh
request来保活,默认lifetime为10分钟。

创建Permission

由allocation创建Permission,每个Permission
由 IP 地址 和lifetime组成。

有两种方法来创建和刷新Permission

  1. CreatePermission
  2. ChannelBind

收发数据:

  1. CreatePermission使用Send and Data indication消息
  2. ChannelBind使用ChannelData消息

ICE介绍

  1. 1.    ICE 的角色

分为 controlling和controlled。

Offer 一方为controlling角色,answer一方为controlled角色。

  1. 2.    ICE的模式

分为FULL ICE和Lite
ICE:

FULL ICE:是双方都要进行连通性检查,完成的走一遍流程。

Lite ICE: 在FULL
ICE和Lite ICE互通时,只需要FULL ICE一方进行连通性检查, Lite一方只需回应response消息。这种模式对于部署在公网的设备比较常用。

  1. 3.     Candidate

媒体传输的候选地址,组成candidate
pair做连通性检查,确定传输路径,有如下属性:

Ÿ  
Type 类型有:

Host/Srvflx/Relay/Prflx

Ÿ  
Componet
ID

传输媒体的类型,1代表RTP;2代表 RTCP。

WebRTC采用Rtcp-mux方式,也就是RTP和RTCP在同一通道内传输,减少ICE的协商和通道的保活。

Ÿ  
Priority

Candidate的优先级。

如果考虑延时,带宽资源,丢包的因素,Type优先级高低一般建议如下顺序:

host
> srvflx > prflx > relay

Ÿ  
Base

是指candidate 的基础地址。

Srvflx address 的base 是本地host address。

host address和 relayed
address 的base 是自身。

  1. 4.    Candidate pair

由本端和远端candidate组成的pair,有自己的优先级。

pair优先级的计算是取决candidate的priority。

priority
= 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)

G:controlling candidate 优先级

D:controlled candidate 优先级

ICE选择高优先级的candidate
pair。

  1. 5.    Checklist

由candidate
pair生成按优先级排序的链表,用于ICE连通性检查。

  1. 6.    Validlist

由连通性检查成功的candidate
pair按优先级排序的链表,用于ICE提名和选择最终路径。

ICE过程

  1. 1.    Gather candidates

根据Componet ID:

Ÿ  
获取本机host address.

Ÿ  
从STUN服务器获取
srvflx address.

Ÿ  
从TURN服务器获取 relay
address.

Ÿ  
同时生成foundation。

  1. 2.    删除重复的candidate

收集地址完成后,需要去掉重复的candidate,如果两个candidate的地址一样,并且Base地址也一样,则删除它。

  1. 3.    交换candidates

ICE 使用offer/answer方式,双方通过SDP协商交换candidate信息.

Candidate信息包括type,foundation,base,component
id,transport

SDP a行格式如下:

“a=candidate:1
1 UDP 9654321 212.223.223.223 12345
typ srflx raddr 10.216.33.9 rport 54321”

 

表示 foundation为1,媒体是RTP,采用UDP协议,公网映射地址为212.223.223.223:12345,优先级为9654321,type为srflx,base地址为10.216.33.9:54321

  1. 4.    生成candidate pairs

在本端收到远端candidates后,将Component
ID和transport protocol相同的candidates组成pair。

修整candidate
pair,如果是srvflx地址,则需要用其base地址替换。

对端也是同样的流程。

  1. 5.    生成checklist

将candidate
pairs按照优先级排序,生成checklist,供连通性检查使用。

  1. 6.    连通性检查

Ordinary
checks 两端都按照各自checklist分别进行检查。

Triggered checks 收到对端的检查时,也在对应的candidate
pair上发起连通性检查,以提高效率

如果checklist里有relay
candidate,则必须首先为relay candidate创建permission。

  1. 7.    发送连通性检查请求

ICE 使用STUN
binding request/response,包含Fingerprint检验校验机制。

如果A收到B的response,则代表连通性检查成功,否则需要进行重传直到超 时。

在建立连接时,如果没有响应,则会以RTO时间进行重传,每次翻倍,直到最大重传次数。

STUN请求 采用STUN short-term
credential方式认证,

STUN USERNAME属性 ”RemoteUsername:localUsername”

两端在SDP协商时交换ice-pwd和ice-ufrag,以得对端用户名和密码。

STUN 检查请求中需要检查地址的对称性,请求的源地址是响应的目的地址,请求的目的地址是响应的源地址,否则都设置状态为
Failed。

  1. 8.    生成validlist

将连通性检查成功的candidate pair并按优先级排序加入validlist,这时本地candidate填写的是公网映射地址,remote
candidate填写的是对端发送的STUN binding request地址。

  1. 9.    提名candidate pair

由controlling来提名哪对candidate
pair为valid pair

提名方式又分为普通提名和进取型提名

普通提名方式会做两次连通性检查,在第一次做连通性检查时不会带上USE-CANDIDATE属性,而是在生成的validlist里选择pair再进行一次连通性检查,这时会带上USE-CANDIDATE属性,并且置位nominated
flag。

进取型方式则是每次发送连通性检查时都会带上USE-CANDIDATE属性,并且置位nominated flag,不会再去做第二次连通性检查。

10. 选择最终传输地址

ICE在提名的valid
pair里选择优先级最高那对作为本次ICE流程传输地址。

ICE状态

  1. Waiting:还未开始连通性检查,从checklist中选择合适优先级的pair进行检查
  2. In-Progress:连通性检查已经开始,但还未结束
  3. Succeeded:该pair 连通性检查已经完成并且成功
  4. Failed:失败
  5. Frozen:连通性检查还未开始

ICE保活

  1. 对于每个ICE通道,都需要为其会话进行保活。
  2. 采用STUN binding request或者STUN
    binding indication。
  3. 如果没有收到响应,则会重传,直到最大重传次数。

ICE角色冲突解决

  1. 当两端角色都为controlling或者controlled角色冲突时,在连通性检查阶段,要求发送binding
    request消息里必须要带上tie-breaker属性。
  2. 当出现冲突时,比较tie-breaker大小,值比较大的则被认为是controlling,同时回应487错误给对端,对端收到487错误后切换角色。

结束语

随着WebRTC的应用越来越普遍,无论是Native端还是Web端,由于广泛的适应       能力以及对未来网络的支持,ICE作为一种综合的解决方案将有着非常广阔的应用前景。

网易云信翻译了W3C推荐标准WebRTC 1.0:
Real-time CommunicationBetween Browsers,并提供《WebRTC1.0: 浏览器间实时通讯》中文版免费下载

  • 对于WebRTC初学者,本文档可以作为学习教程,帮助你快速对WebRTC有全面且详细的了解,学习相关API的使用,其附带的示例代码也是很好的学习资料;
  • 对于WebRTC资深开发者,本文档可以作为开发中的使用手册,根据所提供的函数调用链或是算法流程进行开发或bug定位;
  • 对于高阶玩家,也可通过阅读本文档对WebRTC工作组反馈改进意见。

限时免费下载,WebRTC开发者必备。


想要阅读更多技术干货、行业洞察,欢迎关注网易云信博客

了解网易云信,来自网易核心架构的通信与视频云服务。

网易云信(NeteaseYunXin)是集网易18年IM以及音视频技术打造的PaaS服务产品,来自网易核心技术架构的通信与视频云服务,稳定易用且功能全面,致力于提供全球领先的技术能力和场景化解决方案。开发者通过集成客户端SDK和云端OPEN API,即可快速实现包含IM、音视频通话、直播、点播、互动白板、短信等功能。

WebRTC 之ICE浅谈的更多相关文章

  1. 浅谈Windows API编程

    WinSDK是编程中的传统难点,个人写的WinAPI程序也不少了,其实之所以难就难在每个调用的API都包含着Windows这个操作系统的潜规则或者是windows内部的运行机制…… WinSDK是编程 ...

  2. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  3. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  4. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  5. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  6. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  7. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  8. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  9. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

随机推荐

  1. Java 【Math】

    一.Math类的使用方法 public class demo{ public static void main(String[] args){ double pi = Math.PI; //Math函 ...

  2. netty 4.x用户使用指南

    引言 问题 现在我们使用通用的应用程序或库来相互通信.例如,我们经常使用HTTP客户机从web服务器检索信息,并通过web服务调用远程过程调用.然而,通用协议或其实现有时不能很好地进行扩展.这就像我们 ...

  3. 剑指offer-面试题5-替换空格-字符串

    /* 题目: 请实现一个函数,把字符串中的每个空格替换成'%20'. 例如输入“We are happy",则输出 ”We%20are%happy". */ /* 结题思路: 考虑 ...

  4. 虚拟机(linux)怎么上网

    问题描述:本机并没有显示虚拟机(linux)的虚拟网卡,那能不能用虚拟机上网呢,如果要让本机显示出虚拟机的虚拟网卡会有一万步各种安装卸载,那么,在现有条件下可不可以上网呢,答案是可以的. 解决方案: ...

  5. ArcGIS JavaScript API with jQuery: Error: multipleDefine

    I would like to use ArcGIS JavaScript API 4.3 with jQuery, but I am getting following errors.  I sea ...

  6. Linux系统的启动原理

    Linux系统的启动原理 RHEL的启动原理BIOS自检-MBR-启动GRUB-加载内核-systemd的init进程 systemd的初始化进程加载需要的服务,挂载文件系统/etc/fstabsys ...

  7. Redis缓存数据库(一)

    先导知识:Memcache Memcache是一个高性能的分布式内存对象缓存系统,代码类似于Hash. 已经有了Memcache,为什么还要用Redis呢? 下面Memcache的缺点: 不支持数据持 ...

  8. 2020省选模拟训练1 排列(perm)多项式exp+EGF

    这道题真的还是简单的一批..... 我当时要是参加考试的话该多好(凭这一道题就能进前 5 了) 十分显然的指数型生成函数. 令 $f[i]$ 表示有 $i$ 个点的答案. 然后显然有 $f[i]=\s ...

  9. JS阻止事件冒泡与浏览器默认行为

    阻止冒泡 W3C的方法是e.stopPropagation() IE是e.cancelBubble = true; 阻止默认行为 W3C的方法e.preventDefault(), IE是e.retu ...

  10. vConsole 让你在手机上也能轻松调试网页

    有时候为了想在手机真机上对网页进行 Debug,可手机上没有 F12,用 Chrome DevTools 连接手机操作又太过复杂.VConsole 的出现,正好解决了这一痛点! (下列内容照搬一下官方 ...