完整SIP/SDP媒體協商概論-SDP協商模式詳解-offer初始化流程

​當我們討論SIP或者SDP的一些技術話題時,SDP的協商是一個繞不過的話題。具體的協商機制涉及了多個方面的內容。在我們的討論中,筆者將會針對兩個比較重要的話題進行討論,一個是SDP offer/answer 模式,另外一個是在NAT場景中的SDP offer/answer交互模式拓展-ICE。在本章節中,我們將首先討論SDP offer/answer交互模式,具體內容包括:offer/answer的背景介紹,基本操作,如何實現初始化的offer,重點討論offer中的單播媒體操作,offer中關於指示方向的處理策略,編碼協商優先級設置。在後續的章節中,我們將討論answer如何回應offer,會話修改的細節處理,向對方指示協商能力,offer/answer交互模式的拓展ICE。


背景介紹和基本操作

首先,我們介紹一下我們討論的基本背景環境。到目前為止,我們討論的核心話題涉及了SDP和準備要討論的offer/anser交互模式。基本上我們都是圍繞兩個核心的規範來討論,其中,RFC4566(SDP)為基本藍圖,然後配合RFC3264關於offer/answer交互模式。關於SDP的內容,我們在前面的章節已經有完整的介紹(SDP基礎),那個章節涵蓋了SDP的核心定義/專有名詞,語法,特徵屬性,使用場景等相關細節,讀者可以查閱上一個章節的內容,這裡不再贅述。根據上一個章節的內容,我們在本章節進一步討論SDP協商時使用的交互模式-offer/answer模式。在本章節,我們將重點以RFC3264為藍本,介紹offer/anwer交互模式。這裡提醒讀者,為了更好地支持IPv4,在RFC3264的基礎上,RFC6157對媒體描述管理進行了更新。因此,如果讀者涉及了在IPv6環境中關於SDP中的媒體描述,讀者可以查閱RFC 6157-4.1章節的細節。如果讀者對SDP協商模式有興趣的話,可以結合具體的代碼示例來做進一步的研究。以下示例是開源SIP協議棧-PJSIP中關於SDP協商狀態機的處理流程示意圖:


完整SIP/SDP媒體協商概論-SDP協商模式詳解-offer初始化流程

PJSIP/SDP協商狀態機流程示例

鏈接:https://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__SDP__NEG.htm#details


很多技術人員,一說到offer/answer交互模式,就不假思索說這個概念其實非常簡單。事實上,很多人對此概念有不少誤解或者還在半桶水的認知狀態。因為很多技術人員經常排除的問題基本上都是一個簡單的雙方呼叫(單播會話),排查的交互會話描述也就雙方的會話參數,並沒有涉及到多播會話使用場景,例如IP廣播,會議等處理。另外,關於單播和多播場景中的RTP媒體流的處理也非常不同(可參考RFC 6284-7.1.2的端口映射),需要讀者對這些概念有一個充分的理解。因此,很多具體的協商需要大家瞭解。


完整SIP/SDP媒體協商概論-SDP協商模式詳解-offer初始化流程

此圖片以及以下圖例均來自互聯網資源


我們需要首先提醒讀者這些問題,在offer/answer交互模式下,單播會話和多播會話的處理方式是有差別的。SDP(RFC 4566)當時設計的構想是提供一種方式來描述多播骨幹網中傳輸的多播會話。SAP(RFC 2947)的設計構想是作為一種多播機制傳輸SDP消息的。在很多業務場景中,雖然規範中支持也允許支持單播操作,但是規範中支持單播操作相對不太完整。多播會話操作需要覆蓋全部會話參與者的操作,單播會話則僅涉及了兩個參與者以及其各自的認同的工作參數。具體來說,多播會話比單播會話涉及了更多的關於處理機制和處理方式,在offer/answer交互模式下有不同的處理方式。因此,提醒讀者,我們在下面的討論中,針對各種環境都會分別介紹單播會話和多播會話的處理方式,希望讀者千萬不要迷惑。例如,如果是多播會話的話,它要求針對具體的媒體流對所有參與方地址發送一個單多播地址,如果是單播會話的話,它僅需要雙方的兩個地址即可。再比如,如果是多播會話的話,它僅要求標識出會話所使用的具體編碼即可,通知所有會話參與方僅使用標識的編碼,但是,如果是單播會話中,則需要列出一個編碼支持列表,雙方可能都支持某些重複的編碼,通過二次協商才能決定使用何種編碼。另外,讀者可以想象一下,在單播會話環境中,隨著技術和網絡環境的不斷髮展,終端支持的各種編碼或者協商標識越來越多,儘管雙方的SDP提供了豐富的足夠的會話描述信息,但是因為會話描述定義越來越多,它們所帶來的問題也越來越多,例如定義的語法格式問題,操作細節的統一性問題。因此,會話雙方究竟如何成功協商,在技術方面,這仍然存在很多爭議,這也直接導致了很多環境下,軟硬件終端包括服務器端的雙方SDP協商不成功的問題。因此,為了實現協商的簡化和規範化,RFC 3264基於SDP規定了

一種簡化的offer/answer 交互模式。接下來,我們簡單介紹一下其基本工作原理。


“如無必要,勿增實體”-剃刀原理


在offer/answer交互模式環境中,會話中的發起方(offerer)生成一個offer數據,offer中包括媒體流參數和傳輸編碼,希望接收媒體的IP地址和端口。offer數據傳遞到對端接收方(answerer),接收方也生成一個answer數據回覆給offerer發起方,在answer回覆數據中包含了已匹配的媒體會話描述參數,表示其媒體是否可以接受。然後通過協商好的傳輸編碼,通過offer消息中的地址和端口對offerer發起方發送媒體流。無論是單播會話還是多播會話都可以支持offer/answer交互模式。注意,讀者如果對交互模式下的offer/offerer和answer/answerer有歧義,最好查閱SDP基礎章節中核心定義全解的內容。


現在,我們討論一些關於協議層操作的流程。offer/answer模式工作的前提基於一些高級協議,例如SIP協議存在,SIP協議有能力支持SDP的協商來實現基於代理之間的對會話創建支持。協議層的操作從一方代理對另外一方發起初始化的offer開始。對端的代理可以接受offer,並且返回一個answer或者拒絕這個offer。拒絕offer取決於高級協議層。這裡強調一點,offer/answer交互模式是atomic級的,這表示它具有一定的制鎖功能。如果這個answer被拒絕的話,會話將回復到offer之前的狀態。任何時間其中一個代理都可以生成一個新的offer來更新此會話狀態。

但是,如果代理已經收到了一個offer,代理還沒有接受或者拒絕,此代理一定不能生成新的offer。此外,如果代理已經生成了一個較早的offer,這個代理在還沒有收到針對較早的offer返回的answer消息或者拒絕消息,此代理一定不能生成一個新的offer。簡單來說,就是代理在沒有收到較早offer的回應結果(應答或者拒絕)之前,它一定不能再生成一個新的offer。有時,我們可能會看到一種特殊狀態,代理已經發送了一個offer後,但是在沒有收到此offer的answer前,如果代理收到了一個offer的話,這種狀態稱之為 “glare condition”。

完整SIP/SDP媒體協商概論-SDP協商模式詳解-offer初始化流程

Glare Case 狀態


雙方代理可能同時對對方發送一個更新offer。這種特殊情況下的處理機制需要更高層協議來對這種特殊狀態進行數據包發送到排序處理。如果讀者對glare case 或者異常處理有興趣做進一步研究的話,可以參考RFC 6337-4章節。接下來,我們開始討論生成offer的流程處理,以及在生成初始化offer中關於單播媒體和多播媒體的處理方式。


關於生成初始化offer處理流程

我們討論生成offer消息之前,首先我們一定要確定,無論是offer消息還是answer消息,它們一定是一個有效的SDP消息。


在SDP中針對offer/answer的構成語法可以忽略“e”或者“p=”行。筆者不清楚為什麼在offer/answer的消息中可以忽略“e”或者“p=”行,難道因為這兩個會話描述不是十分重要的協商參數? “o“行中的會話ID的數值和版本號必須是一個64位的有符號整形數,並且版本的初始值必須小於(2**62) − 1,這樣可以防止翻轉。在SDP規範中,可以允許多個SDP會話描述拼接在一起構成一個大的SDP消息,

但是SDP消息使用在offer/answer交互模式下時,一個SDP消息必須包含一個完整的會話描述。


讀者知道,SDP中的"s="傳遞會話主題,這種定義方式對多播會話方式是非常合理的,但是對單播會話方式存在一定問題。因此,一般推薦是”s“行有一個單空格字符或一個破折號構成。SDP "t="行負責傳遞會話時間,通常情況下,對單播會話的媒體來說,它的創建或者結束一般來自於外部的信令的控制,例如,我們現在討論的SIP協議。那種情況下,"t="行應該設定為”0 0.“。


offer消息中包含零個或者多個媒體流,每個媒體流通過”m=“行的媒體會話和其關聯特徵屬性進行說明。讀者可能不明白,為什麼offer消息中可能會包含零媒體信息?其實,包含零媒體仍然有它的原因。如果offer消息中包含零個媒體,這表示發起方-offerer希望和對端通信,但是發起方會在將來某一時間時間在此會話中添加那個媒體,添加媒體的方式是通過發送一個修改的offer來處理。 此媒體可以是一個單播和多播的混合。如果是多播的媒體,那offer消息中需要在"c="行添加多播地址。它們的構成方式取決於它們的媒體是單播還是多播媒體。簡單理解,這裡的零媒體不是表示offer沒有什麼可做,這表示發起方可能將來在

某一時間發起媒體流,但是不是現在。如果將來發起媒體流,offerer會更新offer再次提醒對端answerer。下面,我們繼續討論offer中的單播媒體場景的處理流程。


關於offer的單播媒體處理討論

這裡,我們花費一點時間需要詳細說明offer中的單播媒體處理流程。在offer中的單播媒體處理中,offer對媒體的發送和接收標註涉及了多個方向指示特徵屬性(a=sendonly,a=recvonly,a=sendrecv,a=inactive-參考RFC3108和RFC2327),多個特徵屬性又具有不同的含義,所以請讀者在閱讀本部分內容時一定要特別注意。讀者也可以查閱筆者的歷史文檔來學習關於這三種屬性應用場景示例。


如果offer僅希望對對端發送媒體時,offer必須對此媒體標註為send-only的表示,通過特徵屬性"a=sendonly"行來標識。如果媒體發送的方向屬性作為媒體媒體流屬性或者會話屬性出現的話,我們就會認為此媒體標註了媒體發送方向。同理,如果此offer僅希望從對端接收媒體的話,offer必須對此媒體標識為recvonly,表示僅為接收狀態,通過特徵屬性“a=recvonly”表示。如果,offer希望和對端通信,但是,此時,offer既不想發送媒體也不行接收媒體時,它通過對媒體標識為"

a=inactive"行來表示其當時狀態。


這裡,筆者需要提醒一下,因為很多最新的規範已經對RTP協議的實時應用程序傳輸協議-RFC3550進行了更新(包括5761,6051,6222,7022,7160,7164,8083和8108),因此一些特別的處理流程需要提醒讀者。如果是涉及了RFC3550中描述的實時傳輸協議和實時傳輸控制需要的話,為了支持以上三種方向指示的狀態,RTCP同樣需要被髮送和接收。這種情況下,媒體流的方向指示不會影響RTCP的使用。如果offer希望對對端發送和接收媒體的話,它可以通過"a=sendrecv"行來標識也可以忽略其屬性設置(因為此屬性為默認設置屬性)。


讀者需要注意,offer消息中三種媒體流向的方向有一些不同。對於標記了“a=recvonly”和“a=sendrecv”的媒體流來說,在offer消息中,端口號和地址表示發起方offerer希望接收媒體流的端口和地址。對於標識為“a=sendonly” RTP 媒體流,端口號和地址間接指示為offerer希望接收RTCP數據的地址。除非有明確表示說明,否則RTCP報表數據將會發送到比標識的端口高一位的端口(這是默認的RTCP端口發送方式)。很多時候,讀者可能對offer中的IP地址和端口使用有一些誤解,這裡筆者做進一步的解釋。在offer中出現的ip地址和端口不能指示將要由發起方offerer發送出去的RTP/RTCP的源地址,源端口。在offer消息中,如果端口數為零,這表示媒體已經被經過offer消息處理,但是此媒體一定不能被使用,因為此初始的offer中沒有任何有效的語法參數。有時,如果設置端口零可以結束現存的媒體流。一般來說,端口數量為零表示此媒體流不是offer/answer雙方需要的媒體流。但是,一些特殊的環境下,編碼類型一樣,但是可能因為payload不同的話,也可能需要做一些協商處理。針對標識為”a=sendonly“ 或“a=sendrecv”的媒體,在answer的消息中同樣的媒體可能標識了不同的payload。offerer發起方收到answerer回覆後,重新發送一個offer。這次發送中,offerer發起方

必須包含一個和answer消息中一樣的媒體payload。這樣才能保證雙方的媒體的payload一致性。有時,為了保證和H323的兼容性,每個方向可以支持不同的payload類型號。


在所有的RTP流使用場景中,fmtp 媒體格式類型可能出現來支持更多的媒體格式類型描述。所有的媒體描述應該包含"a=rtpmap"行,它用來映射相應的payload 類型號碼來對編碼進行編碼處理。如果沒有"a=rtpmap"行的話,應該使用默認的當前的屬性設置(RTP/AVP)。具體默認屬性設置,讀者可查閱RFC3551-6。


offer的協商過程中,讀者需要另外注意幾個經常使用的媒體描述參數。在協商過程中,offer消息中必須提供一個"m="行的格式列表,通過偏好優先級的順序來通知對端offer中推薦使用的優先級編碼格式。優先級最高的是最優先使用的編碼格式。有時,我們在配置軟交換或者媒體服務器時,雙方呼叫失敗,有可能是編碼不匹配導致,比如說沒有匹配的prefered的編碼。所以,編碼列表的順序是非常重要的,技術人員需要對照服務器端的編碼列表實現對照本地終端的編碼列表順序檢查。比如FreeSWITCH中的編碼優先級設置:

<code><x-pre-process>/<code>

或者思科終端的設置:

<code>Cisco-router(config-class)#codec preference 1 g723r63Cisco-router(config-class)#codec preference 2 g729br8Cisco-router(config-class)#codec preference 3 g711ulawCisco-router(config-class)#codec preference 4 g726r32 bytes 240/<code>

如果ptime特徵屬性出現offer中,它表示offer所期望的收到的打包時長,當然,ptime必須大於零。如果offer中出現了bandwidth的話,它表示offer所期望帶寬來傳輸媒體流。當然,帶寬值也允許設置為零(不建議),這表示沒有媒體發送,同時也關閉了RTCP數據發送。


如果是offerer中的多媒體的話,根據多媒體類型的不同處理方式也有一定的差別。如果在offer中出現了不同類型的多媒體流(語音,視頻,文本等),這表示發起方offerer希望同時使用這些多媒體流。比較典型的例子就是視頻會議,視頻會議中,語音和視頻媒體流被同時使用。如果在offer中出現來同樣的媒體類型的話,這表示offerer發起方期望同時接收或發送那種同一類型的媒體流。關於同一類型的媒體流收發,雙方可能有一定的規則策略需要遵守,這取決於本地資源(例如,麥克風/攝像頭和錄像終端)和業務需求的設置。另外一些限制也可能影響多媒體的本地處理策略,例如不同語音或者視頻媒體流的混音/混屏處理,按需錄像錄音處理等業務需求。


Offerer發送方需要根據不同的指示標識調整為一個相應的狀態。一旦發起方Offerer發送了offer消息以後,發起方必須準備接收offer描述的任何標識為recvonly的媒體。另外,發起方必須準備發送和接收在offer中標識為sendrecv的媒體,並且準備發送在offer中標識為sendonly的媒體。當然,何時發送還要取決於對端answer的地址和端口。在RTP的環境中,雖然可能offerer在answer消息到達之前,提前收到了媒體流,但是發起方仍然需要收到answer消息後,它才能發送RTCP接收方報告數據。


關於offer的多播媒體處理討論

在offer中,如果一個會話描述中包含一個多播媒體流,此多播媒體流列為僅接收或者發送狀態,這表示參與者(包括了發起方offerer和接收方answerer)僅能接收或發送媒體流。和多播媒體流處理方式相比,單播媒體處理僅是發起方和接收方媒體流的直接收發。除了以上這個區別以外,offer中的多播媒體的語法定義可以查閱RFC 4566的規範說明。


https://www.rfc-editor.org/rfc/rfc3264

https://tools.ietf.org/html/rfc6284

https://tools.ietf.org/html/rfc5939

https://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__SDP__NEG.htm


分享到:


相關文章: