1. 程式人生 > >WebRtc中ICE原理

WebRtc中ICE原理

webRTC支援點對點通訊,但是webRTC仍然需要服務端:
 . 協調通訊過程中客戶端之間需要交換元資料,
   如一個客戶端找到另一個客戶端以及通知另一個客戶端開始通訊。
 . 需要處理NAT(網路地址轉換)或防火牆,這是公網上通訊首要處理的問題。
   所以我們需要了解服務端相關的知識:信令、Stun、trun、ice。

一、什麼是信令
信令就是協調通訊的過程,為了建立一個webRTC的通訊過程,客戶端需要交換如下資訊:
 . 會話控制資訊,用來開始和結束通話,即開始視訊、結束視訊這些操作指令。
 . 處理錯誤的訊息。
 . 元資料,如各自的音視訊解碼方式、頻寬。
 . 網路資料,對方的公網IP、埠、內網IP及埠。

信令處理過程需要客戶端能夠來回傳遞訊息,這個過程在webRTC裡面是沒有實現的,需要自己建立。
一旦信令服務建立好了,兩個客戶端之間建立了連線,理論上他們就可以進行點對點通訊了,
這樣可以減輕信令服務的壓力和訊息傳遞的延遲。


因為信令是我們自己定義的,所以安全性問題跟webrtc無關,需要自己處理。
一旦黑客掌握了你的信令,那他就是控制會話的開始、結束、重定向等等。
最重要的因素在信令安全中還是要靠使用安全協議,如HTTPS,WSS(如TLS),
他們能確保未加密的訊息不能被擷取。為確保信令安全,強烈推薦使用TLS。


二、TURN 和 STUN
元資料是通過信令伺服器中轉發給另一個客戶端,但是對於流媒體資料,一旦會話建立,首先嚐試使用點對點連線。
簡單一點說就是:
   每個客戶端都有一個唯一的地址,他能用來和其他客戶端進行通訊和資料交換。


現實生活中客戶端都位於一個或多個NAT之後,或者一些防毒軟體還阻止了某些埠和協議,
或者在公司還有防火牆或代理等等,防火牆和NAT或許是同一個裝置,如我們家裡用的路由器。


webrtc就是通過 ICE 這套框架來處理複雜的網路環境的,
如果想啟用這個功能,你必須讓你的應用程式傳 ICE 伺服器的URL:
  ICE試著找最好的路徑來讓客戶端建立連線,他會嘗試所有可能的選項,然後選擇最合適的方案,
  ICE首先嚐試P2P連線,如果失敗就會通過Turn伺服器進行轉接。


換一個說法就是:
  STUN伺服器是用來取外網地址的。
  TURN伺服器是在P2P失敗時進行轉發的


stun和turn服務的作用主要處理打洞與轉發,配合完成ICE協議。
首先嚐試使用P2P,
如果失敗將求助於TCP,使用turn轉發兩個端點的音視訊資料,turn轉發的是兩個端點之間的音視訊資料不是信令資料。
因為turn伺服器是在公網上,所以他能被各個客戶端找到,
另外turn伺服器轉發的是資料流,很佔用頻寬和資源。


三、ICE技術
基於IP的語音、資料、視訊等業務在NGN(Next Generation Network)網路中
所面臨的一個實際困難就是如何有效地穿透各種NAT(Network Address Translator)/FW(Fire Wall)的問題。
對此,SIP(會話初始化協議)以往的解決方法由ALGs((Application Layer Gateway Service))、STUN、TURN等方式。


現在有一種新的媒體會話信令穿透NAT/FW的解決方案-互動式連通建立方式ICE。
它通過綜合利用現有協議,以一種更有效的方式來組織會話建立過程,
使之在不增加任何延遲同時比STUN等單一協議更具有健壯性、靈活性。
多媒體會話信令協議是在準備建立媒體流傳輸的代理之間互動資訊的協議,
例如SIP、RTSP(real time streaming protocol)等。


媒體流與信令流截然不同,它們所採用的網路通道也不一致。
由於協議自身設計上的原因,使得媒體流無法直接穿透網路地址轉換/防火牆(NAT/FW)。
因為它們生存期的目標只是為了建立一個在資訊中攜帶IP地址的分組流,這在遇到NAT/FW 時會帶來許多問題。
而且這些協議的目標是通過建立P2P(Peer to Peer)媒體流以減小時延,而協議本身很多方面卻與NAT存在相容性問題,
這也是穿透 NAT/FW的困難所在。


四、ICE簡介
互動式連通建立方式ICE(Interactive Connectivity Establishment)並非一種新的協議,
它不需要對STUN、TURN或RSIP進行擴充套件就可適用於各種NAT。


ICE是通過綜合運用上面某幾種協議,使之在最適合的情況下工作,以彌補單獨使用其中任何一種所帶來的固有缺陷。
對於SIP來說,ICE只需要定義一些SDP(Session Description Protocol)附加屬性即可,
對於別的多媒體信令協議也需要制定一些相應的機制來實現。


五、多媒體信令
媒體流穿透NAT的過程是獨立於某種具體的信令協議的。
通訊發生在兩個客戶端-會話發起者和會話響應者。
初始化資訊(Initiate Message)包含了描述會話發起者媒體流的配置與特徵,
並經過信令調停者(也叫信令中繼),最後到達會話響應者。


假設會話響應者同意通訊,接受資訊(Accept Message)將產生並反饋至會話初始者,媒體流建立成功。
此外,信令協議還對媒體流引數修改以及會話終止訊息等提供支援。
對於SIP,會話發起者即UAC(User Agent Client),會話響應者即UAS(User Agent Server),
初始化訊息對應SDP請求裡面的INVITE,接受訊息對應於SDP應答裡面的200 OK,終止訊息對應於BYE。


六、流程
1. 收集傳輸地址
會話發起者需要收集的物件包括:
  . 本地傳輸地址(Local Transport Address)
  . 來源傳輸地址(Derived Transport Address)。


本地傳輸地址:
  通常由主機上一個物理(或虛擬)介面繫結一個埠而獲得。
  會話發起者還將訪問提供UNSAF(Unilateral self-address fixing)的伺服器,例如STUN、TURN或TEREDO。
對於每一個本地傳輸地址,會話者都可以從伺服器上獲得一組來源傳輸地址。


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


2. 啟動STUN
會話發起者獲得一組傳輸地址後,將在本地傳輸地址啟動STUN伺服器,這意味著傳送到來源地址的STUN服務將是可達的。
與傳統的STUN不同,客戶端不需要在任何其它IP或埠上提供STUN服務,也不必支援TLS, ICE使用者名稱和密碼已經通過信令協議進行交換。
客戶端將在每個本地傳輸地址上同時接受STUN請求包和媒體包,所以發起者需要消除STUN訊息與媒體流協議之間的歧義。


在RTP和RTCP中實現這個並不難,因為RTP與RTCP包總是以0b10(v=2)打頭,而STUN是0b00。
對於每個執行STUN伺服器的本地傳輸地址,客戶端都必須選擇相應的使用者名稱和密碼。
使用者名稱要求必須是全域性唯一的,使用者名稱和密碼將被包含在初始化訊息裡傳至響應者,由響應者對STUN請求進行鑑別。


3. 確定傳輸地址的優先順序
STUN伺服器啟動後,下一步就是確定傳輸地址的優先順序。
優先順序反映了UA在該地址上接收媒體流的優先級別,取值範圍在0到1之間,通常優先順序按照被傳輸媒體流量來確定。


流量小者優先,而且對於相同流量者的Ipv6地址比Ipv4地址具有更高優先順序。
因此物理介面產生的本地Ipv6傳輸地址具有最高的優先順序,
然後是本地Ipv4傳輸地址,
然後是STUN、RSIP、TEREDO來源地址,
最後是通過VPN介面獲得的本地傳輸地址。


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


5. 響應處理:連通性檢查和地址收集
會話應答方接收到初始化資訊Initiate Message後,會同時做幾個事情:
首先,執行 收集傳輸地址 中描述的地址收集過程。這些地址可以在呼叫到達前預收集,這樣可以避免增加呼叫建立的時間。
當獲得來源地址以後,應答方會發送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,那麼客戶端不必重試,直接按超時處理即可。


6. 生成接受資訊(Accept Message)
應答者可以決定是接受或拒絕該通訊,若拒絕則ICE過程終止,若接受則傳送Accept訊息。
Accept訊息的構造過程與Initiate Message類似。


7. 接受資訊處理
接受過程有兩種可能。如果Initiate Message的接受者不支援ICE,
則Accept Message將只包含預設的地址資訊,這樣發起方就知道它不用執行連通性檢查了。
然而如果本地配置資訊要求發起者通過TURN伺服器發包來進行連通性檢查,
這將意味著那些直接發給響應者的包會被對方防火牆丟棄。


為解決這個問題,發起者需要重新分配一個TURN來源地址,然後使用Send命令。
一旦Send命令被接受,發起者將傳送所有的媒體包到TURN伺服器,由伺服器轉發至響應者。
如果Accept Message包含候選項,則發起方處理Accept Message的過程就與響應方處理Initiate Message很相似了。


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


9. ICE到SIP的對映
使用ICE方式穿透NAT,必須對映ICE定義的引數到SIP訊息格式中,
同時對其SDP屬性進行簡單擴充套件—在SDP的Media塊中定義一個新的屬性“alt”來支援ICE。
它包含一個候選IP地址和埠,SDP的接受端可以用該地址來替換m和c中的地址。
Media塊中可能會有多個alt屬性,這時每個alt應該包括不重複的IP地址和埠。


七、寫在最後
ICE方式的優勢是顯而易見的,它消除了現有的UNSAF機制的許多脆弱性。
例如傳統的STUN有幾個脆弱點:
  . 一個是發現過程需要客戶端自己去判斷所在NAT型別,這實際上不是一個可取的做法。
    而應用ICE之後,這個發現過程已經不需要了。


  . 另一點脆弱性在於STUN、TURN等機制都完全依賴於一個附加的伺服器,
    而ICE利用伺服器分配單邊地址的同時,還允許客戶端直接相連,
    因此即使STUN或TRUN伺服器中有任何一個失敗了,ICE方式仍可讓呼叫過程繼續下去。


  . 此外,傳統的STUN最大的缺陷在於它不能保證在所有網路拓撲結構中都正常工作,
    最典型的問題就是Symmetric NAT。
    對於TURN或類似轉發方式工作的協議來說,由於伺服器的負擔過重,很容易出現丟包或者延遲情況。
    而ICE方式正好提供了一種負載均衡的解決方案,它將轉發服務作為優先順序最低的服務,
    從而在最大程度上保證了服務的可靠性和靈活性。


  . 此外,ICE的優勢還在於對Ipv6的支援,目前Cisco等公司正在設計基於ICE方式的NAT/FW解決方案。
    由於廣泛的適應能力以及對未來網路的支援,ICE作為一種綜合的解決方案將有著非常廣闊的應用前景。

 

轉載自:https://blog.csdn.net/fireroll/article/details/50780863