ICE学习笔记 -- RFC 5245

4)STUN Message Type
- request
             - success response
             - failure response 
             - indication
1、A向S发出Allocate Request,请求S在自己的IP地址上为A分配一个端口。
5. 开源实现 https://github.com/NATTools
ICELIB_INSTANCE *m_iceInst;
static ICELIB_Result OnConnectivityChecksComplete(void *pUserData, uint32_t userValue1, bool isControlling, bool iceFailed);
static ICELIB_Result OnOutgoingBindingRequest(void *pUserData, const struct sockaddr *destination,
        const struct sockaddr *source, uint32_t transport, uint32_t userValue1, uint32_t userValue2,
        uint32_t componentId, bool useRelay, const char *pUfragPair, const char *pPasswd,
        uint32_t peerPriority,  bool useCandidate, bool iceControlling, bool iceControlled,
        uint64_t tieBreaker, StunMsgId transactionId, const char *szFingerPrint);
static ICELIB_Result OutgoingBindingResponse(void *pUserData, uint32_t userValue1,
        uint32_t userValue2, uint32_t componentId, const struct sockaddr *source,
        const struct sockaddr *destination, const struct sockaddr *MappedAddress,
        uint16_t errorResponse, StunMsgId transactionId, bool useRelay, const char *pUfragPair,
        const char *pPasswd);
/*
static ICELIB_Result OnSendKeepAlive(void *pUserData, uint32_t userValue1, uint32_t userValue2,
        uint32_t mediaIdx);
*/
6. wilson同学的分享记录
ICE
1. 什么是NAT?(网络地址转换)
2. NAT带来的问题(连通性问题,并没有定义或推荐公网或私网IP地址影射的方法,及互相通迅的问题,完全由应用自己解决)
3. STUN解决的问题(解决两个NAT之后设备的连通)
4. 源地址、目标地址、源端口,目标端口,协议 5个元素
5. NAT暴力猜测方法,两边各猜64个连接,连通的概率就很大了
6. ALG,根据SDP里的信息,帮你分配端口,路由器要支持SDP,且SDP不能被加密
7. Connectivity check,可以做很多并行的尝试,间隔一定的delay,按优先级发包
8. STUN包做了扩展。PRIORITY, USE-CANDIDATE, ICE-CONTROLLED, and ICE-CONTROLLING
9. Nominate的过程:(Nomination 一直在做,priority每过100毫秒加100,达到1000,即可以conclude.)
   收到包以后,好几个都通了,就需要选择一个。Aggressive/Regular nomination, Aggressive nomination已经淘汰,因为协议有bug。
   Aggressive 本来是想更快的建立连接,后来大家发现Regular完全可以做到同样的快, Early media。
Regular Nominate过程,发的STUN包有两种包,USE-CANDIDATE=0(Nominate前), USE-CANDIDATE=1(Nominate后)
   两个人,不能两个人都Nominate, 要选择一个主动,一个被动。SDP里面有个属性,叫ICE-CONTROLLING(主动), ICE-CONTROLLED(被动)。
   被动的一方收到response,看到USE-CANDIDATE=1,就知道了选择好了,以后用这个transport来通讯。
   角色的选择,第一个STUN包的里时候,里面有个tie-breaking,是一个64bit的随机数,谁的大谁就做CONTROLLING,另一个做CONTROLLED
10. LITE实现(当做为服务器时,有公网IP的情况下,申明我是LITE,就不需要connectivity check,由client来check) 
    firefox 对LITE支持的不太好,chrome还可以。
11. Restart/Reconnect
12. Keep live(定时,client发一个包,server回一个包,做有效性检查)
13. Conclude:(为什么Aggressive Nominate不需要了,是因为有Early media)
	Early media就是说,有一个transport连通以后,就可以发送一些数据回去,所以只要你发,对方肯定能收的到.
	因为这时候还没有Conclue,一旦conclue这后,非nominate的transport会被关闭。
    Conclude,是为了保证RTP的transport是symmetric的,即发过去和发过来的transport是同一个。
14. ICE, RTP, DTLS是复用在同一个transport上的。
15. AddMediaStream,一个SDP里面有多个Media(Audio/Video),要建多条连接,一个MediaStream里面有两个component(RTP1 /RTCP 2).
    一个session里面有多个MediaStream(Audio/Video/Sharing)。
	我们ICE session里面的实现,三个是分开的,一个Media就用了一个Session,是觉得放在一个session里,可以做优化的不多。
	Audio/Video/Sharing各有一个ICEConnector,各用一个transport。
16. 优先级 0123456 Nattool里fundation有bug(不同的IP用相同的fundation).
17. OnICEComplete会来两回,第一次是Early meida(最早的连通的一个transport), 第二次是Conclude. bUpdate=0 bUpdate=1。
ICE
//
//----- ICE configuration data
//
typedef struct {
    unsigned int    tickIntervalMS;
    unsigned int    keepAliveIntervalS;
    unsigned int    maxCheckListPairs;
    bool            aggressiveNomination;
    bool            iceLite;
    ICELIB_logLevel logLevel;
} ICELIB_CONFIGURATION;
//
//----- ICE instance data
//
typedef struct tag_ICELIB_INSTANCE {
    ICELIB_STATE                iceState;
    ICELIB_CONFIGURATION        iceConfiguration;
    ICELIB_CALLBACKS            callbacks;
    ICE_MEDIA                   localIceMedia;
    ICE_MEDIA                   remoteIceMedia;
    bool                        iceControlling;
    bool                        iceControlled;
    bool                        iceSupportVerified;
    uint64_t                    tieBreaker;
    ICELIB_STREAM_CONTROLLER    streamControllers[ ICE_MAX_MEDIALINES];
    unsigned int                numberOfMediaStreams;
    unsigned int                roundRobinStreamControllerIndex;
    uint32_t                    tickCount;
    uint32_t                    keepAliveTickCount;
} ICELIB_INSTANCE;
/*!
 * ICE single candidate
 *
 * From draft-ietf-mmusic-ice-18:
 *
 *  foundation      = 1*32 ice-char
 *  componentid     = 1*5 digit  (0..65535)
 *  priority        = 1*10 digit (0..2147483647)
 *  connectionAddr  = address including port
 *  relAddr         = host addres when sending relayed candidates (Optional, used for debugging)
 */
typedef struct {
    char                    foundation[ ICE_MAX_FOUNDATION_LENGTH];
    uint32_t                componentid;
    uint32_t                priority;
    struct sockaddr_storage connectionAddr;
    ICE_CANDIDATE_TYPE      type;
    struct sockaddr_storage relAddr;
    uint32_t                userValue1;
    uint32_t                userValue2;
	uint32_t                transport;
    char                    fingerprint[ICE_MAX_FINGERPRINT];
} ICE_CANDIDATE;
typedef struct {
    uint32_t                componentId;
    struct sockaddr_storage connectionAddr;
    ICE_CANDIDATE_TYPE      type;
} ICE_REMOTE_CANDIDATE;
typedef struct {
    ICE_REMOTE_CANDIDATE remoteCandidate[ICE_MAX_COMPONENTS];
    uint32_t  numberOfComponents;
} ICE_REMOTE_CANDIDATES;
/*!
 * ICE candidates for a single media stream
 */
typedef struct {
    char                    ufrag    [ ICE_MAX_UFRAG_LENGTH];
    char                    passwd   [ ICE_MAX_PASSWD_LENGTH];
    ICE_CANDIDATE           candidate[ ICE_MAX_CANDIDATES];
    uint32_t                numberOfCandidates;
    ICE_TURN_STATE          turnState;
    uint32_t                userValue1;
    uint32_t                userValue2;
    struct sockaddr_storage defaultAddr;
    ICE_CANDIDATE_TYPE      defaultCandType;
} ICE_MEDIA_STREAM;
ICELIB_INSTANCE
ICELIB_Constructor
ICELIB_Destructor
ICELIB_Start
ICELIB_Stop
ICELIB_ReStart
ICELIB_Tick
ICELIB_setCallbackLog
ICELIB_addLocalMediaStream
ICELIB_setLocalMediaStream
ICELIB_getLocalMediaStream
ICELIB_addRemoteMediaStream
ICELIB_getRemoteMediaStream
ICELIB_setCallbackConnecitivityChecksComplete
ICELIB_setCallbackOutgoingBindingRequest
ICELIB_setCallbackOutgoingBindingResponse
ICELIB_setCallbackKeepAlive
ICELIB_doKeepAlive
ICELIB_addLocalCandidate
ICELIB_getActiveCandidate
ICELIB_getActiveRemoteCandidates
ICELIB_incomingBindingRequest
ICELIB_isIceComplete
ICELIB_isRunning
ICELIB_incomingBindingResponse
ICELIB_getRemoteComponentId
ICELIB_generateTransactionId
ICELIBTYPES_ICE_CANDIDATE_TYPE_toString
Frozen已经废弃不用了
ICELIB_setCallbackConnecitivityChecksComplete(m_iceInst, OnConnectivityChecksComplete, this);
    ICELIB_setCallbackOutgoingBindingRequest(m_iceInst, OnOutgoingBindingRequest, this);
    ICELIB_setCallbackOutgoingBindingResponse(m_iceInst, OutgoingBindingResponse, this);
static ICELIB_Result OnConnectivityChecksComplete(void *pUserData, uint32_t userValue1, bool isControlling, bool iceFailed);
    //onicecomplete, aReason
static ICELIB_Result OnOutgoingBindingRequest(void *pUserData, const struct sockaddr *destination,
            const struct sockaddr *source, uint32_t transport, uint32_t userValue1, uint32_t userValue2,
            uint32_t componentId, bool useRelay, const char *pUfragPair, const char *pPasswd,
            uint32_t peerPriority,  bool useCandidate, bool iceControlling, bool iceControlled,
            uint64_t tieBreaker, StunMsgId transactionId, const char *szFingerPrint);
    //start connectivity checking, a Request --->> a check.
static ICELIB_Result OutgoingBindingResponse(void *pUserData, uint32_t userValue1,
            uint32_t userValue2, uint32_t componentId, const struct sockaddr *source,
            const struct sockaddr *destination, const struct sockaddr *MappedAddress,
            uint16_t errorResponse, StunMsgId transactionId, bool useRelay, const char *pUfragPair,
            const char *pPasswd);
//有一个response回来可以做early media
conclude at last, select a transport
/*
    static ICELIB_Result OnSendKeepAlive(void *pUserData, uint32_t userValue1, uint32_t userValue2,
        uint32_t mediaIdx);
        */
ICE学习笔记 -- RFC 5245的更多相关文章
- ICE学习笔记一----运行官方的java版demo程序
		
建议新手和我一样,从官网下载英文文档,开个有道词典,慢慢啃. 官方文档下载: http://download.csdn.net/detail/xiong_mao_1/6300631 程序代码就不说了, ...
 - DTLS学习笔记 -- RFC 4347- 6347
		
想学习一下dtls,是因为想以后没有公司免费VPN可用的时候,我能买一个主机,自己建一个VPN. 1.介绍 Web, email大多用TLS协议来做安全的网络传输,它们必须跑在可靠的TCP传输通道里. ...
 - stun/turn/ice学习笔记
		
stun基本只是用于client探测NAT之后靠近stun server的外网地址,本身不包含应用数据通信的功能,其底层STUN协议通信多是基于UDP的.多个端点之间相互通过信令通道拿到彼此的NAT外 ...
 - SIP学习笔记 -- RFC 3261
		
1.SDP (rfc 4566) 1)用于交换参数 2)内容分三部分Session description, Time description and Media description ...
 - XMPP学习笔记 -- RFC 6120
		
XMPP - Extensible Messaging and Presence Protocol 1. 中文版3920 http://wiki.jabbercn.org/RFC3920 2. 大部分 ...
 - RTP/RTCP学习笔记 -- RFC 3550
		
The MTU of RTP package payload is (IP) - (UDP) - = 1472 #define DEFAULT_MAX_PACKET_SIZE 1200 video ...
 - [转]ICE介绍 (RFC 5245)
		
[转]ICE介绍 (RFC 5245) http://blog.csdn.net/dxpqxb/article/details/22040017 1关于ICE的10个事实 1 ICE使用STUN和TU ...
 - squid 学习笔记
		
Squid学习笔记 1.安装前的配置 编译安装之前需要校正的参数主要包括File Descriptor和Mbuf Clusters. 1.File Descriptor 查看文件描述符的限制数目: u ...
 - <老友记>学习笔记
		
这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...
 
随机推荐
- Drupal service module 介绍
			
https://www.ostraining.com/blog/drupal/services/ https://www.drupal.org/node/1246470 https://www.dru ...
 - git移除上一次的commit中误添加的文件
			
在使用git进行版本管理时,往往会出现一些误操作,比如将一些不加上传的文件放到了暂存区,即上传到了上一次commit中 比如: commit c134ab90ca7c4daf8bfa22e3ad706 ...
 - [CQOI2018] 社交网络
			
题目背景 当今社会,在社交网络上看朋友的消息已经成为许多人生活的一部分.通常,一个用户在社交网络上发布一条消息(例如微博.状态.Tweet等) 后,他的好友们也可以看见这条消息,并可能转发.转发的消息 ...
 - 从顺序随机I/O原理来讨论MYSQL MRR NLJ BNL BKA
			
http://blog.itpub.net/7728585/viewspace-2129502/
 - Attempt to invoke virtual method 'void android.app.ActionBar.setTitle的解决方法
			
在安卓4.4.2的关于蓝牙开发的一个sample BluetoothChat中,调试时,老是出错:Attempt to invoke virtual method 'void android.app. ...
 - 【spring cloud】spring cloud服务发现注解之@EnableDiscoveryClient与@EnableEurekaClient
			
spring cloud服务发现注解之@EnableDiscoveryClient与@EnableEurekaClient的区别
 - Mybatis原理分析一 从JDBC到Mybaits
			
1.引言 本文主要讲解JDBC怎么演变到Mybatis的渐变过程,重点讲解了为什么要将JDBC封装成Mybaits这样一个持久层框架.再而论述Mybatis作为一个数据持久层框架本身有待改进之处. 2 ...
 - ZooKeeper 授权验证
			
ZooKeeper 授权验证 学习了:https://blog.csdn.net/liuyuehu/article/details/52121755 zookeeper可以进行认证授权:
 - Android——动画的分类
			
Android包含三种动画:View Animation, Drawable Animation, Property Animation(Android 3.0新引入). 1.View Animati ...
 - Laravel建站04--建立后台文章管理
			
路由配置 Route::group(['middleware' => 'auth', 'namespace' => 'Admin', 'prefix' => 'admin'], fu ...