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是端口限制型的。