前言
ICE全稱Interactive Connectivity Establishment:交互式連通建立方式。
ICE參照RFC5245建議實現,是一組基於offer/answer模式解決NAT穿越的協議集合。
它綜合利用現有的STUN,TURN等協議,以更有效的方式來建立會話。
客戶端側無需關心所處網絡的位置以及NAT類型,並且能夠動態的發現最優的傳輸路徑。
Classic STUN(RFC3489)的劣勢:
Classic STUN 有着諸多侷限性,例如:
- 不能確定獲得的公網映射地址能否用於P2P通信
- 沒有加密方法
- 不支持TCP穿越
- 不支持對稱型NAT的穿越
- 不支持IPV6
STUN(RFC5389)協議
RFC5389是RFC3489的升級版
- 支持UDP/TCP/TLS協議
- 支持安全認證
ICE利用STUN(RFC5389) Binding Request和Response,來獲取公網映射地址和進行連通性檢查。同時擴展了STUN的相關屬性:
- PRIORITY:在計算candidate pair優先級中使用
- USE-CANDIDATE:ICE提名時使用
- tie-breaker:在角色衝突時使用
TURN協議
ICE使用TURN(RFC 5766)協議作爲STUN的輔助,在點對點穿越失敗的情況下,藉助於TURN服務的轉發功能,來實現互通。端口與STUN保持一致
TURN消息都遵循 STUN 的消息格式,除了ChannelData消息。
- 支持UDP/TCP/TLS協議,適用於UDP被限制的網絡。
- 支持IPV6。
TURN的流程:
- 創建Allocation:
client 使用allocation transaction創建relay 端口,並在allocation的響應中回覆給client。
當allocation創建後需要使用refresh request來保活,默認lifetime爲10分鐘。
- 創建Permission:
由allocation創建Permission,每個Permission 由 IP 地址 和lifetime組成。
有兩種方法來創建和刷新Permission
- CreatePermission
- ChannelBind
- 收發數據:
- CreatePermission使用Send and Data indication消息
- ChannelBind使用ChannelData消息
ICE介紹
- ICE 的角色
分爲 controlling和controlled。
Offer 一方爲controlling角色,answer一方爲controlled角色。
- ICE的模式
分爲FULL ICE和Lite ICE:
FULL ICE:是雙方都要進行連通性檢查,完成的走一遍流程。
Lite ICE: 在FULL ICE和Lite ICE互通時,只需要FULL ICE一方進行連通性檢查, Lite一方只需迴應response消息。這種模式對於部署在公網的設備比較常用。
- Candidate
媒體傳輸的候選地址,組成candidate pair做連通性檢查,確定傳輸路徑,有如下屬性:
- Type 類型有:
Host/Srvflx/Relay/Prflx
- Componet ID
傳輸媒體的類型,1代表RTP;2代表 RTCP。
WebRTC採用Rtcp-mux方式,也就是RTP和RTCP在同一通道內傳輸,減少ICE的協商和通道的保活。
- Priority
Candidate的優先級。
如果考慮延時,帶寬資源,丟包的因素,Type優先級高低一般建議如下順序:
host > srvflx > prflx > relay
- Base
是指candidate 的基礎地址。
Srvflx address 的base 是本地host address。
host address和 relayed address 的base 是自身。
- Candidate pair
由本端和遠端candidate組成的pair,有自己的優先級。
pair優先級的計算是取決candidate的priority。
priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
G:controlling candidate 優先級
D:controlled candidate 優先級
ICE選擇高優先級的candidate pair。
- Checklist
由candidate pair生成按優先級排序的鏈表,用於ICE連通性檢查。
- Validlist
由連通性檢查成功的candidate pair按優先級排序的鏈表,用於ICE提名和選擇最終路徑。
ICE過程
- Gather candidates
根據Componet ID:
- 獲取本機host address.
- 從STUN服務器獲取 srvflx address.
- 從TURN服務器獲取 relay address.
- 同時生成foundation。
- 刪除重複的candidate
收集地址完成後,需要去掉重複的candidate,如果兩個candidate的地址一樣,並且Base地址也一樣,則刪除它。
- 交換candidates
ICE 使用offer/answer方式,雙方通過SDP協商交換candidate信息.
Candidate信息包括type,foundation,base,component id,transport
SDP a行格式如下:
“a=candidate:1 1 UDP 9654321 212.223.223.223 12345 typ srflx raddr 10.216.33.9 rport 54321”
表示 foundation爲1,媒體是RTP,採用UDP協議,公網映射地址爲212.223.223.223:12345,優先級爲9654321,type爲srflx,base地址爲10.216.33.9:54321
- 生成candidate pairs
在本端收到遠端candidates後,將Component ID和transport protocol相同的candidates組成pair。
修整candidate pair,如果是srvflx地址,則需要用其base地址替換。
對端也是同樣的流程。
- 生成checklist
將candidate pairs按照優先級排序,生成checklist,供連通性檢查使用。
- 連通性檢查
Ordinary checks 兩端都按照各自checklist分別進行檢查。
Triggered checks 收到對端的檢查時,也在對應的candidate pair上發起連通性檢查,以提高效率
如果checklist裏有relay candidate,則必須首先爲relay candidate創建permission。
- 發送連通性檢查請求
ICE 使用STUN binding request/response,包含Fingerprint檢驗校驗機制。
如果A收到B的response,則代表連通性檢查成功,否則需要進行重傳直到超 時。
在建立連接時,如果沒有響應,則會以RTO時間進行重傳,每次翻倍,直到最大重傳次數。
STUN請求 採用STUN short-term credential方式認證,
STUN USERNAME屬性 ”RemoteUsername:localUsername”
兩端在SDP協商時交換ice-pwd和ice-ufrag,以得對端用戶名和密碼。
STUN 檢查請求中需要檢查地址的對稱性,請求的源地址是響應的目的地址,請求的目的地址是響應的源地址,否則都設置狀態爲 Failed。
- 生成validlist
將連通性檢查成功的candidate pair並按優先級排序加入validlist,這時本地candidate填寫的是公網映射地址,remote candidate填寫的是對端發送的STUN binding request地址。
- 提名candidate pair
由controlling來提名哪對candidate pair爲valid pair
提名方式又分爲普通提名和進取型提名
普通提名方式會做兩次連通性檢查,在第一次做連通性檢查時不會帶上USE-CANDIDATE屬性,而是在生成的validlist裏選擇pair再進行一次連通性檢查,這時會帶上USE-CANDIDATE屬性,並且置位nominated flag。
進取型方式則是每次發送連通性檢查時都會帶上USE-CANDIDATE屬性,並且置位nominated flag,不會再去做第二次連通性檢查。
- 選擇最終傳輸地址
ICE在提名的valid pair裏選擇優先級最高那對作爲本次ICE流程傳輸地址。
ICE狀態
- Waiting:還未開始連通性檢查,從checklist中選擇合適優先級的pair進行檢查
- In-Progress:連通性檢查已經開始,但還未結束
- Succeeded:該pair 連通性檢查已經完成並且成功
- Failed:失敗
- Frozen:連通性檢查還未開始
ICE保活
- 對於每個ICE通道,都需要爲其會話進行保活。
- 採用STUN binding request或者STUN binding indication。
- 如果沒有收到響應,則會重傳,直到最大重傳次數。
ICE角色衝突解決
- 當兩端角色都爲controlling或者controlled角色衝突時,在連通性檢查階段,要求發送binding request消息裏必須要帶上tie-breaker屬性。
- 當出現衝突時,比較tie-breaker大小,值比較大的則被認爲是controlling,同時迴應487錯誤給對端,對端收到487錯誤後切換角色。
結束語
隨着WebRTC的應用越來越普遍,無論是Native端還是Web端,由於廣泛的適應 能力以及對未來網絡的支持,ICE作爲一種綜合的解決方案將有着非常廣闊的應用前景。
網易雲信翻譯了W3C推薦標準WebRTC 1.0: Real-time CommunicationBetween Browsers,並提供《WebRTC1.0: 瀏覽器間實時通訊》中文版免費下載。
- 對於WebRTC初學者,本文檔可以作爲學習教程,幫助你快速對WebRTC有全面且詳細的瞭解,學習相關API的使用,其附帶的示例代碼也是很好的學習資料;
- 對於WebRTC資深開發者,本文檔可以作爲開發中的使用手冊,根據所提供的函數調用鏈或是算法流程進行開發或bug定位;
- 對於高階玩家,也可通過閱讀本文檔對WebRTC工作組反饋改進意見。
限時免費下載,WebRTC開發者必備。