完整WebRTC技術(shù)及應(yīng)用概要
在本章節(jié)和后續(xù)章節(jié)的討論中,筆者將根據(jù)RFC5245/RFC8445的規(guī)范架構(gòu),結(jié)合筆者的這篇?dú)v史文章來討論WebRTC/ICE的詳細(xì)技術(shù)內(nèi)容。希望通過筆者完整的討論,讀者可以非常清楚了解WebRTC的流程,特別是關(guān)于ICE的處理。筆者在文章中使用的一些本規(guī)范的專有名詞(例如,check 或者check list,事實(shí)上,在本規(guī)范中它具有特定的含義),可能沒有直接以中文的名稱來介紹,這樣做的目的是為了保證不會(huì)產(chǎn)生歧義,所以筆者盡量使用規(guī)范中的專有名詞來解釋。所以,請(qǐng)讀者在閱讀時(shí)一定要注意。
說明:1)一些專有名詞以前的章節(jié)中已經(jīng)發(fā)布,這里不再介紹。2)筆者本人水平有限,文章中所使用的專有名詞中文命名或解釋可能和其他網(wǎng)上的的有所不同,建議讀者參考RFC原文理解或者發(fā)郵件給規(guī)范起草人獲得支持。
筆者會(huì)在接下來的內(nèi)容中重點(diǎn)討論關(guān)于ICE的背景介紹,ICE概覽,ICE使用/ICE候選地址采集和交互,ICE候選對(duì)象流程處理,執(zhí)行連接性檢查,完成ICE創(chuàng)建,輕量級(jí)ICE使用介紹等話題。
1、背景介紹
如果讀者看過前面的SDP全解的讀者可能已經(jīng)了解,SIP使用了offer/answer結(jié)合模式,通過SDP消息來實(shí)現(xiàn)媒體傳輸,其最終目的是實(shí)現(xiàn)媒體流之間的創(chuàng)建和完整傳輸。ICE英文全名是Interactive Connectivity Establishment。RFC5245(更新的RFC6336)對(duì)ICE做了規(guī)定。筆者推薦的一般簡單的定義是:ICE=STUN+TURN+協(xié)商機(jī)制+協(xié)商路徑。
但是,因?yàn)榫W(wǎng)絡(luò)越來越復(fù)雜,終端的環(huán)境也發(fā)生了根本變化,因此NAT問題也越來越多。RFC3235規(guī)范針對(duì)NAT(地址轉(zhuǎn)換)發(fā)布了一個(gè)指導(dǎo)。很多相關(guān)的協(xié)議希望通過媒體流之間的點(diǎn)對(duì)點(diǎn)傳輸解決媒體本身的問題(例如,低時(shí)延,降低丟包,降低部署成本),但是在涉及到NAT環(huán)境時(shí),通常會(huì)遇到一些更加復(fù)雜的問題,導(dǎo)致實(shí)際部署的難度大大增加。為了解決NAT的問題,很多針對(duì)性的技術(shù)規(guī)范增加了對(duì)NAT環(huán)境的支持,常見的規(guī)范包括:
- Application Layer Gateways (ALGs)
- Middlebox Control Protocol (RFC 3303)
- STUN(RFC 3489)
- Realm Specific IP(RFCs 3102和3103)
- SDP拓展支持(RFC 4566和RFC 3605)
隨著技術(shù)本身的不斷發(fā)展,這些針對(duì)NAT支持的規(guī)范也帶來了很多突出的問題,它們都存在各自的優(yōu)缺點(diǎn)。這樣的話,網(wǎng)絡(luò)管理就會(huì)增加很多的不確定性,給系統(tǒng)管理帶來很多問題。為了解決這些問題,一些相關(guān)規(guī)范組織希望使用一種統(tǒng)一的解決方式或規(guī)范,并且這種協(xié)議可以提供靈活性來滿足目前網(wǎng)絡(luò)環(huán)境對(duì)NAT的支持。目前,大家一致的共識(shí)就是使用ICE技術(shù)(Interactive Connectivity Establishment)。此規(guī)范通過offer/answer模式定義ICE來支持基于UDP的媒體流NAT問題(當(dāng)然,ICE也可以通過拓展支持ICE-TCP傳輸協(xié)議)。
ICE是offer/answer模式的一種拓展形式,通過在SDP的offer/answer消息中包含多個(gè)地址和端口,使用這些地址端口和其交互消息來檢測點(diǎn)對(duì)點(diǎn)的連接性。在SDP中的地址和端口,以及其連接性檢測是通過STUN來完成。
圖片來自于互聯(lián)網(wǎng)資源
注意,關(guān)于STUN的最新規(guī)范已經(jīng)再次更新(更新時(shí)間為2020年),如果讀者有興趣做進(jìn)一步研究,可參考RFC5389和RFC8489。除了STUN以外,ICE也使用了STUN的另外一個(gè)拓展協(xié)議-TURN(RFC5766)實(shí)現(xiàn)穿越轉(zhuǎn)發(fā)。另外,因?yàn)镮CE對(duì)每個(gè)媒體流進(jìn)行了多地址和端口交互,它也允許地址選擇支持多宿主和雙棧主機(jī)(IPv4/IPv6),因此也不再支持RFC4091和RFC4092。
2、ICE概覽
在一個(gè)比較典型的ICE部署環(huán)境中,至少需要兩個(gè)終端需要互相進(jìn)行通信。終端之間可以通過一些信令結(jié)合SDP的offer/answer模式來實(shí)現(xiàn),例如,我們前面講的SIP協(xié)議。讀者需要注意,ICE的目的不是為了某些協(xié)議(例如SIP)的NAT穿越,關(guān)于SIP相關(guān)的NAT穿越是通過RFC5626規(guī)定的,如果讀者有興趣的話,可以查閱此規(guī)范。這里,ICE假設(shè)終端之間可以創(chuàng)建協(xié)議連接。具體來說,在ICE流程處理開始階段,agents就忽略了它們本身的技術(shù)屬性。終端也可能在或不在NAT后(例如后面將的輕量級(jí)部署終端),ICE允許終端獲取到技術(shù)屬性的足夠信息,然后找到一個(gè)或多個(gè)潛在的路徑,創(chuàng)建數(shù)據(jù)會(huì)話實(shí)現(xiàn)相互連接。
圖片均來自于互聯(lián)網(wǎng)資源
在以上示例是一個(gè)非常典型的ICE部署場景示例。兩個(gè)終端分別標(biāo)識(shí)為L(左邊)和R(右邊)。兩個(gè)終端都有各自的NAT環(huán)境,雙方也不清楚對(duì)端NAT的狀態(tài)屬性,左右雙方終端都有意愿通過ICE候選對(duì)象交互實(shí)現(xiàn)通信。很多時(shí)候,雙方的交互可能都使用SIP協(xié)議。對(duì)于雙方終端,SIP服務(wù)器和NAT來說,在網(wǎng)絡(luò)中,ICE經(jīng)常使用STUN和TURN來保證所有對(duì)象的協(xié)同。每個(gè)終端agents可以支持自己獨(dú)立的STUN和TRUN服務(wù)器,也可以同一STUN和TURN同一服務(wù)器;镜腎CE工作理念是: 針對(duì)傳輸協(xié)議(這里重點(diǎn)討論UDP)每個(gè)agent都有各種候選地址(綁定了IP地址和端口),通過這種候選地址和對(duì)端agent實(shí)現(xiàn)通信。候選地址可能包括:附加到網(wǎng)絡(luò)接口的傳輸?shù)刂罚╯erver reflexive 地址,其地址是STUN發(fā)現(xiàn)的地址,在NAT外),NAT中公網(wǎng)側(cè)的轉(zhuǎn)換后的傳輸?shù)刂,從TURN分配到的傳輸?shù)刂罚ㄞD(zhuǎn)發(fā)地址)?陀^上存在這種可能,任何L側(cè)的候選傳輸?shù)刂范加脕砗腿魏蜶側(cè)的候選傳輸?shù)刂愤M(jìn)行通信。但是,在實(shí)際場景中,過多的候選傳輸?shù)刂方M合可能不能工作。例如,如果L側(cè)和R側(cè)雙方都在NAT后的話,直接附加的網(wǎng)絡(luò)接口地址可能不會(huì)直接通信,因此這里需要ICE介入。這里,ICE的目的是發(fā)現(xiàn)何種候選地址配對(duì)可以工作。ICE的工作方式是通過系統(tǒng)地嘗試所有可能的候選配對(duì)(排序處理后),直到ICE找到一組或者多組可以工作的候選配對(duì)。ICE對(duì)Peers的檢測配對(duì)需要經(jīng)過幾個(gè)核心步驟:
3、采集候選地址
如果需要執(zhí)行ICE的話,agent首先需要確認(rèn)候選地址。候選地址是一種特別的地址,它是由IP地址和端口的組合構(gòu)成,其目的是支持傳輸協(xié)議(我們這里僅討論UDP)。RFC8445定義了三種候選地址,一種是來自于物理網(wǎng)絡(luò)接口,另外一種來自于網(wǎng)絡(luò)的邏輯接口,還有一種是通過STURN或者TURN發(fā)現(xiàn)的候選地址。第一種類別的候選地址支持的傳輸?shù)刂分苯訌谋镜鼐W(wǎng)絡(luò)接口獲得。這樣的候選地址我們稱之為“host candidate”,這樣類型的本地地址可以從本地網(wǎng)絡(luò),WIFI,遠(yuǎn)端網(wǎng)絡(luò)或者VPN的方式獲得。對(duì)agent來說,這樣的地址都可以通過分配獲得,并且作為本地接口來使用。如果agent是一個(gè)多宿主主機(jī)的話,它可以從不同的IP地址獲得候選地址。具體的候選地址如何獲得取決于網(wǎng)絡(luò)中peer(會(huì)話中另外一個(gè)agent)的位置。例如,如果agent支持了兩個(gè)不同的IP地址的話(一個(gè)是內(nèi)網(wǎng)地址,一個(gè)是外網(wǎng)地址),不同的peer就可以通過不同的地址和agent通信。
另外一種候選地址是agent使用STUN或TURN獲得的額外的候選地址,這些候選地址主要表現(xiàn)為兩種地址形式:NAT公網(wǎng)側(cè)的已轉(zhuǎn)換地址(server-reflexive 候選地址),TURN服務(wù)器分配的轉(zhuǎn)發(fā)地址(relayed 候選地址)。這里讀者一定要注意兩種地址的獲取方式。當(dāng)使用TURN服務(wù)器時(shí),以上兩種候選地址都來自于TURN服務(wù)器分配地址;當(dāng)僅使用了STURN服務(wù)器的話,agent只能獲取到server reflexive地址。以下是候選地址的關(guān)系示例圖:
候選地址關(guān)系
在以上關(guān)系圖中,兩種類型的候選地址都是通過TURN服務(wù)器發(fā)現(xiàn)獲得的。這里的地址端口配對(duì)中,大寫X表示IP地址,小寫x表示UDP端口。當(dāng)agent對(duì)IP地址和端口發(fā)送一個(gè)(X:x)TURN地址分配請(qǐng)求時(shí),NAT(假設(shè)這里有NAT)就會(huì)創(chuàng)建一個(gè)綁定關(guān)系X1':x1',映射server-reflexive地址到主機(jī)候選地址。從本地主機(jī)候選地址發(fā)送出去的數(shù)據(jù)包將會(huì)通過NAT地址轉(zhuǎn)換變成一個(gè)server-reflexive候選地址。同樣的道理,從server-reflexive候選地址進(jìn)入到主機(jī)候選地址的數(shù)據(jù)也是通過NAT地址轉(zhuǎn)換完成。這里,base是一個(gè)比較重要的概念,需要讀者明確,“base"是一個(gè)本地主機(jī)候選地址,它關(guān)聯(lián)一個(gè)給定的server-reflexive候選地址。base指的是一個(gè)agent為指定的候選地址發(fā)出數(shù)據(jù)的地址。因此,有時(shí)存在一個(gè)比較極端的場景,主機(jī)候選地址也可以有自己的base地址,這個(gè)base 地址和主機(jī)候選地址相同。
來自于互聯(lián)網(wǎng)資源
當(dāng)agent和TURN服務(wù)器存在多個(gè)NAT穿越時(shí),TRUN請(qǐng)求會(huì)為每個(gè)NAT創(chuàng)建一個(gè)綁定,但是agent僅發(fā)現(xiàn)最外部的server-reflexive候選地址(距離TRUN服務(wù)器最近的候選地址)。如果agent不在NAT后的話,base 候選地址和server-reflexive候選地址相同,server-reflexive候選地址就會(huì)被移除。
Agent發(fā)出的分配請(qǐng)求到達(dá)TURN服務(wù)器端后,TURN服務(wù)器將會(huì)從它的本地IP地址Y中分配一個(gè)端口y,并且生成一個(gè)分配響應(yīng),分配響應(yīng)通知一個(gè)agent的轉(zhuǎn)發(fā)候選地址。TRUN服務(wù)器也會(huì)通知一個(gè)agent的server-reflexive候選地址X1':x1',通知的方式是把分配請(qǐng)求中的源傳輸?shù)刂房截惖椒峙漤憫?yīng)中來實(shí)現(xiàn)。TRUN服務(wù)器的工作角色類似于一個(gè)在L側(cè)和R側(cè)之間的數(shù)據(jù)轉(zhuǎn)發(fā)。如果R側(cè)想對(duì)L側(cè)發(fā)送數(shù)據(jù)的話,R側(cè)需要發(fā)送數(shù)據(jù)到Y(jié):y 地址,然后TRUN服務(wù)器端前轉(zhuǎn)到X1':x1'候選地址,然后經(jīng)過NAT后映射到L側(cè)agent。
當(dāng)僅使用了STUN服務(wù)器時(shí),agent發(fā)送一個(gè)STUN綁定請(qǐng)求給它的STUN服務(wù)器,STUN將會(huì)通知一個(gè)agent的server-reflexive候選地址X1':x1',其通知的方式是綁定請(qǐng)求中的源傳輸?shù)刂房截惖浇壎憫?yīng)中。
4、連接性檢查
一旦L側(cè)agent采集到它所有的候選地址后,它會(huì)把這些地址重新按照從最高到最低的排序,然后通過信令通道發(fā)送給R側(cè)agent。這些候選地址通過SDP的offer消息的屬性參數(shù)發(fā)送到R側(cè)agent(開始使用offer/answer交互模式)。當(dāng)R側(cè)agent收到offer消息后,R側(cè)的agent也會(huì)執(zhí)行一個(gè)同樣的流程來采集候選地址,然后通過響應(yīng)消息返回自己的候選地址。雙方采集發(fā)送流程完成以后,每個(gè)agent都有自己的完整的候選地址和對(duì)待peer的完整候選地址。通過雙方候選地址的配對(duì)處理,最后產(chǎn)生一個(gè)候選配對(duì)。候選地址配對(duì)產(chǎn)生以后,agent首先需要知道哪個(gè)候選地址配對(duì)是可以工作的,每個(gè)agent會(huì)按時(shí)設(shè)定一系列的檢查。每個(gè)檢查是一個(gè)STUN請(qǐng)求響應(yīng)的事務(wù),每個(gè)終端都會(huì)執(zhí)行具體的候選地址配對(duì)流程,配對(duì)流程檢查通過本地候選地址對(duì)遠(yuǎn)端候選地址發(fā)送一個(gè)STUN請(qǐng)求。連接性檢查(Connectivity Checks)的基本原理非常簡單:
- 對(duì)候選地址配對(duì)進(jìn)行優(yōu)先級(jí)排序
- 按照優(yōu)先級(jí)排序順序?qū)蜻x配對(duì)發(fā)送檢查請(qǐng)求
- 確認(rèn)從其他agent收到檢查狀態(tài)
因此,在執(zhí)行候選配對(duì)檢查時(shí)需要一個(gè)四次握手的處理:
基本候選地址配對(duì)檢查四次握手處理流程
這里一定要注意,發(fā)送STUN請(qǐng)求的目的地和接收源的IP地址和端口,這是完全相同的IP地址和端口,使用此IP地址和端口來傳輸媒體流(包括RTP和RTCP)。因此,agent會(huì)通過數(shù)據(jù)內(nèi)容多路分解STUN/RTP/RTCP相關(guān)數(shù)據(jù),而不使用其接收端口來分解STUN/RTP/RTCP數(shù)據(jù)。相對(duì)于使用端口的方式來說,多路分解方式會(huì)更容易處理檢查狀態(tài),特別是針對(duì)RTP和RTCP的數(shù)據(jù)。因?yàn),STUN綁定請(qǐng)求是用來執(zhí)行連接檢查的,在STUN響應(yīng)中包含了agent的已轉(zhuǎn)譯的傳輸?shù)刂,這個(gè)地址是agent和對(duì)端peer之間的NAT公網(wǎng)側(cè)地址。如果這個(gè)傳輸?shù)刂泛蚢gent已學(xué)習(xí)過的候選地址不同的話,agent就會(huì)知道這個(gè)候選地址是一個(gè)新的地址(PEER REFLEXIVE CANDIDATE),這個(gè)新地址和其他候選地址一樣,也是ICE測試過的地址。
作為一種優(yōu)化方式,只要R側(cè)獲得了L側(cè)的檢查消息,R側(cè)會(huì)在同一候選配對(duì)中按時(shí)對(duì)L側(cè)發(fā)送一個(gè)連接檢查消息。這樣的話,ICE就會(huì)加快發(fā)現(xiàn)有效候選流程處理時(shí)間,這個(gè)過程也稱之為“TRIGGERED CHECK”。在雙方握手完成以后,雙方都知道對(duì)對(duì)端可以接收或者發(fā)送端對(duì)端消息。到此為止,連接檢查結(jié)束。
5、候選地址排序
根據(jù)連接檢查的介紹,讀者可能已經(jīng)注意到了,前面我們討論的候選配對(duì)查詢算法還有一定的問題,假設(shè)候選配對(duì)存在的話,無論查詢方式是何種順序,查詢流程會(huì)一直查詢直到找到這一對(duì)候選配對(duì)。顯然,查詢的順序肯定影響候選配對(duì)的查詢結(jié)果。因此,為了快速生成候選配對(duì)結(jié)果,候選地址需要經(jīng)過排序處理,最后,排序后的候選配對(duì)結(jié)果就是一個(gè)check list。關(guān)于排序算法筆者在發(fā)送初始o(jì)ffer的章節(jié)進(jìn)行討論。基本上,排序算法需要遵守兩個(gè)基本原則:
每個(gè)agent給它的候選地址一個(gè)優(yōu)先級(jí)數(shù)字標(biāo)識(shí),此優(yōu)先級(jí)標(biāo)識(shí)會(huì)隨候選地址發(fā)送到對(duì)端peer。
本地和遠(yuǎn)端優(yōu)先級(jí)合并,每個(gè)agent針對(duì)候選配對(duì)來說有一個(gè)同樣的排序。
其中,第二個(gè)原則非常重要。如果雙方L側(cè)agent和R側(cè)agent的都在NAT后的話,為了確保ICE工作,必須特別注意第二個(gè)原則。我們經(jīng)?梢钥吹,NAT是不會(huì)允許一臺(tái)外部主機(jī)發(fā)送數(shù)據(jù)進(jìn)入到NAT后的網(wǎng)絡(luò)環(huán)境中,只有在NAT后的agent通過NAT發(fā)送數(shù)據(jù)給這臺(tái)主機(jī)后才被允許交互,外部數(shù)據(jù)才能進(jìn)入到NAT后的環(huán)境中。這里要注意,直到agent雙方都已通過自己相關(guān)的NAT穿越發(fā)送check信息后,雙向的ICE check才能最終成功。agent需要通過check list才能啟動(dòng)工作,所以,它需要周期性地發(fā)送一個(gè)STUN請(qǐng)求獲得列表中的候選配對(duì)。這個(gè)處理過程稱之為 “ORDINARY CHECKS”。
通常情況下,優(yōu)先級(jí)算法的設(shè)計(jì)是為了同類候選地址直接獲得同樣的優(yōu)先級(jí),和一些非直接處理的方式相比,優(yōu)先級(jí)算法在處理候選配對(duì)是可能更加高效。因此,通過優(yōu)先級(jí)算法的處理流程可以快速高效地實(shí)現(xiàn)直接路由訪問,路由處理路徑中僅需要幾個(gè)媒體轉(zhuǎn)發(fā)和幾個(gè)NAT轉(zhuǎn)發(fā)。如果采用非直接處理的方式的話,候選配對(duì)可能需要更多媒體轉(zhuǎn)發(fā)和NAT轉(zhuǎn)發(fā),經(jīng)過越多的轉(zhuǎn)發(fā)就會(huì)導(dǎo)致越多的不可控因素。所以,這樣的方式不是一種好的推薦的方式。但是,agent都有自己的決定權(quán)來優(yōu)化算法。
6、鎖定候選配對(duì)
前面的討論中,我們僅僅描述了一種場景,那就是agents想使用一個(gè)組件模塊(COMPONENT)創(chuàng)建一個(gè)媒體會(huì)話。這里,COMPONENT是一個(gè)媒體流。在典型的應(yīng)用環(huán)境中,agents實(shí)際需要?jiǎng)?chuàng)建一個(gè)連接來支持更多的數(shù)據(jù)流程。網(wǎng)絡(luò)環(huán)境中的很多屬性和組件具有非常大的相似度。通常情況下,如果一個(gè)組件模塊可以工作的話,我們會(huì)借用同樣的信息來決定最近的候選地址。ICE使用這樣的處理方式來處理候選配對(duì)流程,這種算法簡稱為frozen candidates或者鎖定候選算法。每個(gè)候選地址都和自己的一個(gè)屬性相關(guān)聯(lián),我們稱這個(gè)屬性為“FOUNDATION”。如果它們被認(rèn)為是“相似”的話,我們就會(huì)認(rèn)為他們具有相同的FOUNDATION屬性,這表示它們有相同的類型,并且都是從同一host candidate,同樣的STUN服務(wù)器,使用同樣的協(xié)議獲得的類型數(shù)據(jù)。否則,這樣的候選地址就是不同的。同樣的道理,候選配對(duì)也有FOUNDATION屬性。這個(gè)候選配對(duì)的FOUNDATION就是通過合并候選地址的FOUNDATION構(gòu)成。在初始階段,只有針對(duì)FOUNDATION是唯一狀態(tài)的候選配對(duì)進(jìn)行測試。其他的候選配對(duì)會(huì)被標(biāo)識(shí)為“frozen” 或者鎖定狀態(tài)。當(dāng)候選配對(duì)的連接檢查是成功狀態(tài)的話,其他帶相同F(xiàn)OUNDATION屬性的候選配對(duì)被unfrozen或者解封。通過這樣的方式就可以避免了重復(fù)的連接性檢查,增加檢查的效率。但是,事實(shí)上,這種方式也有失敗的可能。frozen candidates是ICE處理流程的一部分,ICE有優(yōu)先級(jí)的算法會(huì)自動(dòng)使用正確的順序確保正確的候選地址被解封。
這里筆者再花費(fèi)一點(diǎn)時(shí)間再一點(diǎn)補(bǔ)充說明。在筆者接觸到的資源中,很多關(guān)于WebRTC/ICE的技術(shù)討論,以及相關(guān)的官方中,包括RFC5245本身也沒有非常完整地解釋清楚“frozen”的定義。這里,筆者試圖借用一定的示例來進(jìn)一步明確說明frozen candidates的具體含義。首先,我們來解釋一下在我們討論的場景中具體的frozen定義。如果我們單純從字面意思, 筆者認(rèn)為可以理解frozen為封凍或者鎖定的含義。接下來讀者就容易理解frozen candidates的完整含義。從前面的解釋,我們可以看到frozen candidates就是一種候選地址的狀態(tài)。
來自于互聯(lián)網(wǎng)資源
每個(gè)在check list中的候選配對(duì)都有自己的狀態(tài),具體的狀態(tài)處理經(jīng)過以下幾個(gè)步驟:
- Frozen – 處于鎖定狀態(tài),等待檢查。
- Waiting – 從check list中選擇最高優(yōu)先級(jí)的候選配對(duì)進(jìn)行處理。
- In-Progress – 為這個(gè)配對(duì)發(fā)送check請(qǐng)求,事務(wù)在處理流程中。
- Succeeded – 配對(duì)檢查成功
- Failed – 配對(duì)檢查失敗
7、安全檢查
大家知道,ICE的目的是發(fā)現(xiàn)兩個(gè)agent之間的地址,通過這個(gè)地址來發(fā)送媒體流數(shù)據(jù)。當(dāng)然,ICE必須確保這個(gè)地址不能出現(xiàn)安全問題,也必須避免把媒體數(shù)據(jù)發(fā)送到錯(cuò)誤的地址。每個(gè)STUN的連接性檢查都要經(jīng)過消息認(rèn)證碼(MAC)的計(jì)算,消息認(rèn)證碼在信令通道中使用密鑰交換的方式進(jìn)行計(jì)算。因?yàn)镸AC提供了消息完整性和數(shù)據(jù)原始認(rèn)證,因此它可以杜絕攻擊者偽造和修改連接性檢查消息內(nèi)容。一個(gè)比較典型的例子就是SIP的分叉呼叫處理。如果SIP呼叫用戶正在使用ICE,并且此呼叫進(jìn)行了分叉呼叫處理的話,ICE處理就會(huì)在每個(gè)獨(dú)立的接收方之間進(jìn)行。這種使用場景中,在信令通道中的密鑰交換幫助每個(gè)ICE交換和其分叉的接收方進(jìn)行交換處理。如果讀者不了解分叉呼叫的內(nèi)容,可以查閱本微信號(hào)的歷史文章-關(guān)于分叉呼叫流程的處理。
8、完成ICE創(chuàng)建
通過前面的介紹,我們知道ICE檢查是需要按照順序處理的。ICE首先處理優(yōu)先級(jí)最高的候選配對(duì),然后再處理低優(yōu)先級(jí)的候選配對(duì)。只要每個(gè)模塊的媒體流檢查都成功以后,ICE通過聲明一個(gè)“成功”表示候選配對(duì)成功,整個(gè)ICE的創(chuàng)建就完成了。這種操作方式確實(shí)也是比較合理的,我們會(huì)在后續(xù)的文章中介紹具體的算法。但是,任何事情都有其兩面性,通過這種按照優(yōu)先級(jí)高低來執(zhí)行候選配對(duì)檢查的算法需要考慮一定的風(fēng)險(xiǎn)。如果最高優(yōu)先級(jí)的候選配對(duì)產(chǎn)生了數(shù)據(jù)丟失的問題,這樣就會(huì)耗費(fèi)了稍長時(shí)間完成配對(duì)檢查。這種情況下,ICE可能需要花費(fèi)稍長時(shí)間,但是可能會(huì)產(chǎn)生比較好的結(jié)果。從根本上來說,RFC5245官方規(guī)定的優(yōu)先級(jí)算法不一定會(huì)產(chǎn)生“優(yōu)化”的結(jié)果。如果其算法的目的是選擇低時(shí)延的媒體路徑的話,使用了轉(zhuǎn)發(fā)(轉(zhuǎn)發(fā)可能是高延時(shí))作為一種建議提示的話,這種轉(zhuǎn)發(fā)建議實(shí)際上就沒有多大關(guān)系。實(shí)際場景中可能使用往返時(shí)延(RTT)的衡量指標(biāo)的方式可能比優(yōu)先級(jí)的處理方式更好,在演示中場景中,低優(yōu)先級(jí)的候選配可能比高優(yōu)先級(jí)的候選配對(duì)取得更低的時(shí)延。
標(biāo)識(shí)成功配對(duì)以后,接下來,ICE就會(huì)指定agent的功能角色。其中一個(gè)agent稱之為CONTROLLING AGENT(主控agent),另外一個(gè)agnet是CONTROLLED AGENT(被控agent)。主控agent就會(huì)從有效的候選配對(duì)中指定一個(gè)配對(duì)來應(yīng)對(duì)媒體處理。主控agent通過兩種方式來實(shí)現(xiàn)指定候選配對(duì):使用regular nomination或者使用aggressive nomination的方式來指定候選配對(duì)。
來自于互聯(lián)網(wǎng)資源
使用regular nomination正常指定候選配對(duì)的話,主控方agent會(huì)一直發(fā)送請(qǐng)求消息,讓check處理進(jìn)行處理,直到找到至少一個(gè)有效的候選配對(duì)可以支持媒體。然后選擇其有效的候選配對(duì)。接下來主控agent仍然會(huì)繼續(xù)發(fā)送第二個(gè)STUN請(qǐng)求消息,但是,在第二個(gè)STUN請(qǐng)求中,主控agent會(huì)附加一個(gè)flag,通知對(duì)端,主控agent已經(jīng)指定了一個(gè)候選配對(duì),將要使用那個(gè)候選配對(duì)來處理媒體流。當(dāng)攜帶flag的這個(gè)STUN事務(wù)完成以后,雙方都取消了進(jìn)一步的check流程。ICE將使用最終指定的那個(gè)有效配對(duì)發(fā)送媒體。ICE正在使用的這對(duì)候選配對(duì)稱之為“SELECTED PAIR”,成為已選配對(duì)。所以,讀者一定要明白,ICE是真正使用selected pair來進(jìn)行媒體處理的,前面所有的候選配對(duì)都是為ICE最后選擇配對(duì)進(jìn)行準(zhǔn)備。
上面,筆者介紹了正常指定配對(duì)的方式,這里我們?cè)俳榻B一下aggressive nomination的使用方式。aggressive nomination的方式相對(duì)比較激進(jìn)或主動(dòng)一點(diǎn)。主控agent使用aggressive nomination時(shí),主控agent會(huì)在每個(gè)STUN請(qǐng)求中附加一個(gè)flag,一旦找到第一個(gè)成功的配對(duì)的話,ICE就會(huì)結(jié)束其他的檢查流程,然后使用其配對(duì)處理媒體,主控agent不會(huì)再發(fā)送第二個(gè)STUN請(qǐng)求。此selected pair具有最高的優(yōu)先級(jí)。所以,我們通過兩種方式的介紹,我們可以看出,aggressive nomination檢查速度快,但是缺少靈活性;regular nomination則處理速度慢,但是可能會(huì)找到低時(shí)延的媒體路徑。
一旦所有的媒體處理完成后,如果媒體中“m=”和“c=”行中的候選地址(默認(rèn)候選)不能匹配selected pair(已選配對(duì))的話,主控端會(huì)發(fā)送一個(gè)更新offer消息。如果ICE結(jié)束后,為了支持agent的媒體流,任何一方agent都可以在任何時(shí)間重新啟動(dòng)ICE。重新啟動(dòng)ICE可以通過agent發(fā)送一個(gè)更新offer的方式來處理。
9、ICE 輕量級(jí)部署討論
為了讓呼叫支持ICE,雙方agent必須都使用ICE。但是,在實(shí)際環(huán)境中,某些agent本身就帶了公網(wǎng)地址,它可以從任何通信端接收數(shù)據(jù)或者進(jìn)行通信。為了讓這類終端能夠方便地支持ICE,ICE定義了一種特別的部署方式,稱之為lite implementation,或者輕量級(jí)部署方式。當(dāng)然,相對(duì)于lite implementation的支持方式,ICE支持正常的full implementation全部署方式。因?yàn)檫@類帶國外地址的終端本身帶有公網(wǎng)地址,所以,輕量級(jí)的部署方式會(huì)減少很多中間處理環(huán)節(jié)。首先,它不采集候選地址,它也不包含支持媒體的主機(jī)候選地址(一般的內(nèi)網(wǎng)地址)。另外,雖然它們需要返回響應(yīng)消息,但是,這類agent不會(huì)生成連接檢查或運(yùn)行狀態(tài)機(jī)。當(dāng)兩個(gè)輕量級(jí)agent連接時(shí)無需發(fā)送檢查請(qǐng)求響應(yīng)消息;可是,當(dāng)使用輕量級(jí)agent和全部署方式連接時(shí),這時(shí),全部署方式的agent會(huì)變?yōu)橹骺豠gent來控制檢查流程,輕量級(jí)agent就會(huì)變?yōu)楸豢豠gent。筆者將會(huì)在后續(xù)章節(jié)或者文章中討論這兩種部署方式的具體細(xì)節(jié)。讀者需要特別注意,輕量級(jí)的部署是針對(duì)全部署方式的一種補(bǔ)充方式,是在RFC5245中稍晚時(shí)間增加的功能支持。針對(duì)那些支持公網(wǎng)地址的終端來說,如果可以實(shí)現(xiàn)全部署方式的話,RFC5245推薦使用全部署方式。
以上都是關(guān)于ICE的熱身流程,包括了基本的概念以及大概的處理流程。后續(xù)文章中,筆者將繼續(xù)介紹ICE處理流程和具體細(xì)節(jié),從真正的第一步處理流程開始-初始化offer的處理,包括初始化offer中的Full Implementation 要求和其具體步驟。
參考資料:
https://anyconnect.com/stun-turn-ice/
https://tools.ietf.org/id/draft-ietf-ice-rfc5245bis-13.html
https://tools.ietf.org/html/rfc8445
https://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment
https://www.ietfjournal.org/interactive-connectivity-establishment/
https://ietf.org/documents/144/IETF_ICE_intro_92.pdf
關(guān)注微信公眾號(hào):asterisk-cn,獲得有價(jià)值的Asterisk行業(yè)分享
Asterisk freepbx FreeSBC技術(shù)文檔: www.freepbx.org.cn
融合通信/IPPBX商業(yè)解決方案:www.hiastar.com
如何使用FreeSBC,qq技術(shù)分享群:334023047, www.freesbc.cn