物聯網高併發編程之P2P技術NAT快速理解

物聯網高併發編程之P2P技術NAT快速理解

更多物聯網高併發編程知識請移步:https://www.yuque.com/shizhiy...
html

前言

P2P技術在現實的應用場景中,主要用於諸如IM(尤爲移動端IM)、在線直播、在線教育等(這些應用裏的實時音視頻功能一般都會涉及到P2P),瞭解P2P的原理對於開發相關的應用來講仍是頗有必要的。編程

基礎知識

簡單介紹一下 詳細瞭解請翻閱他的上下篇文章

什麼是NAT?

NAT(Network Address Translation,網絡地址轉換),也叫作網絡掩蔽或者IP掩蔽。NAT是一種網絡地址翻譯技術,主要是將內部的私有IP地址(private IP)轉換成能夠在公網使用的公網IP(public IP)。安全

爲何會有NAT?

時光回到上個世紀80年代,當時的人們在設計網絡地址的時候,以爲再怎麼樣也不會有超過32bits位長即2的32次冪臺終端設備連入互聯網,再加上增長ip的長度(即便是從4字節增到6字節)對當時設備的計算、存儲、傳輸成本也是至關巨大的。後來逐漸發現IP地址不夠用了,而後就NAT就誕生了!(雖然ipv6也是解決辦法,但始終普及不開來,並且將來到底ipv6夠不夠用還是未知)。服務器

所以,NAT技術可以興起的緣由仍是由於在咱們國家公網IP地址太少了,不夠用,因此纔會採起這種地址轉換的策略。可見,NAT的本質就是讓一羣機器公用同一個IP,這樣就暫時解決了IP短缺的問題。網絡

NAT有什麼優缺點?

優點其實上面已經剛剛討論過了,根據定義,比較容易看出,NAT能夠同時讓多個計算機同時聯網,並隱藏其內網IP,所以也增長了內網的網絡安全性;此外,NAT對來自外部的數據查看其NAT映射記錄,對沒有相應記錄的數據包進行拒絕,提升了網絡安全性。架構

那麼,NAT與此同時也帶來一些弊端:首先是,NAT設備會對數據包進行編輯修改,這樣就下降了發送數據的效率;此外,各類協議的應用各有不一樣,有的協議是沒法經過NAT的(不能經過NAT的協議仍是蠻多的),這就須要經過穿透技術來解決。咱們後面會重點討論穿透技術。併發

簡單的背景瞭解事後,下面介紹下NAT實現的主要方式,以及NAT都有哪些類型。


socket

NAT的實現方式

靜態NAT

也就是靜態地址轉換。是指一個公網IP對應一個私有IP,是一對一的轉換,同時注意,這裏只進行了IP轉換,而沒有進行端口的轉換

image.png


高併發

NAPT

端口多路複用技術。與靜態NAT的差異是,NAPT不但要轉換IP地址,還要進行傳輸層的端口轉換。具體的表現形式就是,對外只有一個公網IP,經過端口來區別不一樣私有IP主機的數據

image.png


測試

NAT的主要類型

對於NAPT咱們主要分爲兩大類:錐型NAT和對稱型NAT


其中錐型NAT又分:徹底錐型,受限錐型和端口受限錐型。

歸納的說:對稱型NAT是一個請求對應一個端口;錐型NAT(非對稱NAT)是多個請求(外部發向內部)對應一個端口,只要源IP端口不變,不管發往的目的IP是否相同,在NAT上都映射爲同一個端口,形象的看起來就像錐子同樣。

下面分別介紹這四種類型及其差別:


徹底錐型NAT(Full Cone NAT,後面簡稱FC)

特色:IP和端口都不受限。

表現形式:未來自內部同一個IP地址同一個端口號(IP_IN_A : PORT_IN_A)的主機監聽/請求,映射到公網IP某個端口(IP_OUT_B : PORT_OUT_B)的監聽。

任意外部IP地址與端口對其本身公網的IP這個映射後的端口訪問(IP_OUT_B : PORT_OUT_B),都將從新定位到內部這個主機(IP_IN_A : PORT_IN_A)。該技術中,基於C/S架構的應用能夠在任何一端發起鏈接。是否是很繞啊。

再簡單一點的說,就是,只要客戶端,由內到外創建一個映射(NatIP:NatPort -> A:P1)以後,其餘IP的主機B或端口A:P2均可以使用這個洞給客戶端發送數據。

image.png


受限錐型NAT(Restricted Cone NAT)

特色:IP受限,端口不受限。

表現形式:與徹底錐形NAT不一樣的是,在公網映射端口後,並不容許全部IP進行對於該端口的訪問,要想通訊必需內部主機對某個外部IP主機發起過鏈接,而後這個外部IP主機就能夠與該內部主機通訊了,但端口不作限制。

舉個栗子。當客戶端由內到外創建映射(NatIP:NatPort –> A:P1),A機器可使用他的其餘端口(P2)主動鏈接客戶端,但B機器則不被容許。由於IP受限啦,可是端口隨便。見下圖(綠色是容許通訊,紅色是禁止通訊)

image.png


端口受限型NAT(Port Restricted Cone NAT)

特色:IP和端口都受限。

表現形式:該技術與受限錐形NAT相比更爲嚴格。除具備受限錐形NAT特性,對於回覆主機的端口也有要求。也就是說:只有當內部主機曾經發送過報文給外部主機(假設其IP地址爲A且端口爲P1)以後,外部主機才能以公網IP:PORT中的信息做爲目標地址和目標端口,向內部主機發送UDP報文,同時,其請求報文的IP必須是A,端口必須爲P1(使用IP地址爲A,端口爲P2,或者IP地址爲B,端口爲P1都將通訊失敗)。例子見下圖。這一要求進一步強化了對外部報文請求來源的限制,從而較Restrictd Cone更具安全性



image.png


對稱型NAT(Symmetric NAT)

特色:對每一個外部主機或端口的會話都會映射爲不一樣的端口(洞)。

表現形式:只有來自同一內部IP:PORT、且針對同一目標IP:PORT的請求才被NAT轉換至同一個公網(外部)IP:PORT,不然的話,NAT將爲之分配一個新的外部(公網)IP:PORT。

而且,只有曾經收到過內部主機請求的外部主機才能向內部主機發送數據包。內部主機用同一IP與同一端口與外部多IP通訊。客戶端想和服務器A(IP_A:PORT_A)創建鏈接,是經過NAT映射爲NatIP:NatPortA來進行的。而客戶端和服務器B(IP_B:PORT_B)創建鏈接,是經過NAT映射爲NatIP:NatPortB來進行的。即同一個客戶端和不一樣的目標IP:PORT通訊,通過NAT映射後的公網IP:PORT是不一樣的。此時,若是B想要和客戶端通訊,也只能經過NatIP:NatPortB(也就是紫色的洞洞)來進行,而不能經過NatIP:NatPortA(也就是黃色的洞洞)



image.png


小結

能夠看出從類型1至類型4,NAT的限制是愈來愈大的。




NAT路由類型判斷

根據上面的介紹,咱們能夠了解到,在實際的網絡狀況中,各個設備所處的網絡環境是不一樣的。那麼,若是這些設備想要進行通訊,首先判斷出設備所處的網絡類型就是很是重要的一步。

舉個例子來講:對於IM中的實時音視頻功能和VoIP軟件,對位於不一樣NAT內部的主機通訊須要靠服務器來轉發完成,這樣就會增長服務器的負擔。

爲了解決這種問題,要儘可能使位於不一樣NAT內部的主機創建直接通訊,其中,最重要的一點就是要判斷出NAT的類型,而後才能根據NAT的類型,設計出直接通訊方案。否則的話,兩個都在NAT的終端怎麼通訊呢?咱們不知道對方的內網IP,即便把消息發到對方的網關,而後呢?網關怎麼知道這條消息給誰,並且誰容許網關這麼作了?

爲了解決這個問題,也就是處於內網的主機之間可以穿越它們之間的NAT創建直接通訊,已經提出了許多方法,STUN(Session Traversal Utilities for NAT,NAT會話穿越應用程序)技術就是其中比較重要的一種解決方法,並獲得了普遍的應用。在這個部分,咱們將重點介紹下STUN技術的原理。

PS:除此以外,還有UPNP技術,ALG應用層網關識別技術,SBC會話邊界控制,ICE交互式鏈接創建,TURN中繼NAT穿越技術等等,本文不一一作介紹。

STUN協議介紹

STUN基本介紹

STUN是一種網絡協議,它容許位於NAT(或多重NAT)後的客戶端找出本身的公網地址,查出本身位於哪一種類型的NAT以後以及NAT爲某一個本地端口所綁定的Internet端端口。這些信息被用來在兩個同時處於NAT路由器以後的主機之間創建UDP通訊。該協議由RFC 5389定義。



STUN由三部分組成:

  • STUN客戶端;
  • STUN服務器端;
  • NAT路由器。

STUN服務端部署在一臺有着兩個公網IP的服務器上,大概的結構參考下圖。STUN客戶端經過向服務器端發送不一樣的消息類型,根據服務器端不一樣的響應來作出相應的判斷,一旦客戶端得知了Internet端的UDP端口,通訊就能夠開始了



image.png


STUN的檢測過程

STUN協議定義了三類測試過程來檢測NAT類型:

  • Test1:STUN Client經過端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}發送一個Binding Request(沒有設置任何屬性)。STUN Server收到該請求後,經過端口{IP-S1:Port-S1}把它所看到的STUN Client的IP和端口{IP-M1,Port-M1}做爲Binding Response的內容回送給STUN Client。
  • Test1#2:STUN Client經過端口{IP-C1:Port-C1}向STUN Server{IP-S2:Port-S2}發送一個Binding Request(沒有設置任何屬性)。STUN Server收到該請求後,經過端口{IP-S2:Port-S2}把它所看到的STUN Client的IP和端口{IP-M1#2,Port-M1#2}做爲Binding Response的內容回送給STUN Client。
  • Test2:STUN Client經過端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}發送一個Binding Request(設置了Change IP和Change Port屬性)。STUN Server收到該請求後,經過端口{IP-S2:Port-S2}把它所看到的STUN Client的IP和端口{IP-M2,Port-M2}做爲Binding Response的內容回送給STUN Client。
  • Test3:STUN Client經過端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}發送一個Binding Request(設置了Change Port屬性)。STUN Server收到該請求後,經過端口{IP-S1:Port-S2}把它所看到的STUN Client的IP和端口{IP-M3,Port-M3}做爲Binding Response的內容回送給STUN Client。

STUN協議的輸出是:

  • 1)公網IP和Port;
  • 2)防火牆是否設置;
  • 3)客戶端是否在NAT以後,及所處的NAT的類型。

所以咱們進而整理出,經過STUN協議,咱們能夠檢測的類型一共有如下七種:

  • A:公開的互聯網IP:主機擁有公網IP,而且沒有防火牆,可自由與外部通訊;
  • B:徹底錐形NAT;
  • C:受限制錐形NAT;
  • D:端口受限制形NAT;
  • E:對稱型UDP防火牆:主機出口處沒有NAT設備,但有防火牆,且防火牆規則以下:從主機UDP端口A發出的數據包保持源地址,但只有從以前該主機發出包的目的IP/PORT發出到該主機端口A的包才能經過防火牆;
  • F:對稱型NAT;
  • G:防火牆限制UDP通訊。

STUN協議的判斷過程

輸入和輸出準備好後,附上一張維基百科的流程圖,就能夠描述STUN協議的判斷過程了。



image.png

STEP1:檢測客戶端是否有能力進行UDP通訊以及客戶端是否位於NAT後 -- Test1
客戶端創建UDP socket,而後用這個socket向服務器的(IP-1,Port-1)發送數據包要求服務器返回客戶端的IP和Port,客戶端發送請求後當即開始接受數據包。重複幾回。

  • 若是每次都超時收不到服務器的響應,則說明客戶端沒法進行UDP通訊,多是:G防火牆阻止UDP通訊;
  • 若是能收到迴應,則把服務器返回的客戶端的(IP:PORT)同(Local IP: Local Port)比較:
  •   - 若是徹底相同則客戶端不在NAT後,這樣的客戶端是:A具備公網IP能夠直接監聽UDP端口接收數據進行通訊或者E。
  •   - 不然客戶端在NAT後要作進一步的NAT類型檢測(繼續)。

STEP2:檢測客戶端防火牆類型 -- Test2
STUN客戶端向STUN服務器發送請求,要求服務器從其餘IP和PORT向客戶端回覆包:

  • 收不到服務器從其餘IP地址的回覆,認爲包前被前置防火牆阻斷,網絡類型爲E;
  • 收到則認爲客戶端處在一個開放的網絡上,網絡類型爲A。

STEP3:檢測客戶端NAT是不是FULL CONE NAT -- Test2
客戶端創建UDP socket而後用這個socket向服務器的(IP-1,Port-1)發送數據包要求服務器用另外一對(IP-2,Port-2)響應客戶端的請求往回發一個數據包,客戶端發送請求後當即開始接受數據包。 重複這個過程若干次。

  • 若是每次都超時,沒法接受到服務器的迴應,則說明客戶端的NAT不是一個Full Cone NAT,具體類型有待下一步檢測(繼續);
  • 若是可以接受到服務器從(IP-2,Port-2)返回的應答UDP包,則說明客戶端是一個Full Cone NAT,這樣的客戶端可以進行UDP-P2P通訊。

STEP4:檢測客戶端NAT是不是SYMMETRIC NAT -- Test1#2

  • 客戶端創建UDP socket而後用這個socket向服務器的(IP-1,Port-1)發送數據包要求服務器返回客戶端的IP和Port, 客戶端發送請求後當即開始接受數據包。 重複這個過程直到收到迴應(必定可以收到,由於第一步保證了這個客戶端能夠進行UDP通訊)。
  • 用一樣的方法用一個socket向服務器的(IP-2,Port-2)發送數據包要求服務器返回客戶端的IP和Port。
  • 比較上面兩個過程從服務器返回的客戶端(IP,Port),若是兩個過程返回的(IP,Port)有一對不一樣則說明客戶端爲Symmetric NAT,這樣的客戶端沒法進行UDP-P2P通訊(檢測中止)由於對稱型NAT,每次鏈接端口都不同,因此沒法知道對稱NAT的客戶端,下一次會用什麼端口。不然是Restricted Cone NAT,是否爲Port Restricted Cone NAT有待檢測(繼續)。

STEP5:檢測客戶端NAT是Restricted Cone 仍是 Port Restricted Cone -- Test3
客戶端創建UDP socket而後用這個socket向服務器的(IP-1,Port-1)發送數據包要求服務器用IP-1和一個不一樣於Port-1的端口發送一個UDP 數據包響應客戶端, 客戶端發送請求後當即開始接受數據包。重複這個過程若干次。若是每次都超時,沒法接受到服務器的迴應,則說明客戶端是一個Port Restricted Cone NAT,若是可以收到服務器的響應則說明客戶端是一個Restricted Cone NAT。以上兩種NAT均可以進行UDP-P2P通訊。

經過以上過程,至此,就能夠分析和判斷出客戶端是否處於NAT以後,以及NAT的類型及其公網IP,以及判斷客戶端是否具有P2P通訊的能力了。

相關文章
相關標籤/搜索