STUN/TURN/ICE

RFC 5389 - Session Traversal Utilities for NAT (STUN)

https://www.cnblogs.com/pannengzhi/p/5041546.html

https://www.cnblogs.com/pannengzhi/p/5048965.html

STUN : Session Traversal Utilities for NAT, 一个协助穿越NAT的工具,运行在UDP和TCP之上。

NAT(Network Address Translation)

STUN by itself is not a solution to the NAT traversal problem. Rather, STUN defines a tool that can be used inside a larger solution. 

STUN 作用:位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于 NAT路由器之后的主机之间建立UDP通信。同时可以检测端点间的连接性,也可以作为一种保活(keep-alive)协议来维持NAT的绑定。

STUN is a client-server protocol.

 

It supports two types of transactions. 

request/response transaction (请求/响应):  a  client sends a request to a server, and the server returns a  response.

indication transaction(指示): either  agent -- client or server -- sends an indication that generates no response.

 

消息格式:(采用大端编码(big-endian),即最高有效位在左边)

STUN消息头:20字节

All STUN messages start with a fixed header that includes a method, a  class, and the transaction ID.

1)最高的2位必须置零,这可以在当STUN和其他协议复用端口的时候,用来区分STUN包和其他数据包。

2)STUN Message Type:

Method (方法): 如 Binding

Class(类别):如 a request  / a success response / an error response /  an indication

3)Message Length:不包括20字节头的STUN消息长度

4)Magic Cookie: 固定为RFC 3489 0x2112A442,这是为了前向兼容classic STUN,因为在classic STUN(RFC 3489 )中,这一区域是Transaction ID的一部分。

5)Transaction ID(事务ID):a randomly selected 96-bit number  

对于request/response传输,Transaction ID由客户端选择,服务器收到后以同样的Transaction ID返回response;

对于indication则由发送方自行选择。

Transaction ID的主要功能是把request和response联系起来,同时也在防止攻击方面有一定作用。服务端也把Transaction ID当作一个Key来识别不同的STUN客户端,因此必须格式化且随机在0~2^(96-1)之间。

重发同样的request请求时可以重用相同的Transaction ID,但是客户端进行新的传输时,必须选择一个新的Transaction ID。

  

STUN消息体:0个或者多个TLV属性

Following the fixed header comes zero or more attributes, which are Type-Length-Value extensions that convey additional information for the specific message.(紧跟固定头部的是0个或者多个TLV属性)

其中Type字段和Length字段占用16位,Value字段为32位表示(STUN属性以32bit边界对齐),即属性内容不足4字节的都会以padding bit进行补齐。

Length:不包含补齐(padding bit)的Value长度,以字节为单位。

Type:字为属性的类型。任何属性类型都有可能在一个STUN报文中出现超过一次。除非特殊指定,否则其出现的顺序是有意义的:即只有第一次出现的属性会被接收端解析,而其余的将被忽略。

属性区域被分为两个部分:

Type值在0x0000-0x7FFF之间的属性被指定为强制理解,意思是STUN终端必须要理解此属性,否则将返回错误信息;

而0x8000-0xFFFF之间的属性为选择性理解,即如果STUN终端不识别此属性则将其忽略。

常见的属性:

FINGERPRINT:CRC校验。放在属性列表的最后,即若存在的话应当是最后一个属性。多个协议复用一个端口时,可以用来区分是否是STUN消息。

Wireshark抓包示例:

 

TURN: 在STUN的基础上增加relay功能。在有些情况下,有可能终端无法和其对等端(peer)进行直接的通信,这时就需要公网的服务器作为一个中继,对来往的数据进行转发。这个转发的协议就被定义为TURN。

ICE状态

The RTCIceConnectionState enum defines the string constants used to describe the current state of the ICE agent and its connection to the ICE server (that is, the STUN or TURN server).

Constant

Description

"new"

The ICE agent is gathering addresses or is waiting to be given remote candidates through calls to RTCPeerConnection.addIceCandidate() (or both).

"checking"

The ICE agent has been given one or more remote candidates and is checking pairs of local and remote candidates against one another to try to find a compatible match, but has not yet found a pair which will allow the peer connection to be made. It's possible that gathering of candidates is also still underway.

"connected"

A usable pairing of local and remote candidates has been found for all components of the connection, and the connection has been established. It's possible that gathering is still underway, and it's also possible that the ICE agent is still checking candidates against one another looking for a better connection to use.

"completed"

The ICE agent has finished gathering candidates, has checked all pairs against one another, and has found a connection for all components.

"failed"

The ICE candidate has checked all candidates pairs against one another and has failed to find compatible matches for all components of the connection. It is, however, possible that the ICE agent did find compatible connections for some components.

"disconnected"

Checks to ensure that components are still connected failed for at least one component of the RTCPeerConnection. This is a less stringent test than "failed" and may trigger intermittently and resolve just as spontaneously on less reliable networks, or during temporary disconnections. When the problem resolves, the connection may return to the "connected" state.

"closed"

The ICE agent for this RTCPeerConnection has shut down and is no longer handling requests.

一旦收到ICE候选者,我们应该期望对等连接的状态最终将变为已连接状态。为了检测到这一点,我们在RTCPeerConnection中添加了一个侦听器,在此我们侦听connectionstatechange事件。

// Listen for connectionstatechange on the local RTCPeerConnection

peerConnection.addEventListener('connectionstatechange', event => {

    if (peerConnection.connectionState === 'connected') {

        // Peers connected!

    }

});

猜你喜欢

转载自blog.csdn.net/luyumiao1990/article/details/131756062
今日推荐