Skip to content
Blog of ZheXin
Go back

STUN Protocol

Edit page

摘要

概述

并梳理 STUN 协议的编码格式,具体细节和错误处理请移步对应 RFC。

STUN 协议格式

packet
title STUN Message Header
+2: "0 0"
+14: "STUN Message Type"
+16: "Length"
+32: "Magic Cookie"
+96: "Transaction ID"

STUN Message Type

STUN Message Type 中包含 message class 和 message method。

14 位的 STUN Message Type 按大端序如下:

MMMMMCMMMCMMMM
1110987165403210

其中 M11 到 M0 定义了 message method,C1 到 C0 定义了 message class。

message class 有如下定义:

STUN 只定义了一个 message method: 0b000000000001 (Binding)。

Length

包含以字节为单位的消息大小,不包括 20 字节的 STUN 头。

由于所有 STUN attributes 都填充为 4 字节的倍数,因此该字段的最后 2 位始终为零。

Magic Cookie 为固定值:0x2112A442。

Transaction ID

Transaction ID 用于唯一标识 STUN 事务。对于请求/响应事务,Transaction ID 由 STUN 客户端为请求选择,并由服务器在响应中回显。

STUN Attributes 格式

packet
title STUN Attributes
+16: "Type"
+16: "Length"
+32: "Value (variable)"

Length

Length 表示 Value 填充前的长度,以字节为单位。

Value

Value 字段长度必须填充为 4 的倍数,填充位必须置零。

已注册的 Attribute

MAPPED-ADDRESS (0x0001)

packet
title MAPPED-ADDRESS Attribute
+8: "0 0 0 0 0 0 0 0"
+8: "Family"
+16: "Port"
+32: "Address (32 bits or 128 bits)"

Family 有以下定义:

XOR-MAPPED-ADDRESS (0x0020)

packet
title MAPPED-ADDRESS Attribute
+8: "0 0 0 0 0 0 0 0"
+8: "Family"
+16: "X-Port"
+32: "X-Address (32 bits or 128 bits)"

X-Port:使用 Port 与 magic cookie 的最高 16 位做异或运算得到。

X-Address:如果是 IPv4,是与 magic cookie 做异或运算得到;如果是 IPv6,是与 magic cookie 和 transaction ID 做异或运算得到。

USERNAME (0x0006)

以 UFT-8 编码的文本。

USERHASH (0x001E)

当支持用户名匿名性时,USERHASH 属性用作 USERNAME 属性的替换。

USERHASH 的值具有 32 字节的固定长度。

使用 userhash = SHA-256(OpaqueString(username) ":" OpaqueString(realm)) 得到哈希值。

MESSAGE-INTEGRITY (0x0008)

MESSAGE-INTEGRITY 属性包含 STUN message 的 HMAC-SHA1。HMAC 将是 20 个字节。

用作 HMAC 输入的文本是 STUN message,最多包括 MESSAGE-INTEGRITY 属性前面的属性。STUN 消息头的长度字段被调整为指向 MESSAGE-INTEGRITY 属性的末尾。执行计算后,将填充 MESSAGE-INTEGRITY 属性的值,并将 STUN 头中的长度值设置为其正确的值——整个 STUN message 的长度。

MESSAGE-INTEGRITY-SHA256 (0x001C)

MESSAGE-INTEGRITY-SHA256 属性包含 STUN message 的 HMAC-SHA-256 的初始部分。该值最多为 32 字节,但必须至少为 16 字节,并且必须是 4 字节的倍数。

用作 HMAC 输入的文本是 STUN message,最多包括 MESSAGE-INTEGRITY-SHA256 属性前面的属性。STUN 消息头的长度字段被调整为指向 MESSAGE-INTEGRITY-SHA256 属性的末尾。执行计算后,将填充 MESSAGE-INTEGRITY-SHA256 属性的值,并将 STUN 头中的长度值设置为其正确的值——整个 STUN message 的长度。

FINGERPRINT (0x8028)

STUN message 的 CRC-32,最多(但不包括)指纹属性本身,与 32 位值 0x5354554e 异或。

当存在时,FINGERPRINT 属性必须是消息中的最后一个属性,因此将出现在 MESSAGE-INTEGRITY 和 MESSAGE-INTEGRITY-SHA256 之后。

ERROR-CODE (0x0009)

ERROR-CODE 属性用于 error response 消息中。它包含一个介于 300 到 699 之间的数字错误代码值,外加一个以 UTF-8 编码的文本原因短语。

packet
title ERROR-CODE Attribute
+20: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
+3: "Class"
+9: "Number"
+32: "Reason Phrase (variable)"

Class 表示 ERROR-CODE 的百位数,值介于 3-6 之间。

Number 表示 ERROR-CODE 的后两位数,值介于 0-99 之间。

REALM (0x0014)

以 UFT-8 编码的文本。

NONCE (0x0015)

NONCE 属性必须少于 128 个字符。

PASSWORD-ALGORITHMS (0x8002)

该属性包含算法编号和可变长度参数的列表。算法编号为 16 位值。参数以参数的长度(填充之前)作为 16 位值开始,然后是特定于每个算法的参数。参数填充到 32 位边界,方式与属性相同。

packet
title PASSWORD-ALGORITHMS Attribute
+16: "Algorithm 1"
+16: "Algorithm 1 Parameters Length"
+32: "Algorithm 1 Parameters (variable)"
+16: "Algorithm 2"
+16: "Algorithm 2 Parameters Length"
+32: "Algorithm 2 Parameters (variable)"

已注册的 Algorithm:

PASSWORD-ALGORITHM (0x001D)

PASSWORD-ALGORITHM 属性仅在 request 中存在。

packet
title PASSWORD-ALGORITHM Attribute
+16: "Algorithm"
+16: "Algorithm Parameters Length"
+32: "Algorithm Parameters (variable)"

UNKNOWN-ATTRIBUTES (0x000A)

当错误代码属性中的响应代码为 420(未知属性)时,UNKNOWN-ATTRIBUTES 仅出现在错误响应中。

该属性包含一个 16 位值的列表,每个值表示服务器无法理解的属性类型。

packet
title UNKNOWN-ATTRIBUTES Attribute
+16: "Attribute 1 Type"
+16: "Attribute 2 Type"
+16: "Attribute 3 Type"
+16: "Attribute 4 Type"

SOFTWARE (0x8022)

以 UFT-8 编码的文本,用处类似 HTTP 中的 User-Agent。

ALTERNATE-SERVER (0x8023)

备用服务器表示备用传输地址,该地址标识 STUN 客户端应尝试的其他 STUN 服务器。

编码方式与 MAPPED-ADDRESS 相同。

ALTERNATE-DOMAIN (0x8003)

备用域表示当传输协议使用 TLS 或 DTL 时,用于验证备用服务器属性中的 IP 地址的域名。

它必须是 255 个或更少 ASCII 字符的有效 DNS 名称。


Edit page
Share this post:

Previous Post
TURN Protocol
Next Post
Try Typebox