我們在上一講聊到 STUN 及打洞的機制可以解決錐形 NAT 的穿越問題,然而還有對稱 NAT 這個難題要解決。
我們先再回顧一下為何 P2P 的連線對於對稱 NAT 的穿越如此困難。
由於對稱 NAT 會對於同一個內網的同一個服務(同 IP Address 同 Port,如 192.168.1.2:5566)產生一組新的映射,比如對到 STUN Server 和 8.7.6.5 這個位置的服務,就會產生 External IP Address 為 1.2.3.4,但是 Port 分別是 9200 及 9201 這樣的映射。
如此一來,就算 8.7.6.5 這個位置從中繼 Server 得知我們的服務位於 9200 Port(由我們和 STUN Server 所取得),也沒辦法建立連線,因為 9200 Port 是我們和 STUN Server 所建立的連線,無法被分享。
*對稱 NAT 的 1-1 Mapping
由於 NAT 的映射產生是 Router 所處理的,我們無法假定各種廠商 Router 上的映射表是我們裝置的服務可以取得的,因此也很難透過打洞的策略讓雙方知道對方到自己的映射位置。
怎麼解決這個問題呢?只好靠中繼伺服器!
TURN 的全名為 Traversal Using Relay around NAT,顧名思義,就是 NAT 的 Relay(中繼)。
其原理也就是當作兩個 NAT 中間的節點罷了,所有的流量都會透過 TURN Server,作為中繼站在兩個裝置間幫忙傳輸。
*TURN Server
很明顯的,TURN 的最大缺點就是所有流量都會透過他,這樣也便沒有了 P2P 服務的意義了。當傳輸的內容為影像或音訊時,流量就會很大,而導致成本飆升。
因此,有些策略在處理對稱 NAT 時會先透過「猜」映射表,看看能否透過規律甚至運氣試個幾次矇中。真的不行的話,下策才是將流量導向 TURN Server 來建立雙方的連線。
最後我們來聊聊集大成的 ICE!其全名為 Interactive Connectivity Establishment,是一種幫助 P2P 服務建立連線的 NAT 穿越技術,例如 WebRTC 就是基於 ICE 的標準。
本質上 ICE 就像是將各種穿越法打包起來的武功秘笈,其運作的方法大概可以總結如下:
收集候選者並交換資料(Candidate Gathering and Exchange Candidate Information)
尋找並選擇最佳路徑(Connectivity Check and Nominate a Candidate Pair)
*ICE 運作模式
首先是透過 STUN Server 來找到雙方 Public IP Address + Port 的映射,也就是所謂的候選者們。並且把些資訊交給對方,接著就可以開始尋找最佳路徑。
尋找路徑的方式則是來試試看不同方法,假如是在完全錐形 NAT 後的裝置,直接拿 STUN Server 取得的資料一送就發現通了,最佳路徑便找到了!
若是在受限錐形 NAT 後的裝置,可能就要多試幾次,打開 Hole Punching 的章節,理論上也能夠找到一條不錯路徑。
然而在對稱 NAT 的阻擋下,可能最終還是找不到在兩個裝置間直接的連線路徑,最後只好透過 TURN Server 來幫忙交換封包。
但總而言之,ICE 最後還是能從成本低到高的嘗試中,幫兩台位於 NAT 後的裝置建立起 P2P 的連線!