Proxy的SIP消息重構和RFC7092詳解

我們在IP語音通信領域中一直在討論SIP服務器和應用等相關的話題。關於SIP協議中,讓讀者比較關心的或者我們經常使用的就是SIP應用服務器,包括企業IPPBX,SBC,註冊服務器等核心的構件。這些典型的應用大部分都是B2BUA的形式出現的,大部分技術人員可能僅知道它們是一個背靠背服務,可以通過此服務做一些SIP消息的管理。可能很多人不瞭解B2BUA可以做哪些方面的管理,B2BUA的類型,以及所遵守的規範,還有和SIP代理服務器之間的區別等概念,也缺乏深入瞭解。


今天,筆者將對以上這些問題做比較詳細地分析解釋。我們本次討論將覆蓋,B2BUA和SIP Proxy的區別,B2BUA的概念,RFC7092規範,使用B2BUA的原因,3PCC場景,SIP代理和B2BUA如何重構SIP消息,SBC和SIP Proxy對比。

為什麼使用B2BUA

首先,我們介紹一下使用B2BUA的背景和SIP Proxy的基本概念。根據RFC3261規範的定義,SIP Proxy是:

SIP proxies are elements that route SIP requests to user agent servers and SIP responses to user agent clients.

https://tools.ietf.org/html/rfc3261#section-16

根據RFC3261的定義,SIP Proxy主要作用是對SIP請求的路由。“路由”這個詞具有多層含義,它負責執行路由,認證,籤權,地址解析,迴環檢測和均衡負載的功能。根據這些功能,市場上衍生出了很多這些業務的SIP服務器業務,包括:註冊服務器,籤權服務器,DNS服務器和均衡負載的服務器等多種服務器類型。大家熟悉的開源SIP服務器Kamalio,OpenSIPS就是比較常用的SIP Proxy。筆者在以前的討論中有對這些服務器的介紹,這裡不再討論。

SIP Proxy有分為兩種模式,一種是狀態代理模式,另外一種是無狀態代理模式。關於這兩種模式的使用場景和各自的工作方式,我們在以前的文章中有非常完整的介紹,讀者可以查閱歷史完整來了解它們的功能概念。SIP代理的概念說起來比較抽象,如果沒有很多SIP使用經驗的話,一些讀者可能會產生誤解。


B2BUA/SBC/Proxy的SIP消息重構和RFC7092詳解


簡單來說,SIP 代理可以看作是我們生活中某些業務場景的代理一樣。例如,如果客戶A正在打高爾夫球,不能出席某個會議,他委託公司其他人或者第三方實體幫助他代理出席某一個會議,代理人在現場根據現場的內容,轉發或者通知客戶A。這裡,中間代理人實體實際上就是一個會議的中轉人,不承擔也不執行某些主要的業務。


通過以上的介紹讀者應該可以明白,事實上,代理的功能極其有限,IP語音業務的很多功能,它不能實現。另外,SIP代理自己本身不能發起INVITE請求,這樣就不能滿足IP語音通信的基本呼叫功能。例如,以下的預付費的功能。


如果在簡單的場景中,雙方進行呼叫,通過Proxy的計費系統可以滿足計費的要求。如果話費不足時,SIP Proxy應該自己生成BYE請求,同時對雙方終端發送其生成的請求。事實上,Proxy自己本身不能生成BYE請求,後續的請求應該由終端生成,而不是Proxy自己。因此,SIP Proxy很難滿足某些複雜的業務功能。


另外,在以前的文章中,我們已經討論過,雙方終端通過多個Proxy代理以後,根據Route Set返回處理流程。但是,在一些情況下,如果終端忽略了Route Set以後,直接通過呼叫方和被呼叫方,雙方可能進行非法呼叫,它們跳過了代理服務器,導致業務控制層很難對其進行管理。

對此,一些聰明的開發人員提出了一個非常有創造力的設計思路,他們建議採用一個新的技術架構-(背靠背)B2BUA的機制,通過背靠背的方式來實現業務能力的管理和會話的管理,主要引進了我們通常所說的B2BUA的概念。


根據RFC3261對B2BUA定義,B2BUA-6定義是:

A back-to-back user agent (B2BUA) is a logical entity that receives a request and processes it as a user agent server (UAS). In order to determine how the request should be answered, it acts as a user agent client (UAC) and generates requests. it maintains dialog state and must participate.

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


通過以上定義,我們可以看出,B2BUA是一個邏輯實體,它由一個UAS和一個UAC兩個部分構成,分別負責接收請求,處理請求和生成請求。B2BUA和SIP代理不同,它必須保持在dialog中所有創建的請求。只有這樣,B2BUA才能完全控制所有需要管理的會話。

通常來說,SIP 服務器端是不會信任任何終端的,因此,UAC發起呼叫後,首先需要面對UAS來進行驗證,然後才能進行下一步的處理。一個B2BUA支持的基本功能包括:

  • 呼叫管理,自動呼叫掛斷,呼叫轉移等。
  • 網絡連接包括協議調整
  • 隱藏內網地址,終端地址
  • 監控整個呼叫狀態


B2BUA的基本功能和典型的使用場景: 電話會議,網關,SBC,IPPBX,電話轉接等場景,這些都是通過3PCC來實現。


RFC7092對B2BUA的類別

根據RFC7092規範的定義,B2BUA可分為多個類別,主要包括兩個主類別和多個次類別:

  1. Signaling Plane B2BUA Roles, 其子類別分別包括:Proxy-B2BUA, Signaling-only和 SDP-Modifying Signaling-only。這個類別中,B2BUA側重於信令的處理,SDP的管理,它們本身不介於媒體路徑上,所以,它們不能管理RTP頭和payload。
  2. Signaling/Media Plane B2BUA Roles,其子類別分別包括:Media Relay,Media Aware和Media Termination。扮演信令媒體的B2BUA,它們不僅那個管理SIP頭,而且可以對RTP 頭進行管理或者修改。通過此B2BUA處理後的信令和媒體能夠保證雙方的一致性。大家比較熟悉的SBC可以實現以上這些功能。


通過以上的分類描述,我們可以通過以上抽象的概念映射到我們具體的應用環境中。B2BUA可以實現以下幾個方面的應用場景:

  • 基於SIP的IPPBX和軟交換,市場上很多企業融合通信的IPPBX就是一個非常典型的B2BUA場景。比較熟悉的開源的Asterisk或FreeSWITCH,以及基於Asterisk引擎的開源IPPBX界面管理系統FreePBX
  • 基於應用服務器支持,包括3GPP環境下的分機隨行,ACD等服務
  • SBC邊界控制器,筆者已經多次介紹
  • 編碼轉換服務,支持不同編碼轉換,實現雙方編碼的一致性支持
  • 會議服務器,通過B2BUA實現會議,以及會議控制功能,混音等
  • P-CSCF和IBCF Functions,支持IMS網絡中的網關訪問和切換功能
  • S-CSCF Function,支持IMS環境中的Proxy-B2BUA

在RFC7092規範中定義了具體的角色,但是規範並沒有詳細說明應用場景的具體的使用方式,讀者可以參考具體的場景示例自己去做進一步的研究。在接下來的章節,我們重點介紹B2BUA的具體的工作流程和一些媒體管理的細節。


B2BUA具體呼叫工作流程

通過上面章節的介紹,可能讀者已基本掌握了B2BUA的基本概念。現在我們重點介紹一下B2BUA是如何工作的。首先,這裡說明,根據以上對B2BUA的定義,為了管理雙方的終端和對會話進行管理,B2BUA需要分別創建兩個不同的會話,B2BUA根據終端的不同,B2BUA可以扮演UAS/UAC的功能,只有這樣,B2BUA才能完全控制雙方的呼叫流程,保證雙方在同一信令路徑上。


以上示例是一個簡單的雙方終端呼叫的流程,B2BUA介於兩個終端之間。此呼叫流程經過了大概四個步驟。

  1. UAC對B2BUA發起一個INVITE請求,在B2BUA端,B2BUA是一個UAS來接收這個請求,創建了第一個會話來管理這個請求。雙方保存了彼此的Route Set 記錄消息。
  2. 為了對另外一個終端發起INVITE請求,B2BUA同時也扮演了一個UAC的角色,它創建了第二個會話,並且再次對下游終端發起INVITE請求。這裡,UAC需要從UAS端拷貝SDP消息和其他必要消息內容。然後,UAC對下游終端發起INVITE請求。終端接收了INVITE請求,並且保存了Route Set數據記錄。
  3. 為了響應INVITE請求,這裡,下游終端就會變成一個UAS回覆B2BUA 200 OK。B2BUA再次拷貝200 OK的消息,然後通過UAS再次返回到UAC終端。
  4. UAC終端收到200 OK以後,保存為Route Set數據內容。


在最後的握手確認時,終端必須根據Route Set 返回到B2BUA,因為其中的Contact不是另外終端的Contact地址,而是B2BUA的Contact。接下來,UAC終端繼續對B2BUA的UAS發送ACK消息。這裡的UAC 終端必須通過B2BUA返回到另外一端,而不是直接進行ACK的交互,這樣,B2BUA就會保證對終端雙方的會話管理,同時可以支持其他業務功能的實現,例如,計費功能。

這裡,讀者一定要注意,B2BUA負責橋接兩個呼叫的會話,拷貝必要的消息內容。關於拷貝什麼消息,不能拷貝什麼消息,我們在接下來的章節介紹。另外,B2BUA保持會話內容,兩個會話負責不同的終端。雙方終端不知道對端的Contact地址。終端的Contact地址僅是B2BUA的地址。在這一點上,B2BUA和SIP Proxy有著非常明顯的區別。因此,雙方終端只能通過B2BUA才能進行信令路徑的完整性處理。


另外,一個比較特殊的場景是呼叫的預付費功能,這也是transparent B2BUA的一個基本功能。比較簡單計費的原理如下:

If there is more time left, the B2BUA starts the timer again with the same operations as described above. If there is no more time left, the call legs willbe disconnected by sending BYE messages to all call legs . If either side disconnects the call, the B2BUA stops accounting.

http://mirror.unpad.ac.id/orari/library/library-sw-hw/linux-1/sip/vocal/application/b2bua/b2bua.pdf

事實上,關於預付費的複雜的處理流程,可能需要藉助於媒體服務器的支持,通過mid-call announcements的方式,對預付費的電話服務進行語音播放,然後再執行掛機處理。具體的處理方式,讀者查閱RFC3725-3。另外,關於透明B2BUA的介紹,讀者可以查閱


Send a BYE request towards one, or even both parties, for example in prepaid applications.

https://tools.ietf.org/html/draft-marjou-sipping-b2bua-01#section-3

根據計費原理的工作方式,如果計費模塊檢測到雙方呼叫費用出現超額的時候,這時,B2BUA會切換成UAC/UAC的狀態,同時對終端發送BYE消息。

這裡,透明B2BUA的工作方式類似於一個SIP Proxy,而且仍然利用了B2BUA的其他優點。和透明(transparent)B2BUA相對的是拓展(extended proxy)B2BUA,它可以支持其他的功能設置。兩者之間沒有特別明顯的區別,具體的內容,讀者可查閱:

<code>Requirements for a Session Initiation Protocol (SIP) Transparent Back-                       To-Back User-Agent (B2BUA)                       draft-marjou-sipping-b2bua-00/<code>


B2BUA功能實現3PCC討論

B2BUA可以支持很多應用功能,比較常見的是3PCC,第三方呼叫控制。第三方呼叫控制實現了很多用戶場景,包括點擊呼叫,電話轉接等功能。這些具體的實現流程,筆者在以前的文章中有非常詳細的介紹和消息流程圖,包括18個呼叫流程,讀者可以查閱。

在3PCC的呼叫中,我們需要明確兩個主要的定義:3PCC和控制器。根據RFC3725的定義,這兩個定義是:

3pcc: Third Party Call Control, which refers to the general ability to manipulate calls between other parties.


Controller: A controller is a SIP User Agent that wishes to create a session between two other user agents.

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

在第三方呼叫的規範中定義了四種第三方呼叫的呼叫模式,其中的控制器就扮演著B2BUA的角色。比較典型的場景就是頁面點擊呼叫或者轉接的處理。

在典型的轉接環境中,兩個終端可能已經接通了呼叫,因為其他的原因,終端可能需要轉接此呼叫到第三方。這時,B2BUA或者控制器就會對另外一端掛機,繼續保持著和呼叫方會話。呼叫方收到消息後,再次對第三方發送無SDP的INVITE(不是Option,是一個INVITE Request without SDP),雙方接通後實現RTP創建。然後,B2BUA對另外一端徹底拆線。在整個流程控制中,B2BUA始終扮演和一個控制器的作用,會話互相不影響。關於3PCC的四種操作流程,讀者可以查閱RFC3725進行進一步學習,規範分別對四種流程中INVITE和SDP處理要求有非常詳細的描述,這裡不再討論。


SIP Proxy和B2BUA消息重構

在前面的討論中,B2BUA是介於兩個會話直接的一個邏輯實體,為了能夠管理修改和保持雙方的會話狀態,B2BUA必須可以修改保存雙方會話的消息數據,這樣才能真正實現信令路徑和媒體路徑的完整性。因此,在B2BUA作為UAS/UAC角色切換時,UAS需要拷貝一些SIP消息到UAC,或者相反方向的SIP拷貝重構,否則沒有辦法獲悉從上游過來的消息。但是,因為SIP協議中有很多規範是需要雙方必須遵守的,因此,在拷貝雙方的SIP消息時,需要考慮哪些SIP消息頭是必須拷貝的,哪些SIP頭是完全可能拷貝的,哪些SIP頭是可以拷貝的。下面,我們通過一個示例就以上幾個問題進行分析,檢查雙方數據映射處理時重構結果。

我們的示例是一個簡單SIP終端通過B2BUA呼叫(INVITE)遠端SIP電話。這裡,我們再次強調,雙方呼叫的會話沒有直接的關係,這些SIP頭的重構完全依賴於B2BUA本身。現在,我們逐一介紹這些SIP頭的處理。

  • 首先,在INVITE中的Request-URL可以拷貝也可以通過B2BUA自己重新定義。典型的應用方式是B2BUA直接拷貝這個地址。所以,這個地址是可以直接拷貝的地址。
  • Call-ID,根據RFC3261的定義,它是一個全局變量,並且具有唯一性,因此,兩個會話都分別有各自不同的Call_ID,因此它是不能拷貝的。服務器端需要自己生成自己的ID。


  • Content-Length和Content-Type的處理,雙方的呼叫中,包含了SDP消息和其他下游媒體說需要的參數來和終端協商,B2BUA可以利用它們的Content-Length和Content-Type作為另外一個UA的SDP消息數據。因此,這些數據是可以拷貝的。當然,如果B2BUA進行了特別的編碼處理則是另外一個話題。
  • To和From 地址的處理,理論上說,B2BUA可以自由選擇自己本身所需要的地址。但是,如果沒有其他特別的要求,一般來說,B2BUA直接拷貝了另外一個UA的To地址。From 地址也是一樣的道理,B2BUA可以直接拷貝上游From地址,然後傳遞給下游終端,這樣SIP終端就會獲悉是哪個SIP終端的呼叫。當然,為了更好管理終端之間的呼叫,B2BUA也可以修改為自己B2BUA的地址,下游SIP終端可以獲悉是來自於B2BUA地址的3PCC呼叫。
  • Contact地址的處理,大家知道,如果呼叫到遠端SIP終端時,SIP終端就會保存Route Set的地址,這個地址用來支持後續的請求處理,這個Contact地址不應該是SIP終端地址,如果是SIP終端地址的話,兩個分機就可以實現直接呼叫。但是,在B2BUA的模式下,這個Contact地址不能直接拷貝到下游的Contact地址,只能使用本地B2BUA地址,這樣,下游的SIP終端收到的Contact地址就是B2BUA的地址。在呼叫創建時,下游終端就會通過B2BUA地址呼出。這樣,B2BUA始終在呼叫雙方的媒體路徑和信令路徑,保證B2BUA可以控制和管理呼叫流程。因此,這個Contact地址是不能直接拷貝的。
  • 關於CSeq的處理,根據RFC3261的定義,CSeq method類型必須反映request method的類型。為了保證請求類型的正確,因此,在B2BUA中CSeq的值可以直接拷貝,也可以重新初始化一個新的計算器值。
  • Max-Forward的處理,因為SIP終端設備可以選擇任何計算器的值,B2BUA可以自己決定重新設置為默認的計算器70。另外,因為在SIP路徑經過了一個Hop,所以B2BUA也可以根據上游設備提供的計算器值,自動遞減一次。因此,Max-Forward計算器值也可以直接拷貝或者直接使用上有的值。
  • Via 頭的處理。我們在以前的文章中專門討論了Via的用法,這個地址通知下游設備回覆響應的地址。上游的Via可能經過了多個Hop或者Proxy,對下游SIP終端發送Via時,這裡的B2BUA不關心上游Via的結果,B2BUA僅關心下游SIP終端返回的響應地址,通知下游SIP終端返回到B2BUA的地址,而不是其他的地址。這個Via地址必須是B2BUA的地址,所以,B2BUA不能直接拷貝上游Via的地址。


根據以上分析,我們可以看到,在B2BUA的模式下,大部分的SIP頭是可以拷貝重構的,Call-ID, Contact 地址和Via是完全不能拷貝的。基本上沒有B2BUA必須拷貝的SIP頭。因此,B2BUA是非常靈活,而且具有多種權限來管理SIP話話和應用服務。


特別注意,可能有時出現一些比較特殊的應用場景,例如mid-call的應用場景(中間播放語音提示或者或其他業務流程),如果SIP終端通過Proxy呼叫一個功能服務器,Proxy希望功能服務器端能夠快速響應,收到系統的請求返回到Proxy。但是,因為是B2BUA,功能服務器可能重新生成一個Call-ID, 這樣會導致遠端的SIP終端產生誤解。如何解決這個問題,B2BUA只能拷貝原來的Call-ID確保這是一個同樣的處理流程。具體此細節處理在RFC7329-4.5.2有定義。


根據以上討論,我們可以總結一些它們之間的區別。一般情況下,經過Proxy處理的SIP消息具有幾個方面的特點:大部分的頭是相同的,Proxy沒有處理這些SIP頭,Max-Forwards是遞減的,而且Via頭增加了一個Proxy自己的地址。但是,經過了B2BUA的SIP消息是經過重構的,因此很多SIP頭可能是不一樣的。SIP消息經過了B2BUA的重構以後,SIP消息具有明顯的不同:Contact地址變成了B2BUA的服務器的地址,Via消息是一個單列的地址,這個地址是B2BUA的需要的返回的地址,這裡可能是B2BUA的地址。這裡的Call-ID可能有例外(前面已經討論),可以是同樣的Call-ID。另外,CSeq具有靈活性,可以處理也可以恢復到默認狀態。


其他相關問題討論

除了我們上面討論的B2BUA的SIP消息重構以外,筆者在這裡和大家討論幾個和本文章相關的討論。在很多文章中,包括我們今天的討論中,我們一直使用透明B2BUA(transparent B2BUA)的說法。事實上,根據IETF組織的草案,透明B2BUA的工作方式類似於一個特別的Proxy,但是更多利用了UA的功能。透明B2BUA的功能其實和我們前面介紹的B2BUA功能相似,因此,這裡不再累述。因為透明B2BUA的概念比較寬泛,很多人對這個概念有很多爭論,而且在SIP處理方面具有非常強的靈活性,在一般的討論中,筆者建議根據具體的操作場景來解釋,或者通過一定的場景來理解。


當然,transparency(透明)proxy或者B2BUA是一個無休止的討論,到底有多透明,事實上,完全取決於SIP 處理的流程和業務場景。Proxy比較透明,因為它僅實現了RFC3261的簡單功能,沒有涉及太多的SIP消息重構和3PCC的處理。為了滿足3PCC或其他業務能力,透明B2BUA是一個非常明確的需求,但是在B2BUA的使用場景中,很多SIP 頭是需要經過UA處理的,例如,我們現在使用的SBC。SBC作為一個B2BUA需要對SIP 頭進行處理才能實現拓撲隱藏,協議正規化,編碼轉換和協議轉換等功能。因此,一些比較專業的SBC採取了一定的控制機制來實現透明處理(Relay和Transparency)。


我們在前面的章節中已經多次提及B2BUA和SIP Proxy之間的區別和SIP頭的變化。下面,我們提供幾個示例結合以前B2BUA和Proxy的區別,再次對SBC功能和SIP Proxy進行一個對比說明以幫助讀者進一步瞭解SBC和Proxy主要區別。讀者一定要注意標註的關鍵詞部分。

我們可以通過兩個示例來對比SBC和SIPProxy的消息經過變化。

經過了SBC後,Via 頭變成了SBC的地址,Call-ID發生了變化,Max-Forwards遞減,Contact頭修改為SBC地址,最後c=和m=發送了變化,支持RTP和RTCP的創建。如果經過了Proxy以後,SIP Via 頭中插入了新的Via地址,就是Proxy地址,另外,Max-Forwards發生遞減。其他頭沒有任何修改和變化。


通過以上示例,我們基本上可以理解B2BUA或者SBC和SIPProxy的區別。很多情況下,我們需要檢查系統的日誌來排查問題。那麼,現在問題來了。如何判斷這些SIP消息是經過Proxy的SIP消息還是B2BUA的SIP消息?這裡,我們做一個簡單的介紹以幫助讀者能夠非常快速判斷系統的SIP消息日誌。經過SIP Proxy的系統日誌是這樣的:


經過B2BUA 的SIP重構以後的消息變化是這樣的:

B2BUA/SBC/Proxy的SIP消息重構和RFC7092詳解

根據我們介紹的SIP消息經過Proxy和B2BUA的不同也可以看出兩者之間的不同,它們兩者都基本上完全遵守SIP的規範和各自的定義。


總結

本文章介紹了B2BUA的基本概念,SIP Proxy和B2BUA的區別,然後筆者介紹了B2BUA在3PCC中的應用場景分析。另外,筆者花費時間對B2BUA消息重構做了非常詳細地說明解析,同時對某些SIP頭的處理針對性地做了強調,幫助讀者能夠有重點地瞭解某些規範支持。最後,筆者對透明B2BUA處理,B2BUA的透明處理機制和SIP Proxy的區別做了討論。

再次說明,如果讀者缺少SIP其他方面基礎的介紹,需要查閱筆者的歷史文檔補充這些知識,這樣可以更好理解本章所學習的內容。


分享到:


相關文章: