NAT(The IP Network Address Translator) 的概念和意義是什麼?html
NAT, 中文翻譯爲網絡地址轉換。具體的詳細信息能夠訪問RFC 1631 - http://www.faqs.org/rfcs/rfc1631.html, 這是對於NAT的定義和解釋的最權威的描述。網絡術語都是很抽象和艱澀的,除非是專業人士,不然很難從字面中來準確理解NAT的含義。數據庫
要想徹底明白NAT 的做用,咱們必須理解IP地址的兩大分類,一類是私有IP地址,在這裏咱們稱做內網IP地址。一類是非私有的IP地址,在這裏咱們稱做公網IP地址。關於IP地址的概念和做用的介紹參見個人另外一篇文章: http://hwycheng.blogchina.com/2402121.html服務器
內網IP地址: 是指使用A/B/C類中的私有地址, 分配的IP地址在全球不懼有惟一性,也所以沒法被其它外網主機直接訪問。
公網IP地址: 是指具備全球惟一的IP地址,可以直接被其它主機訪問的。網絡
NAT 最初的目的是爲使用內網IP地址的計算機提供經過少數幾臺具備公網的IP地址的計算機訪問外部網絡的功能。NAT 負責將某些內網IP地址的計算機向外部網絡發出的IP數據包的源IP地址轉換爲NAT本身的公網的IP地址,目的IP地址不變, 並將IP數據包轉發給路由器,最終到達外部的計算機。同時負責將外部的計算機返回的IP數據包的目的IP地址轉換爲內網的IP地址,源IP地址不變,並最終送達到內網中的計算機。
---------------------- ----------------------
| 192.168.0.5 | Internat host | 192.168.0.6 | Internat host
---------------------- ----------------------
^ port:2809 ^port: 1827
| |
V V
---------------------- ----------------------
| 192.168.0.1 | NAT device | 192.168.0.2 | NAT device
| 61.51.99.86 | | 61.51.77.66 |
---------------------- ----------------------
^ ^
| |
V port:80 V port: 80
---------------------- ----------------------
| 61.51.202.88 | Internet host | 61.51.76.102 | Internet host
---------------------- ----------------------
圖一: NAT 實現了私有IP的計算機分享幾個公網IP地址訪問Internet的功能。
隨着網絡的普及,IPv4的侷限性暴露出來。公網IP地址成爲一種稀缺的資源,此時NAT 的功能侷限也暴露出來,同一個公網的IP地址,某個時間只能由一臺私有IP地址的計算機使用。因而NAPT(The IP Network Address/Port Translator)應運而生,NAPT實現了多臺私有IP地址的計算機能夠同時經過一個公網IP地址來訪問Internet的功能。這在很大程度上暫時緩解了IPv4地址資源的緊張。數據結構
NAPT 負責將某些內網IP地址的計算機向外部網絡發出的TCP/UDP數據包的源IP地址轉換爲NAPT本身的公網的IP地址,源端口轉爲NAPT本身的一個端口。目的IP地址和端口不變, 並將IP數據包發給路由器,最終到達外部的計算機。同時負責將外部的計算機返回的IP數據包的目的IP地址轉換內網的IP地址,目的端口轉爲內網計算機的端口,源IP地址和源端口不變,並最終送達到內網中的計算機。架構
---------------------- ----------------------
| 192.168.0.5 | Internat host | 192.168.0.6 | Internat host
---------------------- ----------------------
port: 2809 ^ ^ port: 1827
/ /
v v
----------------------
| 192.168.0.1 | NAT device
| 61.51.99.86 |
----------------------
map port:9882 to 192.168.0.5:2809 ^ ^ map port: 9881 to 192.168.0.6:1827
/ /
port:80 v v port:80
---------------------- ----------------------
| 61.51.202.88 | Internet host | 61.51.76.102 | Internet host
---------------------- ----------------------
圖二: NAPT 實現了私有IP的計算機分享一個公網IP地址訪問Internet的功能。
在咱們的工做和生活中, NAPT的做用隨處可見,絕大部分公司的網絡架構,都是經過1至N臺支持NAPT的路由器來實現公司的全部計算機鏈接外部的Internet網絡的。包括本人在寫這篇文章的時候,也是在家中使用一臺IBM筆記本經過一臺寬帶鏈接的臺式機來訪問Internet的。咱們本篇文章主要討論的NAPT的問題。測試
NAPT(The IP Network Address/Port Translator) 爲什麼阻礙了P2P軟件的應用?翻譯
經過NAPT 上網的特色決定了只能由NAPT內的計算機主動向NAPT外部的主機發起鏈接,外部的主機想直接和NAPT內的計算機直接創建鏈接是不被容許的。IM(即時通信)而言,這意味着因爲NAPT內的計算機和NAPT外的計算機只能經過服務器中轉數據來進行通信。對於P2P方式的下載程序而言,意味着NAPT內的計算機不能接收到NAPT外部的鏈接,致使鏈接數用過少,下載速度很難上去。所以P2P軟件必需要解決的一個問題就是要可以在必定的程度上解決NAPT內的計算機不能被外部鏈接的問題。htm
NAT(The IP Network Address Translator) 進行UDP穿透的原理是什麼?blog
TCP/IP傳輸時主要用到TCP和UDP協議。TCP協議是可靠的,面向鏈接的傳輸協議。UDP是不可靠的,無鏈接的協議。根據TCP和UDP協議的實現原理,對於NAPT來進行穿透,主要是指的UDP協議。TCP協議也有可能,可是可行性很是小,要求更高,咱們此處不做討論,若是感興趣能夠到Google上搜索,有些文章對這個問題作了探討性的描述。下面咱們來看看利用UDP協議來穿透NAPT的原理是什麼:
---------------------- ----------------------
| 192.168.0.5 | Internat host | 192.168.0.6 | Internat host
---------------------- ----------------------
UDP port: 2809 ^ ^ UDP port: 1827
/ /
v v
----------------------
| 192.168.0.1 | NAT device
| 61.51.99.86 |
----------------------
Session(192.168.0.6:1827 <-> 61.51.76.102:8098) ^ ^ Session(192.168.0.6:1827 <-> 61.51.76.102:8098)
map port:9882 to 192.168.0.5:2809 / /map port: 9881 to 192.168.0.6:1827
UDP port:8098 v v UDP port:8098
---------------------- ----------------------
| 61.51.202.88 | Internet host | 61.51.76.102 | Internet host
---------------------- ----------------------
圖三: NAPT 是如何將私有IP地址的UDP數據包與公網主機進行透明傳輸的。
UDP協議包經NAPT透明傳輸的說明:
NAPT爲每個Session分配一個NAPT本身的端口號,依據此端口號來判斷將收到的公網IP主機返回的TCP/IP數據包轉發給那臺內網IP地址的計算機。在這裏Session是虛擬的,UDP通信並不須要創建鏈接,可是對於NAPT而言,的確要有一個Session的概念存在。NAPT對於UDP協議包的透明傳輸面臨的一個重要的問題就是如何處理這個虛擬的Session。咱們都知道TCP鏈接的Session以SYN包開始,以FIN包結束,NAPT能夠很容易的獲取到TCP Session的生命週期,並進行處理。可是對於UDP而言,就麻煩了,NAPT並不知道轉發出去的UDP協議包是否到達了目的主機,也沒有辦法知道。並且鑑於UDP協議的特色,可靠不好,所以NAPT必須強制維持Session的存在,以便等待將外部送回來的數據並轉發給曾經發起請求的內網IP地址的計算機。NAPT具體如何處理UDP Session的超時呢?不一樣的廠商提供的設備對於NAPT的實現不近相同,也許幾分鐘,也許幾個小時,些NAPT的實現還會根據設備的忙碌狀態進行智能計算超時時間的長短。
[192.168.0.6:1827]
| UDP Packet[src ip:192.168.0.6 src port:1827 dst ip:61.51.76.102 dst port 8098]
v
[pub ip: 61.51.99.86]NAT[priv ip: 192.168.0.1]
| UDP Packet[src ip:61.51.99.86 src port:9881 dst ip:61.51.76.102 dst port 8098]
v
[61.51.76.102:8098]
圖四: NAPT 將內部發出的UDP協議包的源地址和源端口改變傳輸給公網IP主機。
[192.168.0.6:1827]
^
| UDP Packet[src ip:61.51.76.102 src port:8098 dst ip:192.168.0.6 dst port 1827]
[pub ip: 61.51.99.86]NAT[priv ip: 192.168.0.1]
^
| UDP Packet[src ip:61.51.76.102 src port:8098 dst ip:61.51.99.86 dst port 9881]
[61.51.76.102:8098]
圖五: NAPT 將收到的公網IP主機返回的UDP協議包的目的地址和目的端口改變傳輸給內網IP計算機。
如今咱們大概明白了NAPT如何實現內網計算機和外網主機間的透明通信。如今來看一下咱們最關心的問題,就是NAPT是依據什麼策略來判斷是否要爲一個請求發出的UDP數據包創建Session的呢?主要有一下幾個策略:
A. 源地址(內網IP地址)不一樣,忽略其它因素, 在NAPT上確定對應不一樣的Session
B. 源地址(內網IP地址)相同,源端口不一樣,忽略其它的因素,則在NAPT上也確定對應不一樣的Session
C. 源地址(內網IP地址)相同,源端口相同,目的地址(公網IP地址)相同,目的端口不一樣,則在NAPT上確定對應同一個Session
D. 源地址(內網IP地址)相同,源端口相同,目的地址(公網IP地址)不一樣,忽略目的端口,則在NAPT上是如何處理Session的呢?
D的狀況正式咱們關心和要討論的問題。依據目的地址(公網IP地址)對於Session的創建的決定方式咱們將NAPT設備劃分爲兩大類:
Symmetric NAPT:
對於到同一個IP地址,任意端口的鏈接分配使用同一個Session; 對於到不一樣的IP地址, 任意端口的鏈接使用不一樣的Session.
咱們稱此種NAPT爲 Symmetric NAPT. 也就是隻要本地綁定的UDP端口相同, 發出的目的IP地址不一樣,則會創建不一樣的Session.
[202.223.98.78:9696] [202.223.98.78:9696] [202.223.98.78:9696]
^ ^ ^
| | |
v v v
9883 9882 9881
|
/ [NAT] /
^
|
v
[192.168.0.6:1827]
圖六: Symmetric 的英文意思是對稱。多個端口對應多個主機,平行的,對稱的!
Cone NAPT:
對於到同一個IP地址,任意端口的鏈接分配使用同一個Session; 對於到不一樣的IP地址,任意端口的鏈接也使用同一個Session.
咱們稱此種NAPT爲 Cone NAPT. 也就是隻要本地綁定的UDP端口相同, 發出的目的地址不論是否相同, 都使用同一個Session.
[202.223.98.78:9696] [202.223.98.78:9696] [202.223.98.78:9696]
^ ^ ^
/ | /
v v v
9881
[NAT]
^
|
v
[192.168.0.6:1827]
圖七: Cone 的英文意思是錐。一個端口對應多個主機,是否是像個錐子?
如今絕大多數的NAPT屬於後者,即Cone NAT。本人在測試的過程當中,只好使用了一臺日本的Symmetric NAT。還好不是本身的買的,我從不買日貨, 但願看這篇文章的朋友也自覺的不要購買日本的東西。Win9x/2K/XP/2003系統自帶的NAPT也是屬於 Cone NAT的。這是值的慶幸的,由於咱們要作的UDP穿透只能在Cone NAT間進行,只要有一臺不是Cone NAT,對不起,UDP穿透沒有但願了,服務器轉發吧。後面會作詳細分析!
下面咱們再來分析一下NAPT 工做時的一些數據結構,在這裏咱們將真正說明UDP能夠穿透Cone NAT的依據。這裏描述的數據結構只是爲了說明原理,不具備實際參考價值,真正感興趣能夠閱讀Linux的中關於NAT實現部分的源碼。真正的NAT實現也沒有利用數據庫的,呵呵,爲了速度!
Symmetric NAPT 工做時的端口映射數據結構以下:
內網信息表:
[NAPT 分配端口] [ 內網IP地址 ] [ 內網端口 ] [ 外網IP地址 ] [ SessionTime 開始時間 ]
PRIMARY KEY( [NAPT 分配端口] ) -> 表示依據[NAPT 分配端口]創建主鍵,必須惟一且創建索引,加快查找.
UNIQUE( [ 內網IP地址 ], [ 內網端口 ] ) -> 表示這兩個字段聯合起來不能重複.
UNIQUE( [ 內網IP地址 ], [ 內網端口 ], [ 外網IP地址 ] ) -> 表示這三個字段聯合起來不能重複.
映射表:
[NAPT 分配端口] [ 外網端口 ]
UNIQUE( [NAPT 分配端口], [ 外網端口 ] ) -> 表示這兩個字段聯合起來不能重複.
Cone NAPT 工做時的端口映射數據結構以下:
內網信息表:
[NAPT 分配端口] [ 內網IP地址 ] [ 內網端口 ] [ SessionTime 開始時間 ]
PRIMARY KEY( [NAPT 分配端口] ) -> 表示依據[NAPT 分配端口]創建主鍵,必須惟一且創建索引,加快查找.
UNIQUE( [ 內網IP地址 ], [ 內網端口 ] ) -> 表示這兩個字段聯合起來不能重複.
外網信息表:
[ wid 主鍵標識 ] [ 外網IP地址 ] [ 外網端口 ]
PRIMARY KEY( [ wid 主鍵標識 ] ) -> 表示依據[ wid 主鍵標識 ]創建主鍵,必須惟一且創建索引,加快查找.
UNIQUE( [ 外網IP地址 ], [ 外網端口 ] ) -> 表示這兩個字段聯合起來不能重複.
映射表: 實現一對多,的
[NAPT 分配端口] [ wid 主鍵標識 ]
UNIQUE( [NAPT 分配端口], [ wid 主鍵標識 ] ) -> 表示這兩個字段聯合起來不能重複.
UNIQUE( [ wid 主鍵標識 ] ) -> 標識此字段不能重複.
看完了上面的數據結構是更明白了仍是更暈了? 呵呵! 多想一下子就會明白了。經過NAT,內網計算機計算機向外連結是很容易的,NAPT會自動處理,咱們的應用程序根本沒必要關心它是如何處理的。那麼外部的計算機想訪問內網中的計算機如何實現呢?咱們來看一下下面的流程:
c 是一臺在NAPT後面的內網計算機,s是一臺有外網IP地址的計算機。c 主動向 s 發起鏈接請求,NAPT依據上面描述的規則在本身的數據結構中記錄下來,創建一個Session. 而後 c 和 s 之間就能夠實現雙向的透明的數據傳輸了。以下面所示:
c[192.168.0.6:1827] <-> [priv ip: 192.168.0.1]NAPT[pub ip: 61.51.99.86:9881] <-> s[61.51.76.102:8098]
因而可知,一臺外網IP地址的計算機想和NAPT後面的內網計算機通信的條件就是要求NAPT後面的內網計算機主動向外網IP地址的計算機發起一個UDP數據包。外網IP地址的計算機利用收到的UDP數據包獲取到NAPT的外網IP地址和映射的端口,之後就能夠和內網IP的計算機透明的進行通信了。
如今咱們再來分析一下咱們最關心的兩個NAPT後面的內網計算機如何實現直接通信呢? 二者都沒法主動發出鏈接請求,誰也不知道對方的NAPT的公網IP地址和NAPT上面映射的端口號。因此咱們要靠一個公網IP地址的服務器幫助二者來創建鏈接。當兩個NAPT後面的內網計算機分別鏈接了公網IP地址的服務器後,服務器能夠從收到的UDP數據包中獲取到這兩個NAPT設備的公網IP地址和這兩個鏈接創建的Session的映射端口。兩個內網計算機能夠從服務器上獲取到對方的NAPT設備公網IP地址和映射的端口了。
咱們假設兩個內網計算機分別爲A和B,對應的NAPT分別爲AN和BN, 若是A在獲取到B對應的BN的IP地址和映射的端口後,迫不急待的向這個IP
地址和映射的端口發送了個UDP數據包,會有什麼狀況發生呢?依據上面的原理和數據結構咱們會知道,AN會在本身的數據結構中生成一條記錄,標識一個新Session的存在。BN在收到數據包後,從本身的數據結構中查詢,沒有找到相關記錄,所以將包丟棄。B是個慢性子,此時才慢吞吞的向着AN的IP地址和映射的端口發送了一個UDP數據包,結果如何呢?固然是咱們指望的結構了,AN在收到數據包後,從本身的數據結構中查找到了記錄,因此將數據包進行處理髮送給了A。A 再次向B發送數據包時,一切都時暢通無阻了。OK, 大工告成!且慢,這時對於Cone NAPT而言,對於Symmetric NAPT呢?呵呵,本身分析一下吧...
NAPT(The IP Network Address/Port Translator) 進行UDP穿透的具體狀況分析!
首先明確的將NAPT設備按照上面的說明分爲: Symmetric NAPT 和 Cone NAPT, Cone NAPT 是咱們須要的。Win9x/2K/XP/2003 自帶的NAPT也爲Cone NAPT。
第一種狀況, 雙方都是Symmetric NAPT:
此狀況應給不存在什麼問題,確定是不支持UDP穿透。
第二種狀況, 雙方都是Cone NAPT:
此狀況是咱們須要的,能夠進行UDP穿透。
第三種狀況, 一個是Symmetric NAPT, 一個是Cone NAPT:
此狀況比較複雜,但咱們按照上面的描述和數據機構進行一下分析也很容易就會明白了, 分析以下,
假設: A -> Symmetric NAT, B -> Cone NAT
1. A 想鏈接 B, A 從服務器那兒獲取到 B 的NAT地址和映射端口, A 通知服務器,服務器告知 B A的NAT地址和映射端口, B 向 A 發起鏈接,A 確定沒法接收到。此時 A 向 B 發起鏈接, A 對應的NAT創建了一個新的Session,分配了一個新的映射端口, B 的 NAT 接收到UDP包後,在本身的映射表中查詢,沒法找到映射項,所以將包丟棄了。
2. B 想鏈接 A, B 從服務器那兒獲取到 A 的NAT地址和映射端口, B 通知服務器, 服務器告知 A B的NAT地址和映射端口,A 向 B 發起鏈接, A 對應的NAT創建了一個新的Session,分配了一個新的映射端口B確定沒法接收到。此時 B 向 A 發起鏈接, 因爲 B 沒法獲取 A 創建的新的Session的映射端口,還是使用服務器上獲取的映射端口進行鏈接, 所以 A 的NAT在接收到UDP包後,在本身的映射表中查詢,沒法找到映射項, 所以將包丟棄了。
根據以上分析,只有當鏈接的兩端的NAT都爲Cone NAT的狀況下,才能進行UDP的內網穿透互聯。
NAPT(The IP Network Address/Port Translator) 進行UDP穿透如何進行現實的驗證和分析!
須要的網絡結構以下:
三個NAT後面的內網機器,兩個外網服務器。其中兩臺Cone NAPT,一臺 Symmetric NAPT。
驗證方法:
可使用本程序提供的源碼,編譯,而後分別運行服務器程序和客戶端。修改事後的源碼增長了客戶端之間直接經過IP地址和端口發送消息的命令,利用此命令,你能夠手動的驗證NAPT的穿透狀況。爲了方便操做,推薦你使用一個遠程登錄軟件,能夠直接在一臺機器上操做全部的相關的計算機,這樣很方便,一我的就能夠完成全部的工做了。呵呵,本人就是這麼完成的。歡迎有興趣和經驗的朋友來信批評指正,共同進步。