STUN協議解析


和STUN協議相關的文檔一共有三個:RFC 3489RFC 5389RFC 5780

引用

  1. nat-behavior-discovery-using-stun-rfc-5780
  2. stun-rfc-3489-vs-stun-rfc-5389-5780
  3. 網絡地址轉換
  4. STUN

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過濾。

NAT隱射方式探測

在這裏插入圖片描述

沒有NAT

在這裏插入圖片描述

端點無關的隱射NAT

在這裏插入圖片描述

地址相關的隱射NAT

在這裏插入圖片描述

地址和端口相關的隱射NAT

在這裏插入圖片描述

NAT過濾方式探測

在這裏插入圖片描述

端點無關的過濾NAT

在這裏插入圖片描述

地址相關的過濾NAT

在這裏插入圖片描述

地址和端口相關的過濾NAT

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章