<address id="lbt7n"></address>
      <delect id="lbt7n"><mark id="lbt7n"></mark></delect>
      <form id="lbt7n"></form>

          <big id="lbt7n"><cite id="lbt7n"><cite id="lbt7n"></cite></cite></big>
          <cite id="lbt7n"></cite>

          <p id="lbt7n"></p>
          您當前的位置是:  首頁 > 資訊 > 國內 >
           首頁 > 資訊 > 國內 >

          完整SIP/SDP媒體協商概論-WebRTC/ICE概覽

          2020-03-31 09:44:19   作者:james.zhu    來源:Asterisk開源派   評論:0  點擊:


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

          相關閱讀:

          專題

          CTI論壇會員企業

          久久成人永久免费播放,国产精品二区在线,鲁啊鲁在线视频免费播放,精品三级内地国产在线观看

              <address id="lbt7n"></address>
              <delect id="lbt7n"><mark id="lbt7n"></mark></delect>
              <form id="lbt7n"></form>

                  <big id="lbt7n"><cite id="lbt7n"><cite id="lbt7n"></cite></cite></big>
                  <cite id="lbt7n"></cite>

                  <p id="lbt7n"></p>