NAT(Network Address Translation)的相關術語及作用在這裡不再贅述,網友如果需要可以參考文獻:Peer-to-Peer Communication Across Network Address Translators。
原文地址:http://www.bford.info/pub/net/p2pnat
中文翻譯(翻譯後名為:穿越NAT的P2P通訊方法的研究):http://www.ppcn.net/n4690c38.aspx
(註:中文資料翻譯了原文的四章內容,翻譯的很好,在此對這位同僚的辛勤工作表示由衷的感謝)
(另外還必須說明的一點是:本文是我在學習《P2P的NAT研究》時寫的,可以說是它的另一個版本,這樣做僅僅為了加深自己對該技術的理解,做一個摘記,無意冒犯)
一 NAT的類型
NAT可以分為很多種,但是最為普遍的是傳統NAT,或者稱為向外NAT。向外NAT在預設情況下只允許向外的Session穿越NAT,這就是我們最為常見的情況。
這種向外NAT又可以分為基本NAT(Basic NAT)和NAPT(Network Address/Port Translation)。
1. 基本NAT
基本NAT只轉換IP地址,而不轉換連接埠。一個基本NAT往往需要具有多個公網IP來滿足多個內網節點中具有相同連接埠的應用程式的同時訪問。由於這種類型的NAT裝置限制大,現在已不常見。
2. NAPT
(註:Endpoint表示一個IP地址和連接埠對)
與基本NAT只轉換IP地址不同,NAPT轉換整個Endpoint。由於NAPT允許內網內的多個節點通過共用的方式使用同一個IP地址,因此,如今NAPT類型的NAT裝置已經越來越多。
NAPT又可以進一步分為以下四種類型:
(1) 完全錐型NAT(FULL CONE NAT)
完全錐型NAT在內網使用者A(Private Endpoint)首次向外部主機發送資料包時建立地址映射會話,並為A分配一個公網地址和連接埠(Public Endpoint),以後任何A向外部發送的資料都將使用這個Public Endpoint。此後,任何外部主機想要與A通訊,只要將資料包發送到Public Endpoint上,A就能夠順利的進行接收。
(2) 限制錐型NAT (RESTRICT CONE NAT)
限制錐型NAT在內網使用者A(Private Endpoint)首次向外部主機發送資料包時建立地址映射會話,並為A分配一個公網地址和連接埠(Public Endpoint),以後任何A向外部發送的資料包都將使用這個Public Endpoint。此後,如果某個外部主機(Endpoint IP:PORT)想要與A通訊,只要將資料包發送到Public Endpoint並且保證A曾用當前與NAT的會話向該外部主機的IP地址發送過資料,A就能夠正常收到外部主機(Endpoint IP:PORT)發送來的資料包。
(3) 連接埠限制錐型NAT(PORT RESTRICT CONE NAT)
連接埠限制錐型在內網使用者A(Private Endpoint)首次向外部主機發送資料包時建立地址映射會話,並為A分配一個公網地址和連接埠(Public Endpoint),以後任何A向外部發送的資料都將使用這個Public Endpoint。此後,如果某個外部主機(Endpoint IP:PORT)想要與A通訊,只要將資料包發送到Public Endpoint並且保證A曾用當前與NAT的會話向該外部主機的Endpoint發送過資料,A就能夠正常收到外部主機(Endpoint IP:PORT)發送來的資料包。
(4) 對稱型NAT(SYMMETRIC NAT)
對稱型NAT是一種比較特殊的NAT。內網使用者A(Private Endpoint)首次向外部主機S1發送資料包時建立地址映射會話Session1,並為A分配一個公網地址和連接埠(Public Endpoint1),以後A所有發向S1的資料包都使用這個Public Endpoint1。如果之後A用同一個Socket向外部主機S2發送資料包,這時對稱型NAT又為其分配一個地址映射會話,並為A分配一個新的公網地址和連接埠對(Public Endpoint2),以後A所有發向S2的資料包都使用這個Public Endpoint2。對稱型NAT規定Public Endpoint1和Public Endpoint2一定不相同。此外,如果任何外部主機想要發送資料給A,那麼它首先應該收到A發給他的資料,然後才能往回傳送,否則即使他知道內網主機的Public Endpoint也不能發送資料給A。這種NAT可以通過連接埠猜測等方法進行穿透,但是效果並不是很好,很難實現UDP-P2P通訊。
圖1 NAT 類型結構圖
二 NAT類型的檢測
前提條件:一個提供兩個公網地址(通訊地址分別設為:Endpoint1與Endpoint2)的伺服器S進行UDP連接埠資料監聽並根據客戶的要求給出響應;待檢測的使用者可以正常進行UDP通訊。
步驟1. 檢測主機是否位於NAT後
為了檢測IP地址是不是公網地址,主機A首先發送任意一個UDP資料包給伺服器S(Endpoint1),S收到包之後,用Endpoint1將接收到資料包頭的IP地址和連接埠打成一個UDP反饋包發送給使用者A。A在收到反饋包之後,比較自身的Endpoint和反饋包中的Endpoint,如果一樣則說明A不位於任何NAT之後,否則,就是位於NAT之後,這裡並不能判斷NAT的具體屬於哪一種類型。
步驟2. 檢測NAT是否是完全錐型
為了檢測所處的NAT是否是完全錐型的,主機A向伺服器S(Endpoint1)發送UDP資料包後,伺服器用Endpoint2將接收到資料包頭的IP地址和連接埠打成一個UDP反饋包發送給使用者A。另外,A在發送UDP資料包後,立即開始連接埠偵聽,設定一個等待時間上限,防止無限堵塞(因為接收是一個While迴圈)。這樣進行若干次,如果A每次都沒有收到資料包,說明A所處的NAT類型不是完全錐型的;相反,在這整個過程中只要收到一次服務的包,就說明A所處的NAT類型是完全限制型的。
步驟3. 檢測NAT是否是對稱型
為了檢測所處的NAT是否是對稱型的,主機A向伺服器S(Endpoint1)發送UDP資料包,伺服器S(Endpoint1)在收到資料包後,用Endpoint1將接收到資料包頭的IP地址和連接埠打成一個UDP反饋包發送給使用者A。另外,A在發送資料包後,開始偵聽連接埠並接收資料,設定一個等待時間上限,防止無限堵塞(因為接收是一個While迴圈)。與此同時,主機A用同一個通訊端向伺服器S (Endpoint2)發送UDP資料,Endpoint2發送與上面類似的UDP回饋包。在A的整個資料接收過程中,如果收到的伺服器反饋資料包中標識自身的IP地址和連接埠存在不相同的情況,就說明NAT是對稱型的,否則就不是。
步驟4. 檢測NAT是限制錐型的還是連接埠限制錐型
最後,為了檢測所處的NAT是限制錐型的還是連接埠限制錐型的,主機A向服務S的Endpoint1發送UDP資料包,伺服器用與Endpoint1相同的IP地址和不同的端號將帶有A的Public Endpoint的UDP反饋包發送給A。另外,A在發送資料包後,立即偵聽連接埠和並進行資料接收,設定一個等待時間上限,防止無限堵塞(因為接收是一個While迴圈)。重複若干次。如過在整個過程中,使用者A收到S發來的資料包,就說明NAT是限制型的;否則就說明NAT是連接埠限制型的。