筆者在前面的完整介紹了關於後續offer/answer交互過程中offer接收和answer生成的細節。這裡,筆者將介紹後續offer/answer交互中的最後一個部分-ICE選項支持,狀態更新以及存活時間的討論。在更新狀態中又涉及了全場景部署的處理流程和輕量級場景的部署流程。現在,我們逐一介紹這些細節。
1、全場景部署處理流程
在全場景部署的更新處理流程中涉及了四個方面的內容需要討論。首先,我們介紹一下關於ICE重新啟動的內容。
在ICE重新啟動之前,針對媒體流的每個構件,agent必須記住在有效列表中的最高優先級標識的配對(稱之為歷史已選配對)。Agent將會繼續使用這些配對發送媒體流。發送媒體流的流程在後面的文章中會加以討論。一旦目的地地址收到提示信息,agent必須刷新有效列表和檢查列表中的數據。然後agent重新計算檢查列表和其狀態。具體處理流程參考歷史文章中關於構建檢查列表的流程。
如果在offer/answer交互中已添加了一個新的媒體流,agent必須為此新媒體流創建一個新的檢查列表,還創建一個新的初始為空的有效列表。具體處理流程參考歷史文章中關於構建檢查列表的流程。
如果在offer/answer交互要移除一個媒體流或answer拒絕了offer中提供的媒體流的話,agent必須為此媒體流刷新有效列表,必須結束在任何處理過程的STUN事務。agent必須為此媒體流移除檢查列表,並且取消任何待處理的ordinary checks。
針對全場景部署中的更新有效列表和檢查列表,ICE的處理根據agent的狀態和檢查列表狀態的不同存在很多不同流程。首先說明,除非正在ICE重新啟動,否則有效列表是不會受更新offer/answer交互影響。
針對一個媒體流來說,如果agent的狀態是正在運行狀態,檢查列表是已更新狀態(如果狀態是完成狀態,檢查列表已無相關性)。為了實現這個要求,agent必須使用計算流程重新計算檢查列表。具體處理流程參考歷史文章中關於構建檢查列表的流程。在計算結果中,如果發現在檢查列表中有一對配對已經是全面檢查列表中出現的配對的話,其配對狀態是Waiting,In-Progress,Succeeded或Failed狀態的話,其狀態將被拷貝到檢查列表中;否則其狀態將設置為封凍狀態(Frozen)。
如果檢查列表中無任何活動配對(意味著每個檢查列表中的配對是封凍狀態),full-mode(雙方agent都使用了ICE)的 agent為第一個媒體流在有效列表中設置第一個配對,設置的第一個配對的狀態為等待狀態,然後把在檢查列表中具有同樣component ID和具有同樣foundation所有其他配對設置為等待狀態。
接下來,agent會逐一執行某個檢查列表,最高優先級的配對首先開始執行。如果列表中有一個配對狀態是成功狀態,其component ID設置為1,然後繼續執行以下處理。在同樣檢查列表中,如果所有其他封凍狀態的配對具有同樣foundation,並且在這些具有同樣foundation配對中,如果它們的component ID不是1的話,agent將把這些封凍的配對的狀態設置為等待狀態。針對一個具體的檢查列表,如果媒體流的每個構件的配對有一對在成功狀態,為其他所有媒體流的第一個構件(可能在不同的檢查列表中),agent將會把所有具有同樣foundation,其配對狀態處於封凍狀態的配對的狀態進行狀態遷移,這些配對的狀態從封凍狀態設置為等待狀態。
2、輕量級場景部署場景
輕量級的部署場景中關於更新列表檢查的處理比較簡單。如果為一個媒體流重新啟動ICE,agent也必須為此媒體流重新啟動一個有效列表。Agent也必須記得此媒體流的每個構件的上次有效列表中的配對(稱之為歷史已選配對)。然後根據流程繼續發送媒體流。流程的規則定義在將來的文章中介紹。接下來,針對每個媒體流的ICE處理狀態必須修改為正在運行狀態。
3、ICE option標識
在實際應用場景中,我們經常遇到一些用戶的反饋WebRTC的兼容性問題,自己也經常面臨WebRTC的兼容性問題。我們不得不經常更新一些功能支持,同時也不得不不斷學習新的知識。其實,我們從RFC5245以及其最新規範8445中就可以看出,這些處理流程在最近幾年內進行了很多次修改。現在,我們介紹一個特殊的ICE選項。除了在RFC5245中規定的ICE啟動流程以外,在最新的RFC8445中增加了一個ICE選項-ice2 選項。當ICE agent在候選交互中包含了ice2選項以後,表示需要遵從RFC8445規範。在一些特定的交互中使用ice2讓對端peer獲悉agent也不再使用此交互流程。例如,在RFC8445中已經移除了主動推薦標識的流程(aggressive nomination procedure),如果agent需要通知對端不再使用此交互流程時,可以增加一個ice2選項來表示。
一個agent如果遵從RFC8445的話,在候選地址交互開始時必須通過ice2通知對端peer其交互模式啟用了ice2選項。否則,對端可能收到一個未知的ice選項。
關於對ice2的編碼和對對端peer的消息傳輸,讀者可以參與RFC4566中的參考規範。在其參考規範中詳細說明了ICE-SIP-SDP的細節。最新的草案參考連結如下:
ice-sip-sdp:
https://tools.ietf.org/html/draft-ietf-mmusic-ice-sip-sdp-39
另外,再次提醒讀者,如果要開發最新的SIP和WebRTC的業務應用的話,因為ICE處理流程中SDP的頻繁更迭,讀者一定要關注最新的RFC8445規範以及關於SDP構建的草案。
4、Keepalives
無論是否使用ICE或者媒體流的狀態如何,keepalives是終端保持存活的重要手段。大家知道,為了終端保持狀態的活動狀態,所有的終端都必須不斷向伺服器端發送存活消息。針對媒體會話來說,存活消息的目的就是為了保持NAT綁定存活狀態。無論媒體流狀態是inactive,sendonly,recvonly還是sendrecv狀態,並且也不管在線狀態,帶寬屬性設置狀態,終端必須發送keepalives。即使周期會話中完全沒有使用ICE,終端也必須發送keepalives。終端應該使用對端peer能夠支持的格式來發送keepalives。ICE終端允許基於STUN的keepalives支持UDP的流。具體來說,當agent是一個全場景部署的agent,並且和對端peer(輕量級部署場景或全場景部署agent)通信時,它們之間必須使用STUN keepalives。agent能夠通過每個媒體會話中屬性a=candidate狀態決定對端peer支持ICE。如果對端peer不支持ICE的話,keepalives數據包格式的選擇是本地部署的事情。根據RFC5245的推薦,keepalives的格式最好是這樣的格式-在實際媒體內容缺失的情況在,其格式支持數據可以非常容易發送出去。比較典型的兩個例子是RTP No-Op和RTP的舒適噪音處理。如果對端peer不支持任何目前比較採用的keepalives格式的話,agent應該使用一個不正確的版本發送RTP數據包或者其他格式發送(當然,peer可能會丟棄這些錯誤數據)。
在Tr秒時間內,為了一個媒體構件的處理流程,ICE使用一個候選配對發送數據,如果此候選配對中沒有數據發送,agent必須為此配對生成一個keepalives。Tr值應該是可配置的值,默認設置為15秒。Tr值一定不能低於15秒設置。另外一種處理方式是,如果agent通過動態方式可以發現intervening NAT的綁定生命周期的話,agent可以使用這個綁定生命周期來設置Tr值。系統管理人員是在自己可控的網絡環境中部署ICE,在網絡環境允許的情況下,Tr值應該儘可能的長一點。
如果keepalives使用了STUN,STUN綁定指示需要根據RFC5389規範來執行。此綁定指示不能使用任何認證機制。綁定指示中一個包含FINGERPRINT屬性實現多路分用,但是不能包含任何其他的屬性。此綁定指示僅用來維持NAT綁定存活處理。綁定指示通過同樣的發送媒體的本地和遠端候選地址來發送。雖然綁定指示是用來處理keepalives,但是agent仍然也需要準備好接收連接檢查。如果agent收到了一個連接檢查的話,agent應該根據RFC5389生成一個響應消息,但是,這個處理不會影響ICE的處理。
一旦ICE選擇了候選配對準備發送媒體流,或媒體開始傳輸,無論以上兩種方式哪種方式首先發生,agent必須開始keepalives的流程處理。一旦會話結束或媒體流被移除,keepalives也需要馬上結束。
這裡需要補充一點關於keepalives和Voice Activity Detection (VAD)一些討論。實際環境中,keepalives 在實際數據缺失的情況下發送,所以實際環境中如果沒有使用VAD的話,從來不會產生keepavlives消息發送的情況,因此也不會存在帶寬增加的可能性。當啟用VAD時,keepalives消息是在靜音期發送,會在每15秒-20秒之間發送一個單數據包,此數據所佔用的網絡資源遠小於語音數據發送狀態下的(每20-30毫秒之間發送)所需要的網絡資源。因此,keepalives的影響不會對環境部署中網絡帶寬有很大的影響。
讀者注意,因為keepalives涉及了多種網絡環境的連接,網絡設備的部署也非常複雜,簡單的一種規範很難完整說明全部的具體場景。筆者可以根據不同的場景做進一步的研究:
關於keepalives的優化,讀者可以查閱草案的3.4章節:
https://tools.ietf.org/id/draft-ietf-pcp-optimize-keepalives-00.txt
關於keepalives的討論,一些規範和瀏覽器支持做了一些調整,讀者可以查閱筆者參考資料連結獲得詳情。RFC5245僅提供了ICE的keepalives的討論,讀者也可以結合RFC6263關注RTP中NAT綁定中的keepavlives的討論。
參考資料:
https://www.rfc-editor.org/rfc/rfc5389
https://tools.ietf.org/id/draft-ietf-pcp-optimize-keepalives-00.txt
https://www.cisco.com/c/en/us/support/docs/ip/serial-tunnel-stun/16398-50.html
https://tools.ietf.org/html/draft-muthu-behave-consent-freshness-04
https://tools.ietf.org/html/rfc6263
https://www.semanticscholar.org/paper/NAT-Traversal-Techniques-and-UDP-Keep-Alive-Widmer/9f730e024dd212186c7b2ced75c877edad6951f0
https://www.rfc-editor.org/rfc/rfc8445#section-10
https://tools.ietf.org/html/draft-ietf-mmusic-ice-sip-sdp-39
融合通信/IPPBX商業解決方案:www.hiastar.com
最新Asterisk完整中文用戶手冊詳解及免費slack支持:www.asterisk.org.cn
Freepbx/FreeSBC技術文檔: www.freepbx.org.cn
如何使用FreeSBC,qq技術分享群:334023047
關注微信公眾號:asterisk-cn,獲得有價值的通信行業技術分享