【網絡通信 -- WebRTC】WebRTC 基礎知識 -- ICE 交互總結
【1】ICE 的一般概念簡介
ICE 角色
offer (主動發起)的一方為 controlling 角色
answer (被動接受)的一方為 controlled 角色
full ice agent 必須是 controlling role,lite ice agent 是 controlled;srs 僅支持 lite ice
ICE 模式
FULL ICE,雙方都要進行連通性檢查;ice 客戶端實現,該模式既可以收 binding request,也可以發 binding request
Lite ICE,在 FULL ICE 和 Lite ICE 互通時,只需要 FULL ICE 一方進行連通性檢查,Lite 一方只需回應 response 消息,該模式對于部署在公網的設備比較常用;只接受并回復 binding request 請求,不會主動發送 binding request 請求給對方
sdp 中有 a=ice-lite 字樣
srs 服務器采用 lite-ice 模式
Candidate 地址
媒體傳輸的候選地址,組成 candidate pair 做連通性檢查,確定傳輸路徑
Type 類型
Host (Host Candidate),該地址是一個真實的主機,參數中的地址和端口對應一個真實的主機地址,該地址來源于本地的物理網卡或邏輯網卡上的地址,對于具有公網地址或者同一內網的端可以用;
Srvflx (Server Reflexive Candidate),該地址是通過 Cone NAT (錐形 NAT) 反射的類型,參數中的地址和端口是端發送 Binding 請求到 STUN/TURN server 經過 NAT 時,NAT 上面分配的地址和端口
Relay (Relayed Candidate),該地址是端發送 Allocate 請求到 TURN server,由 TURN server 用于中繼的地址和端口,該地址和端口是 TURN 服務用于在兩個對等點之間轉發數據的地址和端口,是一個中繼地址端口;( 可能是本機或 NAT 地址);
Prflx(Peer Reflexive Candidate),該地址是通過發送 STUN Binding 時,通過 Binding 獲取到的地址;在建立連接檢查期間新發生,參數中的地址和端口是端發送 Binding 請求到 STUN/TURN server 經過 NAT 時,NAT 上分配的地址和端口
Componet ID
傳輸媒體的類型,1 代表 RTP; 2 代表 RTCP
WebRTC 采用 Rtcp-mux 方式,也就是 RTP 和 RTCP 在同一通道內傳輸,減少 ICE 的協商和通道的保護
Priority
Candidate 的優先級
Base
candidate 的基礎地址
SDP 中的 Candidate 地址描述
ICE 保活
對于每個 ICE 通道,都需要為其會話進行保護
采用 STUN binding request 或者 STUN binding indication
如果沒有收到響應,則會重傳,直到最大重傳次數
ICE 角色沖突的解決方法
當兩端角色都為 controlling 或者 controlled 角色沖突時,在連通性檢查階段,要求發送信息 binding request 消息中必須要帶上 tie-breaker 屬性
當出現沖突時,比較 tie-breaker 大小,值比較大的則被認為是 controlling,同時回應 487 錯誤給對端,對端收到消息 487 錯誤后切換角色
私信【1】領取上圖學習webRTC高級開發技術,資源資料共享
【2】ICE 的一般過程
收集 candidates
客戶端無法知道自己的外網 IP,需要發送 stun 包給 stun 服務,stun 服務返回對應客戶端的出口 IP 和端口,返回來的地址和自己本地地址做比對便可以知道 NAT 類型
根據 Componet ID,獲取本機 host address;從 STUN 服務器獲取 srvflx address;從 TURN 服務器獲取 relay address;同時生成 foundation;
刪除重復的 candidate 收集地址完成后,需要去掉重復的 candidate,如果兩個 candidate 的地址一樣,并且 Base 地址也一樣則刪除
交換 candidates
ICE 交換 candidates 方式可以使用 sdp 交換,也可以使用單獨信令交換
ICE 交換 candidates sdp 方式
ICE 使用 offer/answer 方式,雙方通過 SDP 協商交換 candidate 信息;
Candidate 信息包括 type, foundation, base, component id, transport
SDP 示例
生成 candidate pairs
在本端收到遠端 candidates 后,將 Component ID 和 transport protocol 相同的 candidates 組成 pair
修整 candidate pair,如果是 srvflx 地址則需要用其 base 地址替換
連通性檢查
將 candidate pairs 按照優先級排序,供連通性檢查使用,其實就是把 sdp 中的 candidate 地址和本地的 candidate 地址進行排隊,組成一個 checklist 表,生成按優先級排序的鏈表,按優先順序發起每個候選地址對的檢查;
連通性檢查成功的 candidate pair 按優先級排序的鏈表,用于 ICE 提名和選擇最終路徑,連通性檢查完畢后,開始進行優先級排序
如果 checklist 中存在 relay candidate,則必須先為 relay candidate 創建 permission;permission 就是一個許可,如果沒有創建許可,發送的包將被丟棄 (針對 TURN 時使用)
ICE 使用 STUN binding request/response,包含 Fingerprint 檢驗校驗機制
如果 A 收到 B 的 response 則代表連通性檢查成功,否則需要進行重傳直到超時,在建立連接時,如果沒有響應,則會以 RTO 時間進行重傳,每次翻倍,直到最大重傳次數;
STUN 請求采用 STUN short-term credential 方式認證,即一段時間如果沒有 stun 包發送時,該連接會過期失效,因此需要不斷地發送 stun 包并收到回復的 stun 包,用來保持連接有效性;剛開始建聯時,以 50ms 間隔頻率發送,后期穩定后是以 2.5s 的間隔頻率發送,維持連接的有效性
STUN USERNAME 屬性 ”RemoteUsername : localUsername”
兩端在 SDP 協商時交換 ice-pwd 和 ice-ufrag,以得對端用戶名和密碼,計算 stun 包中的 MESSAGE-INTEGRITY 時,需要自己本地的 ice-pwd 去計算 Hmac-SHA1,生成對應的屬性值串,用來檢查消息的完整性
生成 validlist
將連通性檢查成功的 candidate pair 按優先級排序加入 validlist,此時本地 candidate 填寫的是公網映射地址,remote candidate 填寫的是對端發送的 STUN binding request 地址
提名 candidate pair
由 controlling 提名哪對 candidate pair 為 valid pair
提名方式分為普通提名和進取型提名
普通提名方式會做兩次連通性檢查,在第一次做連通性檢查時不會帶上 USE-CANDIDATE 屬性,而是在生成的 validlist 中選擇 pair 再進行一次連通性檢查,這時會帶上 USE-CANDIDATE 屬性,并且置位 nominated flag (ICE 提名地址對)
進取型方式則是每次發送連通性檢查時都會帶上 USE-CANDIDATE 屬性,并且置位 nominated flag (ICE 提名地址對),不會再去做第二次連通性檢查
選擇最終傳輸地址
ICE 在提名的 valid pair 中選擇優先級最高的那對作為本次 ICE 流程傳輸地址,然后開始建立 DTLS 連接,開始握手,交換證書
【3】ICE 交互示例解析
如果 A 收到 B 的 response,則代表連通性檢查成功,否則需要進行重傳直到超時
在建立連接時,如果沒有響應,則會以 RTO 時間進行重傳,每次翻倍,直到最大重傳次數
STUN 請求,采用 STUN short-term credential 方式認證
STUN USERNAME 屬性 ”
RemoteUsername:localUsername”
兩端在 SDP 協商時交換 ice-pwd 和 ice-ufrag,以得對端用戶名和密碼
STUN 檢查請求中需要檢查地址的對稱性,請求的源地址是響應的目的地址,請求的目的地址是響應的源地址,否則都設置狀態為 Failed
ICE 的完整實現過程
1. 為中繼候選地址生成許可 (Permissions)
2. 從本地候選往遠端候選發送 Binding Request
在 Binding 請求中通常需要包含特殊的屬性,以在 ICE 進行連接性檢查的時候提供必要信息
PRIORITY 和 USE-CANDIDATE
終端必須在其 request 中包含 PRIORITY 屬性,指明其優先級,優先級由公式計算獲得;如果有需要也可以給出特別指定的候選 (即 USE-CANDIDATE 屬性)
ICE-CONTROLLED 和 ICE-CONTROLLING
在每次會話中,每個終端都有一個身份,存在兩種身份,即受控方(controlled role) 和主控方(controlling role),主控方負責選擇最終用來通訊的候選地址對,受控方被告知哪個候選地址對用來進行哪次媒體流傳輸,并且不生成更新過的 offer 來提示此次告知;發起 ICE 處理進程 (即生成 offer)的一方必須是主控方,而另一方則是受控方;如果終端是受控方,那么在 request 中就必須加上 ICE-CONTROLLED 屬性;如果終端是主控方,就需要 ICE-CONTROLLING 屬性
生成 Credential
作為連接性檢查的 Binding Request 必須使用 STUN 的短期身份驗證;驗證的用戶名被格式化為一系列 username 段的聯結,包含了發送請求的所有對等端的用戶名,以冒號隔開;密碼就是對等端的密碼
3. 處理 Response
當收到 Binding Response 時,終端會將其與 Binding Request 相聯系,通常通過事務 ID;隨后將會將此事務 ID 與候選地址對進行綁定
終端收到成功響應之后,先檢查其 mApped address 是否與本地記錄的地址對有匹配,如果沒有則生成一個新的候選地址,即對等端的反射地址;如果有匹配,則終端會構造一個可用候選地址對 (valid pair);
通常很可能地址對不存在于任何檢查列表中,此時檢索檢查列表中沒有被服務器反射的本地地址,將這些地址的本地候選轉換成服務器反射地址的基地址并把冗余的地址去除掉;
失敗響應
如果 STUN 傳輸返回 487(Role Conflict) 錯誤響應,終端首先會檢查其是否包含了 ICE-CONTROLLED 或 ICE-CONTROLLING 屬性;如果有 ICE-CONTROLLED 終端必須切換為 controlling role; 如果請求包含 ICE-CONTROLLING 屬性則必須切換為 controlled role;切換完成,終端必須將使得產生 487 錯誤的候選地址對放入檢查隊列中,并將此地址對的狀態設置為 Waiting
成功響應,一次連接檢查在滿足下列所有情況時候就被認為成功
STUN 傳輸產生一個 Success Response
response 的源 IP 和端口等于 Binding Request 的目的 IP 和端口
response 的目的 IP 和端口等于 Binding Request 的源 IP 和端口