转:WebRTC技术及应用2 – NAT穿越技术的使用
评:webrtc自带的打洞,穿透协议。
转: http://www.unclekevin.org/?p=924
959 views
WebRTC技术及应用2 – NAT穿越技术的使用
![]()
(题图来源)
WebRTC的开发者在这篇技术文档【1】之中提到了WebRTC使用的NAT穿越技术。简而言之,就是基于ICE技术,而ICE本身不是NAT技术,而是整合了STUN,TURN等几个NAT技术的的一个框架。相关技术都很成熟,这里简明解释一下原理。
NAT的分类
RFC 3489【2】之中介绍了给出了已有NAT实现的分类,就是三个Cone (圆锥) NAT和一个Symmetric NAT。Cone (圆锥)NAT的命名是把IP + Port看成一个点之后的比喻。
1.Full Cone NAT
![]()
上图是Full Cone NAT的示意图。
在内网用户PC A对外发送数据流产生了一个NAT条目,等效于将内网PC的端口,通过公网地址映射成外网可以任意访问的“服务端口”。
2.Restricted Cone NAT
![]()
受限Cone NAT,和Full Cone NAT的区别是,前者只允许已经建立的NAT条目中对应的外部IP访问这个的PC A的端口。
3.Port Restricted Cone NAT
![]()
在受限core NAT,端口受限的含义是,必须以前见过远端IP和Port才能访问PC A的相应端口。
4.Symmetric NAT
![]()
看起来和端口受控Cone NAT类似,其实本质已经和Corn NAT不一样了。前三个Cone NAT生成NAT entry之后,对外映射的Port还可以被后续inbound session使用,不会变化。而对称NAT,每次启动新的会话,NAT得到的IP+Port是不同的。因此无法向外部提供一个稳定的“服务端口”了。
STUN(Simple Traversal of UDP Through NAT)
STUN是一个C/S模式的协议,允许NAT内的用户(例如PC A),通过STUN Client同外部的STUN Server通信。交互几次后,得到自己对外映射的公网IP,并且知道所处网络的NAT的类型。
下图是STUN Wiki之中的NAT发现算法的流程图,。
![]()
上图”Symmetric” NAT的判断有些问题,协议中的描述“If the IP address and port returned in the MAPPED-ADDRESS attribute are not the same as the ones from the first test I, the client knows its behind a symmetric NAT.”。流程图中只有“Public IP is constant?”没有考虑port NAT。其它部分看起来还是正确的:
初始的时候,STUN Client发送基于TLS的Share Secret Request,Server应答中返回临时的用户名和密码,用于认证的辅助机制,协议的主要实现是Binding Request。
Binding Request有两种类型的功能:
1.可以要求Server发送的Response的Payload中携带Client的公网源IP和端口。
2.也可以要求Server发送的报文从另一个地址和端口过来。
用这两种类型的request参照上图算法可以判别公网IP以及NAT类型。
TURN (Traversal Using Relays around NAT)
TURN的引入是因为两个位于Symmetric NAT后的端点无法进行通信(IP和Port不固定,无法实现公开)。因此引入了TURN Server这个实体作为中继转发。可以用下图示意,有了以及持久的Relay Session,外部可以通过TURN Server的代理
![]()
TURN RFC 5766提到了STUN和TURN的关系:
”TURN is an extension to the STUN (Session Traversal Utilities for
NAT) protocol [RFC5389]. Most, though not all, TURN messages are
STUN-formatted messages.“
可以理解为TURN = STUN + Relay功能。两者的一个区别是,在用STUN发现公网地址信息后,实际通信功能是Peer to Peer的。而对于TRUN, Peer和Peer之间的通信需要经过TRUN Server。
ICE (Interactive Connectivity Establishment)
![]()
ICE功能如上图所示,ICE是一个NAT框架,调用下层的具体NAT协议进行最优路径选择。而应用调用ICE进行路径选择。
【1】中提到:
1.ICE会首先试图使用本机地址。
2.如果失败表示本机在NAT之后,则试用通过STUN获取外部地址。
3.如果失败,则试图使用TURN Server进行中继。
WebRTC的ICE功能实现
每个RTCPeerConnection (可以理解为Javascript中P2P连接对象,后文会提到)有一个ICE Agent,(参照【8】)
ICE Agent功能:
1.获取ICE candidate, 也就是本地一对<IP, port>对映射的公网<IP, port>信息。获取的过程叫做ICE gathering。(细节参照RFC5245)
首先得到本地IP和端口,然后用ICE流程通过STUN或者TURN服务器,得到公网IP和Port。
下面是ICE的参数(【8】),是公网可用的TUNE和STUN服务器地址。
|
1
2
3
4
|
var ice = {"iceServers": [
{"url": "stun:stun.l.google.com:19302"}, 1
{"url": "turn:turnserver.com", "username": "user", "credential": "pass"} 2
]};
|
可能获得的Candidate有三类:
A.如果本地IP是公网IP,则直接本地IP和Port。
B.STUN可用,则STUN检测到的NAT翻译之后的公网IP和Port。
C.TURN可用,则TURN服务器的Relay地址。
2.检测同peer之间的连通性
3.Keepalive
ICE Gathering过程的触发
在调用RTCPeerConnection的set local session description或者set remote session description时候,ICE Gathering流程会被触发。下面是【8】中的代码,在ICE收集的状态达到complete也就是结束后,会产生SDP消息中的a line,将ICE candidates信息发送给对方。
|
1
2
3
4
5
6
7
8
|
pc.onicecandidate = function(evt) {
if (evt.target.iceGatheringState == "complete") { 4
local.createOffer(function(offer) {
console.log("Offer with ICE candidates: " + offer.sdp);
signalingChannel.send(offer.sdp); 5
});
}
}
|
…
// Offer with ICE candidates:
// a=candidate:1862263974 1 udp 2113937151 192.168.1.73 60834 typ host … 6
// a=candidate:2565840242 1 udp 1845501695 50.76.44.100 60834 typ srflx … 7
Peer之间的连通性检测(connectivity checks)
这一步的触发时机是在remote session description设置之后,如果本地的ICE收集也做完了,可以进行连通性检测。
检测的方式是,一方的ICE Agent发送STUN binding request,另一方回应STUN response。检测成果的结果是,在双方之间建立了一条可用的路径。
Incremental Provisioning (Trickle ICE)
引入这种机制的原因是,ICE Gathering的过程耗时很长,会影响连接建立,为此可以做如下优化:
1.双方在交换SDP的时候可以不用带ICE Candidate信息。
2.当发现ICE Candidate的时候,通过信令通道发送。
3.连通性检测也可以增量的去做。
也就是不需要等到ICE过程完全结束后再进行SDP的交换和P2P的建立。
【参考】
1.WebRTC in the real world: STUN, TURN and signaling,http://www.html5rocks.com/en/tutorials/webrtc/infrastructure/
2.STUN, RFC 3489 STUN – Simple Traversal of User Datagram Protocol (UDP) ThroughNetwork Address Translators (NATs).
3.STUN2,RFC 5389 Session Traversal Utilities for NAT (STUN),替代RFC 3489
4.TURN,RFC 5766 Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)
5.URL Scheme, RFC 7064 URI Scheme for the Session Traversal Utilities for NAT (STUN)Protocol.
6.ICE,RFC 5245 Interactive Connectivity Establishment (ICE): A Protocol for Network
Address Translator (NAT) Traversal for Offer/Answer Protocols
7.Introduction to libjingle , https://developers.google.com/talk/libjingle/developer_guide
8.WebRTC of High Performance Browser Network,http://chimera.labs.oreilly.com/books/1230000000545/ch18.html
本条目发布于2015年6月4日。属于P2P、VoIP、WEB、网络协议分类。
转:WebRTC技术及应用2 – NAT穿越技术的使用的更多相关文章
- NAT详解:基本原理、穿越技术(P2P打洞)、端口老化等
这是一篇介绍NAT技术要点的精华文章,来自华3通信官方资料库,文中对NAT技术原理的介绍很全面也很权威,对网络应用的应用层开发人员而言有很高的参考价值. 学习交流 移动端即时通讯学习交流: 21589 ...
- P2P技术详解(三):P2P技术之STUN、TURN、ICE详解
1.内容概述 在现实Internet网络环境中,大多数计算机主机都位于防火墙或NAT之后,只有少部分主机能够直接接入Internet.很多时候,我们希望网络中的两台主机能够直接进行通信,即所谓的P2P ...
- P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...
- p2p网络中的NAT穿透技术----常见NAT穿越解决方案
转:http://blog.csdn.net/cllzw/article/details/46438257 常见NA丁穿越解决方案 NAT技术在缓解IPv4地址紧缺问题.构建防火墙.保证网络安全等方面 ...
- NAT原理与NAT穿越
最近在看东西的时候发现很多网络程序中都需要NAT穿越,特意在此总结一下. 先做一个约定: 内网A中有:A1(192.168.0.8).A2(192.168.0.9)两用户 网关X1(一个NAT设备)有 ...
- SOCKET 实现NAT 穿越
在当前IPv4NAT盛行的网络环境下,两个用户要直接进行P2P连接是非常困难的.较好的解决办法是借助含公网的用户或是服务器中介实现P2P连接. NAT:Network Address Translat ...
- IPFS: NAT traversal(NAT穿越)
IPFS是一个p2p网络,那么一定绕不开的一个问题就是NAT穿越.之前的文章里面也提到过IPFS网络连通性使用的ICE NAT穿越框架,本文简单介绍一下什么是NAT. 为什么有NAT技术? NAT ...
- (转)NAT与NAT穿越学习总结--ICE过程讲的不错
转:http://cgs1999.iteye.com/blog/1994072 1.引言网络地址转换(Network Address Translation,简称NAT)是一种在IP分组通过路由器或防 ...
- VOIP NAT穿越之SIP信令穿越
本文原创自 http://blog.csdn.net/voipmaker 转载注明出处. 本文是VOIP通信NAT系列专题的第三篇, 本文论述NAT对SIP协议穿越的影响.SIP协议是基于文本的,而 ...
随机推荐
- nuc 第二届山西省大学生程序设计大赛 魔力手环
problem 很妙啊--发现状态转移矩阵每一行都可以由上一行平移得到,每次只算第一行然后平移,\(O(n^3)\) 就变成了 \(O(n^2)\). #include <iostream> ...
- 两种图片延迟加载的方法总结jquery.scrollLoading.js与jquery.lazyload.js
估计网上能查到的最多的两种图片延迟加载方法就是jquery.scrollLoading.js与jquery.lazyload.js了,其中jquery.lazyload.js的调用方法因为有网友爆出的 ...
- Selenium WebDriver- 操作 IFrame 中的页面元素
#encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...
- concurrent.futures模块(进程池&线程池)
1.线程池的概念 由于python中的GIL导致每个进程一次只能运行一个线程,在I/O密集型的操作中可以开启多线程,但是在使用多线程处理任务时候,不是线程越多越好,因为在线程切换的时候,需要切换上下文 ...
- pytion3--class一个更实际的例子
class一个更实际的例子 到目前为止,我们所看的大多数例子都是人为创造而且是独立完备的,其目的是为了帮助你把注意力集中在基础知识上.然而,本章的结尾是一个较大的例子,把我们所学的大多数概念都聚合在这 ...
- Diango路由控制
路由的格式: #路由配置的格式: urls.py里面写 from diango.conf.urls import url urlpatterns = [ url(正则表达式,views视图函数,nam ...
- 利用Solr的post工具对核心my_core执行删除操作
<delete> <query>*:*</query> </delete> 将上面代码保存到delete_all.xml文件中,并使用Solr的post ...
- 九度oj 题目1355:扑克牌顺子
题目描述: LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他 ...
- 备忘 CSS字体中英文名称对照表
转载自:http://www.jb51.net/css/67658.html 在CSS文件中,我们常看到有些字体名称变成了乱码,这是由于编写者将中文字体的名字直接写成了中文,并且再上传或者拷贝复制的时 ...
- javaweb学习总结(十一)——使用Cookie进行会话管理(转)
一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...