STUN(Session Traversal Utilities for NAT)协议是一个用于处理穿透NAT的协议工具,定义在RFC3489(已废弃),RFC5389,RFC8489。
1. STUN消息格式
所有的STUN消息都有一个20字节的头,后面跟着0个或者多个属性。
1.1 STUN消息头
定义在RFC5389 / RFC8489
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0| STUN Message Type | Message Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic Cookie |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Transaction ID (96 bits) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 2: Format of STUN Message Header
- 最前 2bit 为 0 , 用于与其他协议做区分
- STUN Message Type: STUN 消息类型,定义了消息 class 和消息 method,STUN Message Type的结构如下
0 1
2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 3: Format of STUN Message Type Field
其中C0 和 C1 合起来定义 class,M0-M11定义了 method, method只定义了一个方法,即Binding,0b000000000001 (0x0001); class 四个值都有定义,如下表
| C1C0的值 | 定义 |
|---|---|
| 0b00 | request |
| 0b01 | indication |
| 0b10 | success response |
| 0b11 | error response |
因此Binding的request的消息类型为 0x0001, Binding的success response的消息类型为 0x0101。
- Message Length,消息长度,不包含消息头的长度值
- Magic Cookie,固定值 0x2112A442,用于区分STUN协议是否是RFC5389的版本,RFC3489没有这么定义这个值
- Transaction ID, 96bit事务ID,请求端发送消息时定义这个字段的值,应答端原封不动带回来这个值,用于请求端关联时哪一个请求的应答
1.2 STUN消息体或者属性
20字节的STUN消息头之后是0个或者多个属性。每个属性的长度不固定,但都是 4 字节的整数倍
属性的结构如下
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Value (variable) ....
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 4: Format of STUN Attributes
- Type: 16字节属性类型
- Length: 属性长度,Value的长度,单位是字节,必须是 4 字节的整数倍
- Value: 属性的数据,网络字节序
属性定义表
| Type | 属性名 | 含义 | 备注 |
|---|---|---|---|
| 0x0001 | MAPPED-ADDRESS | NAT客户端的反射地址,即在server端看到NAT后客户端的地址,只用于兼容RFC3489的 STUN 客户端 | 格式见 1.2.1 |
| 0x0006 | USERNAME | USERNAME属性用于message integrity。它标识消息完整性检查中使用的用户名和密码组合。USERNAME的值是可变长度的值。它必须包含少于513字节的utf-8[RFC3629]编码序列,并且必须使用SASLprep [RFC4013]进行过处理。 | |
| 0x0008 | MESSAGE-INTEGRITY | MESSAGE-INTEGRITY(消息完整性)属性包含STUN消息的HMAC-SHA1 [RFC2104]。由于它使用SHA1哈希,HMAC将是20字节。 | |
| 0x0009 | ERROR-CODE | ERROR-CODE属性用于错误响应消息。它包含一个300到699范围内的数字错误代码值,加上一个以UTF-8 [RFC3629],编码的文本短语。 | 格式见 1.2.3 |
| 0x000A | UNKNOWN-ATTRIBUTES | UNKNOWN-ATTRIBUTES仅出现在当ERROR-CODE属性为 420 得错误应答中 | |
| 0x0014 | REALM | REALM属性可以出现在请求和响应中。它包含符合RFC 3261中描述的"realm-value"语法的文本,但没有双引号及其周围的空白。必须是少于128个字符(可长达763字节)的UTF-8 [RFC3629]编码序列,并且必须已经使用SASLprep [RFC4013] 进行了处理。消息中出现REALM字段表示身份认证使用长期凭据方式。 | |
| 0x0015 | NONCE | NONCE属性可以出现在请求和响应中。它必须少于128个字符(可以长达763个字节)。 | |
| 0x001C | MESSAGE-INTEGRITY-SHA256 | ||
| 0x001D | PASSWORD-ALGORITHM | ||
| 0x001E | USERHASH | ||
| 0x0020 | XOR-MAPPED-ADDRESS | NAT客户端的反射地址,即在server端看到NAT后客户端的地址,意义和 MAPPED-ADDRESS 一样,只是地址值经过了异或计算 | 格式见 1.2.2 |
| 0x0024 | PRIORITY | RFC 8445 ICE 扩展定义 | |
| 0x0025 | USE-CANDIDATE | RFC 8445 ICE 扩展定义 | |
| 0x8002 | PASSWORD-ALGORITHMS | ||
| 0x8003 | ALTERNATE-DOMAIN | ||
| 0x8022 | SOFTWARE | ||
| 0x8023 | ALTERNATE-SERVER | ||
| 0x8028 | FINGERPRINT | FINGERPRINT(指纹)属性可以出现在所有STUN消息中。属性的值被计算为STUN消息的CRC-32,直到(但不包括) FINGERPRINT属性本,与32位值0x5354554e进行异或运算。当FINGERPRINT属性存在时,它必须是消息中的最后一个属性,因此将出现在MESSAGE-INTEGRITY之后。 | |
| 0x8029 | ICE-CONTROLLED | RFC 8445 ICE 扩展定义 | |
| 0x802A | ICE-CONTROLLING | RFC 8445 ICE 扩展定义 |
1.2.1 MAPPED-ADDRESS
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 0 0 0 0 0| Family | Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Address (32 bits or 128 bits) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 5: Format of MAPPED-ADDRESS Attribute
- 前 8bit 必须为 0
- Family 表示 address family,0x01 - IPv4, 0x02 - IPv6
- Port: 2字节的映射端口号,网络字节序
- Address : 如果Family=0x01 表示32bit IPv4地址;Family=0x02 表示128bit IPv6地址;网络字节序
1.2.2 XOR-MAPPED-ADDRESS
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 0 0 0 0 0| Family | X-Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| X-Address (32 bits or 128 bits) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 6: Format of XOR-MAPPED-ADDRESS Attribute
- 前 8bit 必须为 0
- Family 表示 address family,0x01 - IPv4, 0x02 - IPv6
- X-Port: 2字节的映射端口号与magic cookie高16位异或后的结果,先主机字节序计算,最后转网络字节序
- X-Address : 如果Family=0x01 表示32bit IPv4地址与magic cookie异或后的结果;Family=0x02 表示128bit IPv6地址与(magic cookie + 96bit Transaction ID) 异或后的结果;先主机字节序计算,最后转网络字节序
1.2.3 ERROR-CODE
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved, should be 0 |Class| Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reason Phrase (variable) ..
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 7: Format of ERROR-CODE Attribute

浙公网安备 33010602011771号