文章目錄
和STUN協議相關的文檔一共有三個:RFC 3489,RFC 5389和RFC 5780
引用
Message Header
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| STUN Message Type | Message Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Transaction ID
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
STUN消息主要分爲兩種:
- Header說明
類型 | 說明 |
---|---|
STUN Message Type | STUN類型 |
Message Lenght | 去除固定頭部(20Byte)的剩餘的長度 |
Transaction ID | 一個128位的標識符,客戶端隨機生成的,然後服務端要回復相同的標識符 |
- STUN Message Type說明
MessageType值 | 類型 |
---|---|
0x0001 | Binding Request |
0x0101 | Binding Response |
0x0111 | Binding Error Response |
Message Attributes
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 ....
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
一個STUN消息可以包含0個或者多個STUN屬性,屬性有一個通用的頭部,如上。
- Message Attributes說明
類型 | 說明 |
---|---|
Type | 一個uint16長度的類型,用不同的值區分不同的屬性 |
Lenght | 表示Value的長度,不包括固定頭部的大小(4Byte) |
Value | 不固定長度,表示屬性的內容 |
- Type說明
值 | 類型 |
---|---|
0x0001 | MAPPED-ADDRESS |
0x0002 | RESPONSE-ADDRESS |
0x0003 | CHANGE-REQUEST |
0x0004 | SOURCE-ADDRESS |
0x0005 | CHANGED-ADDRESS |
0x0006 | USERNAME |
0x0007 | PASSWORD |
0x0008 | MESSAGE-INTEGRITY |
0x0009 | ERROR-CODE |
0x000a | UNKNOWN-ATTRIBUTES |
0x000b | REFLECTED-FROM |
0x802b | RESPONSE-ORIGIN |
0x802c | OTHER-ADDRESS |
MAPPED-ADDRESS
用於表示客戶端外部IP地址,如果沒有NAT,那麼外部IP地址和內部IP地址是相同的。前8位保留,之後8位用於表示IP類型(IPV4/6)。之後16位表示端口號。這裏強制使用IPV4版本,所以Address是32位。
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|x x x x x x x x| Family | Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RESPONSE_ADDRESS
用於標示哪一個服務端的IP和Port發送發送的數據。數據格式參考MAPPED-ADDRESS
。
CHANGE-REQUEST
請求服務端使用不同的IP或者Port來給客戶端發送消息。A表示“改變IP”標誌,B表示“改變端口”標誌。
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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A B 0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0 |Class| Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reason Phrase (variable) ..
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ERROR-CODE說明
類型 | 說明 |
---|---|
Class | 用於存儲100的倍數,這個值只能是1~6 |
Number | 100的餘數,值的範圍是0~99,Error Code的計算是:Class * 100 + Number |
Reason Phrase | ByteString類型,用於描述錯誤信息 |
- Error Code說明
Error Code | 說明 |
---|---|
400 | 請求格式不正確 |
401 | 請求消息不包含MESSAGE-INTEGRITY 屬性 |
420 | 服務器不理解請求中的強制屬性 |
430 | 請求消息包含MESSAGE-INTEGRITY 屬性,但是卻使用了一個過期的共享密鑰 |
431 | 請求消息包含MESSAGE-INTEGRITY 屬性,但是HMAC校驗失敗。 |
500 | 服務器遇到了一個臨時錯誤。客戶端應該重試 |
600 | 服務器拒絕滿足該請求。 客戶端不應重試 |
RESPONSE-ORIGIN
用於標示哪一個服務端的IP和Port發送的數據。數據格式參考MAPPED-ADDRESS
。
OTHER-ADDRESS
用於標示服務端另一個IP和Port發送的數據。數據格式參考MAPPED-ADDRESS
。
RFC3478 VS RFC5780
RFC3478和RFC5780主要區別在於:NAT類型和探測方式。RFC5780細化NAT類型,採用新的探測方式,爲了新類型和新探測方式新增了幾種對應的屬性。
RFC3478 NAT類型定義
RFC3478 NAT Variations中定義了四種NAT類型:Full cone、Restricted cone、Port-Restricted cone和Symmetric。
完全圓錐形NAT(Full cone NAT)
- 一旦一個內部地址(iAddr:port)映射到外部地址(eAddr:port),所有發自iAddr:port的包都經由eAddr:port向外發送。任意外部主機都能通過給eAddr:port發包到達iAddr:port(注:port不需要一樣)
受限圓錐形NAT(Address-Restricted cone NAT)
- 內部客戶端必須首先發送數據包到對方(IP=X.X.X.X),然後才能接收來自X.X.X.X的數據包。在限制方面,唯一的要求是數據包是來自X.X.X.X。
- 內部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有發自iAddr:port1的包都經由eAddr:port2向外發送。外部主機(hostAddr:any)能通過給eAddr:port2發包到達iAddr:port1。(注:any指外部主機源端口不受限制,但是目的端口必須是port2。只有外部主機數據包的目的IP 爲 內部客戶端的所映射的外部ip,且目的端口爲port2時數據包才被放行。
端口受限圓錐形NAT(Port-Restricted cone NAT)
類似受限制錐形NAT(Restricted cone NAT),但是還有端口限制。
- 一旦一個內部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有發自iAddr:port1的包都經由eAddr:port2向外發送。
- 在受限圓錐型NAT基礎上增加了外部主機源端口必須是固定的。
對稱NAT(Symmetric NAT)
- 每一個來自相同內部IP與端口,到一個特定目的地地址和端口的請求,都映射到一個獨特的外部IP地址和端口。同一內部IP與端口發到不同的目的地和端口的信息包,都使用不同的映射
- 只有曾經收到過內部主機數據的外部主機,才能夠把數據包發回
RFC5780 NAT類型
RFC5780 NAT類型主要分爲兩類:地址和端口隱射,地址和端口過濾。
Full cone
Restricted cone
Port-Restricted cone
Symmetric
下圖顯示了RFC 5780中定義的九種NAT類型和RFC 3489中定義的四種NAT類型,以及RFC 3489中的NAT類型如何與RFC 5780中的對應類型匹配。
RFC3478 探測算法
RFC3478 Binding Lifetime Discovery
一旦路經通過紅色箱子的終點時,UDP的溝通是沒有可能性的。一旦通過黃色或是綠色的箱子,就有連線的可能。
RFC5780 探測算法
RFC5780探測分爲兩種方式:NAT隱射和NAT過濾。