Android IOS WebRTC 音視頻開發總結(十三)-- ice原理


    以前在做一個視頻監控項目的時候,剛開始客戶沒提到要支持P2P,因為服務端是我們自己寫的,為了便於處理一些邏輯,全部采用轉發的方式,后來客戶要求支持P2P,沒辦法了,后來自己部署了一個STUN服務器(不過也有很多開源STUN服務器,不過用起來會有些肖問題),客戶端取到NAT類型和ip地址后,自己根據這些信息進行打洞處理,搞得有點復雜,其實按照ICE協議就比較簡單了,主要分成兩個部分:地址獲取與連通性檢查,詳細介紹如下:

說明:下文是轉載的,轉載自哪里我也不知道,貌似經過很多層轉載了,在這里先對原創者表示感謝,同時為了便於閱讀和理解,我也對文本格式進行了調整,以及加入了自己的一些理解在里面.  cnblogs RTC.Blacker

     基於IP的語音、數據、視頻等業務在NGN網絡中所面臨的一個實際困難就是如何有效地穿透各種NAT/FW的問題。對此,會話初始化協議SIP以往的解決方法有ALGs,STUN,TURN等方式。本文探討了一種新的媒體會話信令穿透NAT/FW的解決方案—交互式連通建立方式(ICE)。它通過綜合利用現有協議,以一種更有效的方式來組織會話建立過程,使之在不增加任何延遲同時比STUN等單一協議更具有健壯性、靈活性。本文詳細介紹了ICE算法,並設計一個實例針對SIP信令協議穿透Symmetric NAT流程進行了描述,最后總結了ICE的優勢及應用前景。     

 

1 問題背景

        多媒體會話信令協議是在准備建立媒體流傳輸的代理之間交換信息的協議,例如SIP、RTSP、H.323等。媒體流與信令流截然不同,它們所采用的網絡通道也不一致。由於協議自身設計上的原因,使得媒體流無法直接穿透網絡地址轉換/防火牆(NAT/FW)。因為它們生存期的目標只是為了建立一個在信息中攜帶IP地址的分組流,這在遇到NAT/FW 時會帶來許多問題。而且這些協議的目標是通過建立P2P(Peer to Peer)媒體流以減小時延,而協議本身很多方面卻與NAT存在兼容性問題,這也是穿透 NAT/FW的困難所在。   

而NAT仍是解決當前公用IP地址緊缺和網絡安全問題的最有力手段,它主要有四種類型:完全圓錐型NAT(Full Cone NAT),地址限制圓錐型NAT (Address Restricted Cone NAT),端口限制圓錐型NAT (Port Restricted Cone NAT),對稱型NAT (Symmetric NAT)。前三種NAT,映射與目的地址無關,只要源地址相同,映射就相同,而對稱型NAT的映射則同時關聯源地址和目的地址,所以穿透問題最為復雜。

        不少方案已經被應用於解決穿透NAT問題,例如:ALGs(Application Layer Gateways)、Middlebox Control Protocol、STUN (Simple Traversal of UDP through NAT)、TURN(Traversal Using Relay NAT)、RSIP(Realm Specific IP)、symmetric RTP等。然而,當這些技術應用於不同的網絡拓撲時都有着顯著的利弊,以至於我們只能根據不同的接入方式來應用不同的方案,所以未能很好地解決All-NAT與Efficiency的問題,同時還會給系統引入了許多復雜性和脆弱性因素。所以我們目前需要一種綜合的足夠靈活的方法,使之能在各種情況下對NAT/FW的信令穿透問題提供最優解。事實上,ICE正是符合這樣要求的一種良好的解決方案。


2 ICE技術


2.1 ICE簡介

      交互式連通建立方式ICE(Interactive Connectivity Establishment)並非一種新的協議,它不需要對STUN、TURN或RSIP進行擴展就可適用於各種NAT。ICE是通過綜合運用上面某幾種協議,使之在最適合的情況下工作,以彌補單獨使用其中任何一種所帶來的固有缺陷。對於SIP來說,ICE只需要定義一些SDP(Session Description Protocol)附加屬性即可,對於別的多媒體信令協議也需要制定一些相應的機制來實現。本文僅就SIP問題展開討論。

2.2 多媒體信令

     媒體流穿透NAT的過程是獨立於某種具體的信令協議的。通信發生在兩個客戶端-會話發起者和會話響應者。初始化信息(Initiate Message)包含了描述會話發起者媒體流的配置與特征,並經過信令調停者(也叫信令中繼),最后到達會話響應者。假設會話響應者同意通信,接受信息(Accept Message)將產生並反饋至會話初始者,媒體流建立成功。此外,信令協議還對媒體流參數修改以及會話終止消息等提供支持。對於SIP,會話發起者即UAC(User Agent Client),會話響應者即UAS(User Agent Server),初始化消息對應SDP請求里面的INVITE,接受消息對應於SDP應答里面的200 OK,終止消息對應於BYE。


2.3 算法流程


2.3.1 收集傳輸地址

        會話發起者需要收集的對象包括本地傳輸地址(Local Transport Address)和來源傳輸地址(Derived Transport Address)。本地傳輸地址通常由主機上一個物理(或虛擬)接口綁定一個端口而獲得。會話發起者還將訪問提供UNSAF(Unilateral self-address fixing)的服務器,例如STUN、TURN或TEREDO。對於每一個本地傳輸地址,會話者都可以從服務器上獲得一組來源傳輸地址。

        顯然,實現物理或虛擬連通方式越多,ICE將工作得越好。但為了建立對等通信,ICE通常要求至少有一個來源地址由位於公網上的中繼服務器(如TURN)所提供的,而且需要知道具體是哪一個來源傳輸地址。


2.3.2 啟動STUN

        會話發起者獲得一組傳輸地址后,將在本地傳輸地址啟動STUN服務器,這意味着發送到來源地址的STUN服務將是可達的。與傳統的STUN不同,客戶端不需要在任何其它IP或端口上提供STUN服務,也不必支持TLS, ICE用戶名和密碼已經通過信令協議進行交換。

        客戶端將在每個本地傳輸地址上同時接受STUN請求包和媒體包,所以發起者需要消除STUN消息與媒體流協議之間的歧義。在RTP和RTCP中實現這個並不難,因為RTP與RTCP包總是以0b10(v=2)打頭,而STUN是0b00。對於每個運行STUN服務器的本地傳輸地址,客戶端都必須選擇相應的用戶名和密碼。用戶名要求必須是全局唯一的,用戶名和密碼將被包含在初始化消息里傳至響應者,由響應者對STUN請求進行鑒別。


2.3.3 確定傳輸地址的優先級

        STUN服務器啟動后,下一步就是確定傳輸地址的優先級。優先級反映了UA在該地址上接收媒體流的優先級別,取值范圍在0到1之間,通常優先級按照被傳輸媒體流量來確定。流量小者優先,而且對於相同流量者的Ipv6地址比Ipv4地址具有更高優先級。因此物理接口產生的本地Ipv6傳輸地址具有最高的優先級,然后是本地Ipv4傳輸地址,然后是STUN、RSIP、TEREDO來源地址,最后是通過VPN接口獲得的本地傳輸地址。


2.3.4 構建初始化信息(Initiate Message)

         初始化消息由一系列媒體流組成,每個媒體流都有一個缺省地址和候選地址列表。缺省地址通常被Initiate消息映射到SIP信令消息傳遞地址上,而候選地址列表用於提供一些額外的地址。對於每個媒體流來說,任意Peer之間實現最大連通可能性的傳輸地址是由公網上轉發服務器(如TURN)提供的地址,通常這也是優先級最低的傳輸地址。客戶端將可用的傳輸地址編成一個候選地址列表(包括一個缺省地址),並且為每個候選元素分配一個會話中唯一的標識符。該標識符以及上述的優先級都被編碼在候選元素的id屬性中。一旦初始化信息生成后即可被發送。


2.3.5 響應處理:連通性檢查和地址收集

        會話應答方接收到初始化信息Initiate Message后,會同時做幾個事情:首先,執行2.3.1中描述的地址收集過程。這些地址可以在呼叫到達前預收集,這樣可以避免增加呼叫建立的時間。當獲得來源地址以后,應答方會發送STUN Bind請求,該請求要求必須包含Username屬性和Password屬性,屬性值為從 “alt”中得到的用戶名和密碼。STUN Bind請求還應包括一個Message-Integrity屬性,它是由Initiate Message中候選元素的用戶名和密碼計算得來的。此外,STUN Bind請求不應有Change-Request或Response-Address屬性。

        當一個客戶端收到Initiate Message時,它將通過其中缺省地址和端口發送媒體流。如果STUN Bind請求消息引起錯誤應答,則需要檢查錯誤代碼。如果是401,430,432或500,說明客戶端應該重新發送請求。如果錯誤代碼是400,431和600,那么客戶端不必重試,直接按超時處理即可。


2.3.6 生成接受信息(Accept Message)

        應答者可以決定是接受或拒絕該通信,若拒絕則ICE過程終止,若接受則發送Accept消息。Accept消息的構造過程與Initiate Message類似。


2.3.7 接受信息處理

        接受過程有兩種可能。如果Initiate Message的接受者不支持ICE,則Accept Message將只包含缺省的地址信息,這樣發起方就知道它不用執行連通性檢查了。然而如果本地配置信息要求發起者通過TURN服務器發包來進行連通性檢查,這將意味着那些直接發給響應者的包會被對方防火牆丟棄。為解決這個問題,發起者需要重新分配一個TURN來源地址,然后使用Send命令。一旦Send命令被接受,發起者將發送所有的媒體包到TURN服務器,由服務器轉發至響應者。如果Accept Message包含候選項,則發起方處理Accept Message的過程就與響應方處理Initiate Message很相似了。


2.3.8 附加ICE過程

        Initiate或Accept消息交換過程結束后,雙方可能仍將繼續收集傳輸地址,這通常是由於某些STUN事務過長而未結束引起,另一種可能是由於Initiate/Accept消息交換時提供了新的地址。


2.3.9 ICE到SIP的映射

         使用ICE方式穿透NAT,必須映射ICE定義的參數到SIP消息格式中,同時對其SDP屬性進行簡單擴展—在SDP的Media塊中定義一個新的屬性“alt”來支持ICE。它包含一個候選IP地址和端口,SDP的接受端可以用該地址來替換m和c中的地址。Media塊中可能會有多個alt屬性,

這時每個alt應該包括不重復的IP地址和端口。語法屬性如下:
                 alt-attribute = "alt" ":" id SP qvalue SP derived-from SP
                 username SP password SP
                 unicast-address SP port [unicast-address SP port]
                 ;qvalue from RFC 3261
                 ;unicast-address, port from RFC 2327
                 username = non-ws-string
                 password = non-ws-string
                 id = token
                 derived-from = ":" / id
                 Symmetric NAT/FW


        下面設計一個簡化的基於ICE的對稱式網絡地址轉換/防火牆(Symmetric NAT/FW)的穿透實例,進一步說明ICE的工作流程。


此主題相關圖片如下:
圖1 Symmetric NAT/FW網絡拓撲圖

 假設通信雙方同時處於對稱式NAT/FW內部,現在SIP終端A要與B進行VoIP通信。A所在的內部地址是10.0.1.9,外部地址是211.35.29.30;B的內部地址是192.168.1.6,外部地址是202.205.80.130;STUN/TURN服務器的地址是218.65.228.110。
首先A發起請求,進行地址收集,如圖所示。生成A的Initiate Message如下:

v=0
o=Dodo 2890844730 2890844731 IN IP4 host.example.com
s=
c=IN IP4 218.65.228.110
t=0 0
m=audio 8076 RTP/AVP 0
a=alt:1 1.0 : user 9kksj== 10.0.1.9 1010

a=alt:2 0.8 : user1 9kksk== 211.35.29.30 9988
a=alt:3 0.4 : user2 9kksl== 218.65.228.110 8076


       其中本地地址的優先級為1.0,STUN地址的優先級為0.8,TURN地址優先級為0.4。當B收到消息后,也進行地址收集,過程和A類似。然后B開始執行連通性檢查,可是
我們不難發現,到10.0.1.9:1010的STUN請求和到211.35.29.30:9988的STUN請求都將不可避免地失敗。因為前者是一個不可路由的保留地址;而后者由於Symmetric NAT會對於每一個STUN/TURN請求都將分配不同的Binding,當數據包抵達A的NAT時,NAT會發現傳輸地址211.35.29.30:9988已經映射218.65.228.110:3478了。而此時STUN請求的源地址並非218.65.228.110:3478,所以數據包必然會被A的NAT/FW所丟棄。然而,到218.65.228.110:8076的STUN請求卻是成功的,因為TURN服務器用它收集到的原始地址來發送TURN請求。


當A收到應答后,它也執行連通性檢查,如圖所示:
圖2 :A的地址收集過程時序圖
此主題相關圖片如下:

圖3 :B的地址收集過程時序圖

此主題相關圖片如下:

圖4 :B的連通性檢查

 

完成連通性檢查后,B產生的應答消息如下:
v=0

o= Vincent 2890844730 289084871 IN IP4 host2.example.com
s=
c=IN IP4 218.65.228.110
t=0 0
m=audio 8078 RTP/AVP 0
a=alt:4 1.0 : peer as88jl 192.168.1.6 23766
a=alt:5 0.8 : peer1 as88kl 202.205.80.130 10892
a=alt:6 0.4 : peer2 as88ll 218.65.228.110 8078
a=alt:7 0.4 3 peer3 as88ml 218.65.228.110 5556

 

此主題相關圖片如下:
圖5: A的連通性檢查

    和前面一樣,對於B的私有地址和STUN來源地址的連通性檢查結果均為失敗,而到B的TURN來源地址和到B的peer-derived地址成功(本例中它們都具有相同的優先級0.4)。相同優先級下我們通常采用peer-derived地址,所以A發送到B的媒體流將使用218.65.228.110:5556地址,而B到A的媒體流將發送至218.65.228.110:8076地址。以上為基於ICE方式解決Symmetric NAT/FW穿透問題的一個簡化后的典型實例。

4 結束語

        ICE方式的優勢是顯而易見的,它消除了現有的UNSAF機制的許多脆弱性。例如傳統的STUN有幾個脆弱點,其中一個就是發現過程需要客戶端自己去判斷所在NAT類型,這實際上不是一個可取的做法。而應用ICE之后,這個發現過程已經不需要了。另一點脆弱性在於STUN、TURN等機制都完全依賴於一個附加的服務器,而ICE利用服務器分配單邊地址的同時,還允許客戶端直接相連,因此即使STUN或TRUN服務器中有任何一個失敗了,ICE方式仍可讓呼叫過程繼續下去。此外,傳統的STUN最大的缺陷在於它不能保證在所有網絡拓撲結構中都正常工作,最典型的問題就是Symmetric NAT。對於TURN或類似轉發方式工作的協議來說,由於服務器的負擔過重,很容易出現丟包或者延遲情況。而ICE方式正好提供了一種負載均衡的解決方案,它將轉發服務作為優先級最低的服務,從而在最大程度上保證了服務的可靠性和靈活性。此外,ICE的優勢還在於對Ipv6的支持,目前Cisco等公司正在設計基於ICE方式的NAT/FW解決方案。由於廣泛的適應能力以及對未來網絡的支持,ICE作為一種綜合的解決方案將有着非常廣闊的應用前景。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM