pjsip教程-ICE-NAT passthrough
来源:互联网 发布:新通用顶级域名 编辑:程序博客网 时间:2024/04/29 13:11
http://www.cnblogs.com/ishang/p/3413232.html
PJNATH - Open Source ICE, STUN, and TURN Library
PJNATH (PJSIP NAT Helper)是一个开源的并且是使用标准协议(STUN,TURN,ICE)提供NAT设备穿越功能的库.
Background
在现今的网络中网络地址转换技术/设备(NAT)很常见,这种技术允许多台主机共享同一个公网地址从而接入网络,其主要目的就是为了缓解IPv4地址的枯竭。 这种技术在普通的服务器/客户端模式下并不存在问题,因为请求总是由客户端发起,并且客户端也不需要维持长时间的维持与服务器的连接。但是NAT技术最大的问题就是使得点对点通信不能进行,比如VoIP.
Introduction to PJNATH
PJNATH库包含了NAT穿越的标准实现,它可以独自应用或者与PJSUA-LIB共同使用,PJSUA-LIB库将PJSIP, PJMEDIA, PJNATH很好的集成在一起,使用方便。.
PJNATH 具有以下特征:
- STUNbis实现
该实现遵照RFC 5389.它既提供了现成的STUN网络接口,又提供了基于TURN和ICE的实现更高层次STUN的框架。
- NAT 类型探测
探测通信两端的NAT设备类型,该实现依据 RFC 3489. 然而为了支持ICE,协助NAT穿越的NAT类型的探测已经不被推荐了,但是在故障排除的时候还是有用的,因此提供了NAT类型探测的功能.
- TURN实现
TURN 是使用中转服务器进行中继通信的协议,它联合ICE提供了尽可能的高效的通信路径。它的实现符合 draft-ietf-behave-turn-14 草案.
- ICE实现
ICE 是发现待通信两端一条或多条可直接通信的路径的协议。它的实现符合draft-ietf-mmusic-ice-19.txt 草案
在将来,我们会实现更多的协议(比如UPnP IGD、SOCKS5).
Library Organization
提供的主要组件如下:
- STUN: Session Traversal Utilities for NAT
- TURN: Traversal Using Relays around NAT
- ICE: Interactive Connectivity Establishment
- NAT Classification/Detection Tool
除了 NAT Classification/Detection Tool, 每个组件都进一步划分为两个部分:
- 传输对象
传输对象是session对象加上指定的 传输/套接字(transport/sockets) 的实现,它给应用程序提供一个直接可以使用的对象。比如,STUN transport, TURN transport以及ICE stream transport
传输无关/session 层
session对象(比如 STUN session, TURN session, ICE session)是维护通信协议中session的核心对象,它是与传输无关的(意思是说它自己没有专门用于传输数据的socket,它只有发送和接受数据的接口,至于发送和接收数据时用到的具体的协议它是不关心的)。这样,不管传输层使用的什么协议,开发者都可以重用这个对象,比如使用UDP, TCP或者TLS或者是开发者自己实现的其他某种协议。
Introduction to ICE
ICE是提供客户端穿越能力的有力武器,只要在两个客户端之间确实存在一条可以通信的路径,ICE肯定就能找到该路径,并且该路径是两个客户端之间通信路径中最高效的最节省资源的(在两个客户端之间经ICE探测后,可能存在多条路径,而ICE保证从它那里获取的路径是最高效的).
ICE把几个协议结合在一起,在两个客户端之间能提供几条候选路径,这在最大程度上保证了两端通信成功的几率。并且它还提供了在几条通信路径中给出优先顺序的能力,让使用中继(中继的方式代价比较昂贵)的传输方式的优先级降到最低,只有在其他路径都行不通的情况下,才会启用该路径。具体的ICE协商的过程包括以下几个几步:
- 1:候选地址的收集:ICE客户端收集本地所有可能用于通信的地址。所收集的地址类型分3种:主机候选地址(host candidate),这个地址其实就是本地物理网卡的地址;服务器反射候选地址(server reflexive candidate,其实就是在NAT上关于本地ip的映射地址),这个地址通过STUN服务器获取;中转/中继候选地址(relay candidate),这个地址是在使用中继(relay)的传输方式时,在中继服务器(或者称为TURN服务器)上为本地机器所分配的地址。
- 2:候选地址的优先策略:一般情况下,使用中继方式而产生的中继候选地址的优先权最低,因为它的代价最昂贵。
- 3:将本地候选地址编码,把编码后的候选地址传送至对端,双方通过报告/应答的方式进行协商。
- 4:为候选地址配对儿:将本端的地址与对端的地址一一进行配对。此时应该已经通过某种方式得到了对端的候选地址。
- 5:为每对儿地址做连接测试。
- 6:得到结果:由于已经对所有候选地址一一配对,并一一进行连接测试,所以,如果确实存在一个可以通信的路径,ICE肯定会找到他。
Using ICE transport
ICE stream transport 是一个现成可用的对象,可以使用它来进行ICE操作,而且它为应用程序提供了数据发送与接受的接口,而数据收发的路径,正是经ICE协商过后的高效的路径。
Creating custom ICE transport
如果ICE stream transport 还是不能满足您的需求,那么您还可以通过使用本软件包提供的ICE Session以及自己的数据传输策略去实现自己的运输层,ICE stream transport 在这方面为您提供了很好的借鉴。
1:pjsip教程(一)之PJNATH简介
2:pjsip教程(二)之ICE穿越打洞:Interactive Connectivity Establishment简介
3:pjsip教程(三)之ICE stream transport的使用
4:pjsip文档(四)之ICE Session的使用方法
本文原文地址:http://www.pjsip.org/pjnath/docs/html/group__PJNATH__ICE__STREAM__TRANSPORT.htm#ga6fb7cfdde71523f9fce885fd5cad982d
学习使用 ICE stream transport
下面的步骤描述了怎样使用ICE session:
- 首先初始化结构体: pj_ice_strans_cfg. 这个结构体中包含了ICE stream transport 的配置信息,其中就包括了SUTN以及TURN的配置信息.
- 使用 pj_ice_strans_create()方法创建stream transport的实例. 该函数的成功调用还需要以下列出的重要的参数:
- pj_ice_strans_cfg :主配置信息
- components 的个数
- 用于产生回调的结构体的实例:pj_ice_strans_cb .
- 当调用函数pj_ice_strans_create()后,初始化的过程会在后台运行,该初始化过程主要是收集本地的候选地址,最后,当初始化完成,应用程序会在回调函数on_ice_complete 中返回
- 当想要开启一个媒体流时(例如,想进行视频或语音电话),使用pj_ice_strans_init_ice()创建一个ICE session用于进行打洞.
- 通常在两个客户端开始打洞之前,双方都需要知道对方的ICE信息(ICE信息,包括用户名,密码以及3组候选地址),那么可以使用下面的方法得到自己的ICE信息:
- pj_ice_strans_get_ufrag_pwd()
- pj_ice_strans_enum_cands()
- pj_ice_strans_get_def_cand()
应用程序需要将以上信息封装为SDP消息发送至对方.
- 当应用程序收到远程客户端发来的ICE消息后,就可以开始ICE探测了。开始ICE探测需要调用pj_ice_strans_start_ice()方法.
- 需要注意的是,PJNATH库不支持直接处理SDP消息,SDP消息的封装与拆解还需应用程序自己实现。
- 一旦ICE的探测协商开始后,程序最终将会在回调函数on_ice_complete() 中返回。on_ice_complete() 属于结构体: pj_ice_strans_cb.
- 应用程序在程序运行的任何时刻都能发送或者接受数据,但是ICE的stream transport 对象它能否发送数据,取决于它发送数据时候的状态。状态分为三种:1,探测协商之前,这种状态下可以发送数据,并且使用的是默认的地址;2,探测协商的过程中,此时不能发送数据;3,探测协商完成之后,这种状态下也可以发送数据,且发送数据的地址为探测成功的地址对!
- 应用程序使用pj_ice_strans_sendto()发送数据,并在pj_ice_strans_cb的on_rx_data()回调中返回.
- 当需要结束媒体Session时,使用pj_ice_strans_stop_ice()回收ICE Session。
关于ICE stream transport,在单次媒体交互完成后,可以选择销毁ICE stream transport或保留它以备后用。保留ICE stream transport有利有弊,好处是减少下次会话时创建它的时间;坏处是应用程序需要与STUN server以及relay server中相应的端口保活,这会无形中造成电量的损耗(consume power), 而电量损耗的高低是移动设备应用的重要参考标准之一。
Detailed Description
这个模块描述的pj_ice_sess对象是PJNATH库的组成部分同时它是与数据包的传输无关的对象(a transport independent)。
ICE Session
ICE Session 是PJNATH库中关于ICE的最底层的抽象,它使用一个单一的媒体流来执行两端的连接检测(双方通过互发数据包进行协商,从而确定一条从A到B可以互通的路径)。ICE Session 使用pj_ice_sess结构体来表示.
此处描绘的ICE Session它不做数据的传输(is independent from any transports),那么这也表明网络的IO得是由应用程序本身或者由它更高的抽象层来执行。使用这个框架,应用程序就可以使用ICE Session来处理所有接收到的数据包,并且该框架也为ICE Session提供了向外发送数据的回调接口。
关于ICE更高级的抽象,请查看ICE stream transport进行了解.
Using The ICE Session
下面是ICE Session的详细使用步骤,当然,开发者也可使用ICE stream transport的API,它对ICE进行了更高级的封装,并且提供了ICE socket的集成。
ICE Session的使用步骤类似于报告/答复模式(offerer and answerer):
- 使用pj_ice_sess_create()创建ICE Session,其中用户需要指定一下几个参数:
- STUN 的配置:STUN的一些设置,比如超时时间以及STUN 中需要用到的timer heap、ioqueue实例.
- Session名称,可用于在日志中标识唯一的会话.
- 初始化ICE的角色(pj_ice_sess_role).角色的设置可以在初始化完成之后通过pj_ice_sess_change_role()改变。ICE Session也可以在检测到角色冲突之后自动更改。
- 媒体会话中构件的数目.
- 触发ICE事件之后的回调函数的设置(pj_ice_sess_cb)
- 本地ICE用户名称和密码,不过不设置此项时,系统将会随机生成.
- 使用pj_ice_sess_cand结构体来表示候选者实例,使用pj_ice_sess_add_cand()为每一个构建添加本地地址候选. 每个构件初始化过程中必须至少有一个候选地址,并且所有的控件必须拥有相同的候选地址数,不然会导致配对过程的失败。
- 创建本地信息的实例(用于描述本地ICE候选者):ICE session没有提供创建该实例的功能,但是应用程序应该实现该功能。如果应用程序使用ICE stream transport的时候,可以使用pj_ice_strans_enum_cands()方法来枚举所有本地候选者。应用程序可使用pj_ice_sess_find_default_cand() 来让ICE Session选择使用在SDP c= and m= lines中的默认的传输地址.
- 通过某一种信令(比方说SIP)将承载本地信息的实例发送至对端.
- 当本地接收到对端的应答(包含了对端的候选者信息),应马上解析该消息,建立关于对端的候选者列表,并且通过pj_ice_sess_create_check_list()来建立check lists,这个过程就称为配对.
- 配对完成后,就可以调用pj_ice_sess_start_check()开始执行连接测试,查看上步中哪个配对是有效的.
- 最后,在连接测试完成后,应用程序会在pj_ice_sess_create()回调中收到测试结果.
使用pj_ice_sess_send_data()方法来发送数据。如果发送数据的时候是在ICE协商还没完成时,那么ICE session 将直接丢弃该数据并且给调用者返回错误信息;如果是在ICE协商完成后,那么ICE session 将会调用pj_ice_sess_cb的on_tx_pkt来发送数据.
由于ICE Session本身没有传输机制,所以应用程序必须把从底层接收到的所有数据包都通过pj_ice_sess_on_rx_pkt()方法传递给ICE Session,ICE Session判断该包是否为STUN包,如果是,则处理;如果不是,则使用on_rx_data回调把数据包向上传递给应用上层.
- pjsip教程-ICE-NAT passthrough
- 6年pjsip移植iphone,android等平台经验实现P2P和ICE-穿越3G各种NAT
- ICE for NAT
- NAT穿透之ICE协议
- stun turn ice等穿越NAT方法
- NAT穿透(STUN/TURN/ICE/UPnP)
- stun turn ice等穿越NAT方法
- stun turn ice等穿越NAT方法
- TURN/STUN/ICE NAT的基本知识
- stun turn ice等穿越NAT方法
- NAT ICE STUN TURN uPNP概念
- NAT and Traversal NAT(TURN/STUN/ICE)
- !NAT and Traversal NAT(TURN/STUN/ICE)
- NAT and Traversal NAT(TURN/STUN/ICE)
- NAT and Traversal NAT(TURN/STUN/ICE)
- NAT and Traversal NAT(TURN/STUN/ICE)
- NAT and Traversal NAT(TURN/STUN/ICE)
- NAT and Traversal NAT(TURN/STUN/ICE)
- 数据库增删改查语句学习
- debian修改配置软件源
- 文件服务的独立拆分思路(一)
- 【学习笔记】系列十二:Google Espresso和Robolectric配置实例
- java jetty 启动设置根路径
- pjsip教程-ICE-NAT passthrough
- 1200华中科技
- webservice开发(cxf)
- IllegalArgumentException 关于点击事件bindService后出现的问题
- Android APK终极瘦身21招
- EventBus使用
- 为什么要make update -api ???
- 懒人之家-QQ客服右侧
- TabLayout用法,android顶部导航栏,android底部导航栏