STUN协议详解

STUN协议详解STUN 是一种网络协议 它允许位于 NAT 或多重 NAT 后的客户端找出自己的公网地址 查出自己位于哪种类型的 NAT 之后以及 NAT 为某一个本地端口所绑定的 Internet 端端口 stun 协议

大家好,欢迎来到IT知识分享网。

STUN 支持两种类型的事务,分别是 REQUEST/RESPONSE 事务和 INDICATION 事务。STUN 本身并不是一种穿越解决方案,而只是协议,被 NAT 穿越的解决方案(比如 ICE 和 TURN)所使用。

STUN 协议能够帮助处于内网的终端确定 NAT 为其分配的外网 IP 地址和端口。

在 ICE 中,STUN 协议用于连通性检查(BINDING_REQUEST/RESPONSE)和 ICE 的保活(BINDING_INDICATION)。在 TURN 协议中,STUN 协议用于 Allocation 的建立,可以作为中继数据的载体(比如 sendindication 和 dataindication),ICE 和 TURN 是两种不同的 STUN 使用方式。

这里,我们暂时先讨论协议本身:

STUN协议详解

STUN 报文格式

STUN协议结构由20字节头和若干个属性组成,属性的个数可以为0,且统一是大端字节序的二进制序列。报文分为两部分:

  • 20字节的 STUN Header
  • Body,其中携带0或多个attribute

STUN Header

报文头一共20个字节,其中:

// STUN packet transaction id = 96 bits #define STUN_TRANSACTION_ID_LEN (UINT16) 12 // STUN Header typedef struct { UINT16 stunMessageType; // 14 bit UINT16 messageLength; // 16 bit UINT32 magicCookie; // 32 bit BYTE transactionId[STUN_TRANSACTION_ID_LEN]; // 96 bit } StunHeader, *PStunHeader;

STUN协议详解

Message Type

Message Type是主机字节序,比较重要:

STUN协议详解

1、BINDING/地址捆绑

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0001 | BINDING REQUEST | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0011 | BINDING INDICATION | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0101 | BINDING RESPONSE SUCCESS | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0111 | BINDING RESPONSE ERROR | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2、SHARED SECRET/共享私密

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0002 | SHARED SECRET REQUEST | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0102 | SHARED SECRET RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0112 | SHARED SECRET ERROR RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

3、ALLOCATE

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0003 | ALLOCATE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0103 | ALLOCATE SUCCESS RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0113 | ALLOCATE ERROR RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

4、REFRESH

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0004 | REFRESH | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0104 | REFRESH SUCCESS RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0114 | REFRESH ERROR RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

5、SEND

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0006 | SEND | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0106 | SEND INDICATION | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

6、DATA

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0007 | DATA | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0107 | DATA INDICATION | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

7、CREATE PERMISSION

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0008 | CREATE PERMISSION | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0108 | CREATE PERMISSION SUCCESS RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0118 | CREATE PERMISSION ERROR RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8、CHANNEL BIND/通道捆绑

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0009 | CHANNEL BIND REQUEST | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0109 | CHANNEL BIND SUCCESS RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0119 | CHANNEL BIND ERROR RESPONSE | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Message Length

这里的长度,指的是所有 STUN Attributes 的长度:

STUN协议详解

下面这段,就是 STUN Attributes:

STUN协议详解

Magic Cookie & Transaction ID

在传输中一般都认为 Cookie 是 Transaction ID 的一部分,故 Transaction ID 被认为是16字节内容。但是 Cookie 在 [RFC 3489] 或者 [RFC 5389] 中是固定数值0x2112A442

STUN协议详解

Transaction ID 是由请求一方产生,在回复时需要和请求时 Transaction ID 一样,同一请求使用相同的Transaction ID,但客户端需为新的事务选择新的Transaction ID。

STUN协议详解

STUN Attributes

属性是继在Header之后,以一个个排列的结构(STUN Attributes)组成:

STUN协议详解

其中,STUN Attributes 由 Attribute Header 和 Attribute Body 组成。其中 Attribute Header 包括了 Type 和 Length,长度固定为 4 字节。Attribute Body 长度不固定,由 Length 决定。

下面,解释一些比较重要的属性:

/ * STUN attribute types */ typedef enum { STUN_ATTRIBUTE_TYPE_MAPPED_ADDRESS = (UINT16)0x0001, STUN_ATTRIBUTE_TYPE_RESPONSE_ADDRESS = (UINT16)0x0002, STUN_ATTRIBUTE_TYPE_CHANGE_REQUEST = (UINT16)0x0003, STUN_ATTRIBUTE_TYPE_SOURCE_ADDRESS = (UINT16)0x0004, STUN_ATTRIBUTE_TYPE_CHANGED_ADDRESS = (UINT16)0x0005, STUN_ATTRIBUTE_TYPE_USERNAME = (UINT16)0x0006, STUN_ATTRIBUTE_TYPE_PASSWORD = (UINT16)0x0007, STUN_ATTRIBUTE_TYPE_MESSAGE_INTEGRITY = (UINT16)0x0008, STUN_ATTRIBUTE_TYPE_ERROR_CODE = (UINT16)0x0009, STUN_ATTRIBUTE_TYPE_UNKNOWN_ATTRIBUTES = (UINT16)0x000A, STUN_ATTRIBUTE_TYPE_REFLECTED_FROM = (UINT16)0x000B, STUN_ATTRIBUTE_TYPE_XOR_MAPPED_ADDRESS = (UINT16)0x0020, STUN_ATTRIBUTE_TYPE_PRIORITY = (UINT16)0x0024, STUN_ATTRIBUTE_TYPE_USE_CANDIDATE = (UINT16)0x0025, STUN_ATTRIBUTE_TYPE_FINGERPRINT = (UINT16)0x8028, STUN_ATTRIBUTE_TYPE_ICE_CONTROLLED = (UINT16)0x8029, STUN_ATTRIBUTE_TYPE_ICE_CONTROLLING = (UINT16)0x802A, STUN_ATTRIBUTE_TYPE_CHANNEL_NUMBER = (UINT16)0x000C, STUN_ATTRIBUTE_TYPE_LIFETIME = (UINT16)0x000D, STUN_ATTRIBUTE_TYPE_XOR_PEER_ADDRESS = (UINT16)0x0012, STUN_ATTRIBUTE_TYPE_DATA = (UINT16)0x0013, STUN_ATTRIBUTE_TYPE_REALM = (UINT16)0x0014, STUN_ATTRIBUTE_TYPE_NONCE = (UINT16)0x0015, STUN_ATTRIBUTE_TYPE_XOR_RELAYED_ADDRESS = (UINT16)0x0016, STUN_ATTRIBUTE_TYPE_EVEN_PORT = (UINT16)0x0018, STUN_ATTRIBUTE_TYPE_REQUESTED_TRANSPORT = (UINT16)0x0019, STUN_ATTRIBUTE_TYPE_DONT_FRAGMENT = (UINT16)0x001A, STUN_ATTRIBUTE_TYPE_RESERVATION_TOKEN = (UINT16)0x0022, } STUN_ATTRIBUTE_TYPE;

MAPPED-ADDRESS/映射地址

表示 “NAT客户端的反射地址”。其中,Family 标识协议族,包括 IPv4 和 IPv6。其中,IPv4 为 0x01,IPv6 为 0x02。需要注意的是,Port 和 Address 都是以网络序存在,本地查看时需要转换到主机序。

STUN协议详解

STUN协议详解

XOR-MAPPED-ADDRESS/亦或映射

与 MAPPED-ADDRESS 属性基本相同,区别在于反射地址经过一次异或(XOR)处理,异或运算是其自身的逆运算,客户端经过一次异或运算获得真实的反射地址。之所以这么做,目的就是解决ALG篡改地址和端口的问题。

STUN协议详解

STUN协议详解

USERNAME/用户名

用户名,用于消息完整性,识别在消息完整性检查中使用的用户名和密码组合。

STUN协议详解

MESSAGE-INTEGRITY/消息认证

STUN 消息的 HMAC-SHA1 值,长度 20 字节,用于消息完整性认证。

STUN协议详解

FINGERPRINT/指纹认证

FINGERPRINT 属性可以在所有的 STUN 消息中出现。该属性的值被计算为 STUN 消息的 CRC-32 值,与 32 位值 0xe 进行异或操作(这种异或操作有助于处理应用包也在其中使用 CRC-32 的情况)。

32 位 CRC 是 ITU V.42 [ITU.V42.2002] 中定义的,具有生成多项式 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1。当存在时,FINGERPRINT 属性必须是消息中的最后一个属性,因此会出现在 MESSAGE-INTEGRITY 之后。

FINGERPRINT 属性可以帮助区分 STUN 数据包与其他协议的数据包。与 MESSAGE-INTEGRITY 一样,FINGERPRINT 属性中使用的 CRC 也覆盖了 STUN 消息头的长度字段。因此,在计算 CRC 之前,此值必须正确,并将 CRC 属性作为消息长度的一部分包括在内。

在消息中使用 FINGERPRINT 属性时,首先将属性放入消息中并赋予虚拟值,然后计算 CRC,最后更新属性的值。如果 MESSAGE-INTEGRITY 属性也存在,则在计算 CRC 之前必须出现具有正确 message-integrity 值的 MESSAGE-INTEGRITY 属性,因为 CRC 也会对 MESSAGE-INTEGRITY 属性的值进行操作。

STUN协议详解

PRIORITY 和 USE-CANDIDATE

终端必须在其 request 中包含 PRIORITY 属性,指明其优先级,优先级由公式计算而得。如果有需要也可以给出特别指定的候选(即 USE-CANDIDATE 属性)

STUN协议详解

UNKNOWN-ATTRIBUTES/未知属性

此属性只会在错误代码为 420 的错误响应中出现

ICE-CONTROLLING 和 ICE-CONTROLLED

ICE流程中定义了两种角色:Controlling 和 Controlled。

不同的角色在 Candidate Pair 优先级的计算,Pair Nominate 决策上有所不同。一般流程下,会话的双发各自的角色选择是与会话协商的流程相关的,Offer端是 Controlling,Answer端是 Controlled。

STUN协议详解

ICE-CONTROLLED 或者是 ICE-CONTROLLING,这两个属性都会携带一个 Tie breaker 这样的字段,其中包含一个本机产生的随机值。收到该 Binding Request 的一方会检查这两个字段,如果和当前本机的 Role 冲突,则检查本机的 Tie breaker 值和消息中携带的 Tie breaker 值进行判定本机合适的 Role。

判定的方法为 Tie breaker 值大的一方为 Controlling。如果判定本端变更角色,这直接修改;如果判定对端变更角色,则对此 Binding Request 发送487错误响应,收到此错误响应的一方变更角色即可。

STUN协议详解

ERROR-CODE/错误码

属性用于 “error response” 报文中,其中包含了300-699表示的错误码,以及一个UTF-8格式的文字出错信息(Reason phrase)。

STUN协议详解

SOFTWARE

此属性用于代理发送消息时包含版本的描述,用于客户端和服务器。它的值包括制造商和版本号。该属性对于协议的运行没有任何影响,仅为诊断和调试目的提供服务。SOFTWARE属性是个可变长度的,采用UTF-8编码的小于128个字符的序列号。

STUN协议详解

ALTERNATE-SERVER

属性表示 STUN 客户可以尝试的不同的 STUN 服务器地址,属性格式与 MAPPED-ADDRESS 相同。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/110150.html

(0)
上一篇 2026-02-02 14:00
下一篇 2026-02-02 14:16

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信