查看單個文章
舊 2005-06-15, 05:20 AM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 P2P之UDP穿透NAT的原理與實現

P2P之UDP穿透NAT的原理與實現





論壇上經常有對P2P原理的討論,但是討論歸討論,很少有實質的東西產生(來源碼)。哈哈,在這裡我就用自己實現的一個來源碼來說明UDP穿越NAT的原理。

首先先介紹一些基本概念:
NAT(Network Address Translators),網路位址轉換:網路位址轉換是在IP位址日益缺乏的情況下產生的,它的主要目的就是為了能夠位址重用。NAT分為兩大類,基本的NAT和NAPT(Network Address/Port Translator)。
最開始NAT是執行在路由器上的一個功能模組。

最先提出的是基本的NAT,它的產生關於如下事實:一個私有網路(域)中的節點中只有很少的節點需要與外網連接(哈哈,這是在上世紀90年代中期提出的)。那麼這個子網中其實只有少數的節點需要全球唯一的IP位址,其他的節點的IP位址應該是可以重用的。
因此,基本的NAT實現的功能很簡單,在子網內使用一個保留的IP子網段,這些IP對外是不可見的。子網內只有少數一些IP位址可以對應到真正全球唯一的IP位址。如果這些節點需要訪問外部網路,那麼基本NAT就負責將這個節點的子網內IP轉化為一個全球唯一的IP然後傳送出去。(基本的NAT會改變IP包中的原IP位址,但是不會改變IP包中的連接阜)
關於基本的NAT可以參看RFC 1631

另外一種NAT叫做NAPT,從名稱上我們也可以看得出,NAPT不但會改變經過這個NAT設備的IP資料報的IP位址,還會改變IP資料報的TCP/UDP連接阜。基本NAT的設備可能我們見的不多(哈哈,我沒有見到過),NAPT才是我們真正討論的主角。看下圖:
Server S1
18.181.0.31:1235
|
^ Session 1 (A-S1) ^ |
| 18.181.0.31:1235 | |
v 155.99.25.11:62000 v |
|
NAT
155.99.25.11
|
^ Session 1 (A-S1) ^ |
| 18.181.0.31:1235 | |
v 10.0.0.1:1234 v |
|
Client A
10.0.0.1:1234
有一個私有網路10.*.*.*,Client A是其中的一台電腦,這個網路的網路閘道(一個NAT設備)的外網IP是155.99.25.11(應該還有一個局內網的IP位址,比如10.0.0.10)。如果Client A中的某個行程(這個行程新增了一個UDP Socket,這個Socket綁定1234連接阜)想訪問外網主機18.181.0.31的1235連接阜,那麼當資料包通過NAT時會發生什麼事情呢?
首先NAT會改變這個資料包的原IP位址,改為155.99.25.11。

接著NAT會為這個傳輸新增一個Session(Session是一個抽像的概念,如果是TCP,也許Session是由一個SYN包開始,以一個FIN包結束。而UDP呢,以這個IP的這個連接阜的第一個UDP開始,結束呢,哈哈,也許是幾分鍾,也許是幾小時,這要看具體的實現了)並且給這個Session分配一個連接阜,比如62000,然後改變這個資料包的源連接阜為62000。所以本來是(10.0.0.1:1234->18.181.0.31:1235)的資料包到了網際網路上變為了(155.99.25.11:62000->18.181.0.31:1235)。
一旦NAT新增了一個Session後,NAT會記住62000連接阜對應的是10.0.0.1的1234連接阜,以後從18.181.0.31傳送到62000連接阜的資料會被NAT自動的轉發到10.0.0.1上。(注意:這裡是說18.181.0.31傳送到62000連接阜的資料會被轉發,其他的IP傳送到這個連接阜的資料將被NAT拋棄)這樣Client A就與Server S1建立以了一個連接。

哈哈,上面的基礎知識可能很多人都知道了,那麼下面是關鍵的部分了。
看看下面的情況:
Server S1 Server S2
18.181.0.31:1235 138.76.29.7:1235
| |
| |
+----------------------+----------------------+
|
^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^
| 18.181.0.31:1235 | | | 138.76.29.7:1235 |
v 155.99.25.11:62000 v | v 155.99.25.11:62000 v
|
Cone NAT
155.99.25.11
|
^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^
| 18.181.0.31:1235 | | | 138.76.29.7:1235 |
v 10.0.0.1:1234 v | v 10.0.0.1:1234 v
|
Client A
10.0.0.1:1234
接上面的例子,如果Client A的原來那個Socket(綁定了1234連接阜的那個UDP Socket)又接著向另外一個Server S2傳送了一個UDP包,那麼這個UDP包在通過NAT時會怎麼樣呢?
__________________
http://bbsimg.qianlong.com/upload/01/08/29/68/1082968_1136014649812.gif
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次