2020年11月4日 星期三

WebRTC - STUN/TURN server運作流程及限制

在網路上,當Client A 要和 Client B 連線,雙方都不知道自己的 public IP和 port。這時候就可以透過 STUN server 告訴A和B對方的public IP 跟 port 是多少。

交互式連接建立(ICE)

交互式連接建立是一種標準穿透協議,利用Stun和Turn服務器來幫助端點建立連接。市面上已有不少介紹ICE的資料,像《WebRTC權威指南(第三版)》中的“9.2 交互式連接建立”。但看了那些後,有人還是不能理解,這裡試著用一個實例來描述整個過程。 ICE協議只是製定規範,沒規定怎麼實現細節,在細節實現上這裡參考Google的WebRTC。

ICE呼叫流程

上圖就是《WebRTC權威指南(第三版)》中的圖9.1。呼叫要交換兩種信息,一是候選地址,二是媒體信息。候選地址用於建立網絡連接,它存儲著和網絡連接相關的參數。媒體信息(SDP)用於描述要在對等連接上傳輸的數據,包括音頻、視頻和數據。用路和車來比喻的話,候選地址用於造路,媒體信息於用指定要跑什麼車。

  在圖中,雙方是串行處理媒體、候選地址,但實際中是並發的。舉個例子,主叫收到Answer後,它仍可能在收集候選地址,然後通過信令服務器發向被叫。

  除了主叫必須創建Offer才開始收集候選地址、被叫必須創建Answer才開始收集候選地址外,ICE代理是相互獨立地處理媒體和候選地址。 (這結論細節參考底下的“四:選定候選地址,並啟動媒體”)。

  和“9.2 交互式連接建立”一樣, 這裡也把ICE分為六個步驟。下圖是例子使用的網絡拓撲結構。

一:收集候選地址
  候選地址是或許可用於接收媒體以建立對等連接的<IP地址, 端口>對,它分四種類型。

prflx和srflx都是為了獲取內網主機IP映射的公網IP,只是srflx是通過STUN協議,prflx是直接向目的主機發起連接並請求響應的方式。

srflx candidate是通過信令方式向STUN服務器發送binding request,通過該請求找到NAT映射後的地址(server視角);prflx candidate用於鏈接檢查,當A按照優先級向目標peer B發送binding request,B收到peer A的連通性成功時獲得的地址(peer視角)。不知道是否是這樣。

具體到例子,以下是此階段將至少能收集到的候選地址。為簡單,不再寫A的IP2、B的IP2的服務器反射地址。

二:交換候選地址
  A通過信令服務器把A$Cand1、A$Cand2、A$Cand3發向B,相應地,B通過信令服務器把B$Cand1、B$Cand2、B$Cand3發向A。對端收到一個候選地址後會做什麼?深入它之前讓引入兩種對象:P2PTransportChannel、Connection。
  ICE代理用P2PTransportChannel管理通道(Component)上的網絡傳輸。什麼是通道? Webrtc有個概念叫軌道(Track),常見有視頻軌、音頻軌,而要發送一條軌道中數據,最多可能使用兩個通道,分別是Rtp、Rtcp。肯定會有Rtp,Rtcp則可選。一個P2PTransportChannel對應一條通道,如果當前會話要同時處理音頻、視頻,每條軌道又都包括Rtp、Rtcp,那會話中就存在四個P2PTransportChannel對象。 P2PTransportChannel用維護一張連接狀態表來管理網絡傳輸,表中一條記錄對應一個Connection對象。這裡讓具體到A的視頻Rtp對應的P2PTransportChannel,看它在收到B$Cand1後會做什麼。
  當A收到B發來的B$Cand1後,P2PTransportChannel會向連接狀態表新增兩條記錄,即兩個Connection。這時已到通道,地址須是ip:port對。


此時A不知道該用哪個網卡IP才能把數據成功發向192.168.0.204,於是它只要在有可能的地址對就創建Connection。注意Connection只會基於網卡IP,即host,因為對發送源來說,host才可能是源,其它的只是中間轉換出的地址,像srflx。當然,創建時會放棄明顯不可能的<網卡地址, 對端地址>對,舉個例子,網卡地址是ipv4,而對端地址是ipv6。
  當收全B$Cand1、B$Cand2、B$Cand3,狀態表中就有6條記錄。


表中有一條、或多條、或沒有,能夠把A的視頻Rtp數據發向B的視頻Rtp通道,到底怎麼個可能性就要執行接下的Stun檢查。

三:STUN檢查
  在狀態表新建一條記錄,即一個Connection,很快就會在此Connection上進行Stun檢查。 Stun檢查具體操作是在此Connection上發Stun Binding請求。由於要能支持Stun應答,每個ICE代理必須內置Stun服務器功能。 Stun檢查具體步驟見下圖。
為什麼說Stun檢查會發現prflx候選項?假如A和Stun服務器之間連接狀態不好,在它收到B發來的srflx(11.92.14.8)之後還沒得出自個的srflx(211.161.240.181)。雖然A沒得到自個的srflx,但這不妨礙對B的srflx這個候選地址進行Stun檢查,於是會向11.92.14.8發Stun請求。 B收到這個請求,從請求解析出211.161.240.181。雖然這個地址在值上等於A的srflx,但不是從信令服務器得到,而是來自對端的Stun請求。此時B就會以這個prflx向狀態表新建Connection。
  A在之後終於向Stun服務器拿到了自個的srflx,並通過信令服務器發向B。 B發現這個srflx值對應的Connection已存在,就不會再創建了。
  到此可得出個結論:兩種原因會導致新建Connection,一是從信令服務器收到候選地址,二是Stun檢查發現prflx。不同於從信令服務器得到地址而創建的Connection,Stun檢查時創建的Connection一開始就基本能確定連接是暢通的。

四:選定候選地址,並啟動媒體
  P2PTransportChannel會維護連接狀態表,並排序表中記錄(SortConnectionsAndUpdateState)。排序指的是計算每條記錄的連接“成本”,把成本最低的排在第一條。如何計算成本?這涉及到很多因素,比如發出Stun請求到收到應答經過了的時間,用時越少的“成本”自然會低些。
  當A有視頻Rtp數據要發送時,它檢查狀態表的第一條記錄,如果判斷出它的狀態是發送就緒,就會用此Connection進行發送。否則直接放棄這個發送任務。媒體模塊在處理數據的採集、編碼任務時,不用考慮候選地址方面進展怎樣了,只是要到發送時才關注下,而即使不能發送也不會影響自個進度;同樣,候選地址處理模塊也不會關注媒體處理模塊的進度。這正是之前寫的一個結論:“除了主叫必須創建Offer才開始收集候選地址、被叫必須創建Answer才開始收集候選地址外,ICE代理是相互獨立地處理媒體和候選地址”。
  維護表任務包括新建、刪除記錄,以及修改記錄中的狀態字段。刪除記錄、修改狀態都涉及到“長連接”。

五:長連接
  為確保NAT映射和過濾規則不在媒體會話期間超時,ICE會不斷通過使用中的候選項對發送Stun連接檢查。具體到P2PTransportChannel,表現出來的是對狀態表中所有記錄隔段時間就要發送個Stun Binding請求。如果檢測到本來是暢通的Connection上Stun應答超時了,那它就會更改該Connection狀態,執行表排序時就有可能會向下掉,嚴重時會從狀態表刪除該記錄。
  一記錄被刪除後,如果之後那候選地址的連接又恢復了,則會基於該候選地址重新創建Connection。

六:ICE重新啟動
  分析長連接時,我們已能得出個結論,如果是網絡擁堵或通斷導致的狀態表變化,P2PTransportChannel內部就能處理。但是,如果基地址發生改變,像一網卡被禁用,這就超出P2PTransportChannel可處理範圍了,需重啟ICE。

STUN + TRUN server

Open source

明辨STUN/TURN協定 輕鬆跨越NAT建立連線

mystun:

STUN server and client library from the iptel.org guys. Old but mature. License: GPL, You have to download the file via CVS.

Vovida STUN server (stund):

STUN server and client library/application for Linux and Windows from the Vovida guys. Old but mature. License: Vovida Software License 1.0.

WinSTUN:

A Windows STUN client, part of the Vovida STUN server (see above). A nice application to test your NAT box.

reTurn:

STUN/TURN server and client library, part of the resiprocate project. Server application is provided as well, but it seems incomplete (authentication). License: 3-clause BSD license.

restund:

STUN/TURN server, supports authentication against a mysql DB. License: 3-clause BSD license. 

TurnServer:

STUN/TURN server. License: GPL3.

PJNATH :

Open Source ICE, STUN, and TURN Library

Numd:

a free STUN/TURN serve

NAT是什麼?

假設區域網路(LAN)內有5台電腦對外連線,各自有一個對內的 private IP (192.168.0.1~5,5是Client A),對外分別是 222.222.222.222 (port 99, 98, 97, 96, 95),假設有人對 222.222.222.222:95 發送 request, NAT 就會對應到192.168.0.5 轉送給Client A。

過程如下:

Before Pending Request Process for Connection

Client A propose a request to STUN server

STUN get client A ‘s public IP / port and respond to Client A

Client A told webRTC signal server that he wanted to connect Client B

Signal server informed Client B the connection request from Client A (public IP / port included)

Client B repeat step 1–2 get its own IP address information

Signal server respond information to Client A

Now they both use its own IP address information to connect each other, no signal server business included.

General overview of reflex candidates and STUN servers


在某些情況下還是有機會無法連線,因為在某些特定的 NAT 下,STUN server的運作會沒有意義,例如:

對稱NAT(Symmetric NAT)取自 維基百科

  • 每一個來自相同內部 IP 與端口,到一個特定目的地 IP 和端口的請求,都映射到一個獨特的外部 IP 和端口。同一內部 IP 與端口發到不同的目的地和端口的信息包,都使用不同的映射
  • 只有曾经收到过内部主机数据的外部主机,才能够把封包发回


Distinctive IP address/ port for each connection between clients.

我們在重新審視一下剛剛透過 STUN server 交換IP information的過程,很容易可以發現,STUN server 回應給我的 IP 資訊,在Symmetric NAT的限制下只限於我與server 間的連線,若有其他Client透過這組 IP 資訊與我連線,會在 NAT 被擋下,無法順利建立連線。

That’s why we need TURN server

以下轉自 WebRTC in the real world: STUN, TURN and signaling

Session Traversal Utilities for NAT

(STUN) is a standardized protocol for such address discovery including NAT classification. Traversal Using Relays around NAT (TURN) places a third-party server to relay messages between two clients when direct media traffic between peers is not allowed by a firewall.

TURN server

TURN servers have public addresses, so they can be contacted by peers even if the peers are behind firewalls or proxies. TURN servers have a conceptually simple task — to relay a stream — but, unlike STUN servers, they inherently consume a lot of bandwidth. In other words, TURN servers need to be beefier

ICE (Interactive Connectivity Establishment) 

Reference

WebRTC 的靈魂 — STUN/TURN server

交互式连接建立(ICE)

沒有留言:

張貼留言