SIP代理服务器(2)
4請求轉發
對于上一步確定的每一個目的地,proxy轉發請求都遵循下列步驟:
1)、 拷貝一個接收到的請求
2)、 更新Request-URI
3)、 更新Max-Forwards頭域
4)、 可選增加一個Record-Route頭域
5)、 可選增加附加的頭域
6)、 路由信息后處理
7)、 決定下一個節點地址、端口、通訊協議。
8)、 增加一個Via頭域值
9)、 如果需要,增加一個Content-Length頭域
10)、 轉發這個新的請求
11)、 設置定時器C
(2) 更新Request-URI
在拷貝好的請求中的Request-URI必須用目的地的URI進行替換。
(3) Max-Forwards
如果拷貝的頭域包含一個Max-Forwards,proxy必須把這個域值減一。
如果拷貝的頭域沒有包含一個Max-Forwards頭域,proxy必須自己增加一個頭域,缺省值是70。現在有一些UA不會在請求中填寫Max-Forwards頭域。
(4)Record-Route
在建立一個對話的請求時,如果希望保留這個請求創建的對話中,后續的請求依舊是要經過本proxy,那么本proxy必須增加一個Record-Route頭域值在這個拷貝中,并且增加的這個頭域值應當是在其他現存的Record-Route頭域之前。
而在對話建立之后的請求中,即使不再增加Record-Route,對話之中的請求還是會經過該代理服務器,除非終端UA重建一個對話。
在Record-Route頭域中防止的URI必須是SIP或者SIPSURI。這個URI必須包含一個lr參數。
當proxy需要查看所有對話中的消息的時候,我們就需要Record-routeing,即一般在建立對話的請求INVITE中包含Record-Route頭域。
(6)處理路由信息
如果請求的拷貝中包含了Route頭域,這個proxy必須檢查這個Route頭域的第一個值。如果這個URI并沒有包含lr參數,那么proxy必須根據下列步驟修改這個請求:
- proxy必須把Request-URI放在Route頭域中的最后一個值。
-proxy必須把第一個Route頭域的值放在Request-URI中,并且從Route頭域中刪去。
(7)確定下一個節點的地址,端口和通訊協議。
proxy可以有自己的策略來決定發送請求到特定的IP地址,端口和transport,可以和Route的值或者Request-URI的值無關。
proxy還可以應用RFC 3263的步驟來決定應當向哪里發送這個請求。
(8)增加一個Via頭域值 。
proxy必須在請求的拷貝中增加一個Via頭域值,并且在其他Via頭域值之前增加。proxy需要計算自己的分支參數,并且應當是全局唯一的分支,并且包含必要的magiccookie。
在proxy構造分支參數的值上,有一個附加的約束,用來進行循環的檢測。一個要檢測循環的proxy應當創建一個由兩部分組成的分支參數。第二部分是用來做循環檢測的,并且是從螺旋中判定是否存在循環。
(8)設置定時器C。
為了能夠處理INVITE請求沒有產生終結應答的情況,TU使用一個定時器。
5應答的處理
當proxy收到一個應答的時候,它首先嘗試定位一個與這個應答匹配的客戶端事務。如果沒有匹配,proxy必須作為無狀態的proxy來處理這個應答(即使這個應答是信息性質的應答)。如果與應答匹配的客戶端事務找到了,那么這個應答將轉給這個客戶端事務進行處理。
當客戶端事務把應答交給proxy層,將會執行下列步驟:
1)、 尋找適當的應答上下文。
2)、 用臨時應答來更新定時器C
3)、 從最上邊移除Via
4)、 在應答上下文中增加應答
5)、 檢查這個應答是否需要立刻發送
6)、 如果需要,從應答上下文中選擇最好的終結應答。
7)、 需要合并認證頭域值。
8)、 可選的重寫Record-Route頭域值
9)、 轉發應答
10)、 產生合適的CANCEL請求。
(3)從最上邊移除Via
如果在這個應答中沒有這個Via頭域值,那么應答的含義就是說這個應答不應當被這個proxy轉發。
(4)在應答上下文中增加應答
收到的終結應答都會保存在應答的上下文中,直到收到一個由服務端事務產生的針對這個上下文的終結應答為止。這個應答是從那個服務端事務中收到最佳終結應答的一個候選。即使這個應答不會被選中作為最佳應答,這個應答的信息也需要用來構造成為最佳應答。
(5)檢查這個應答是否需要立刻發送
當終結應答到達服務端事務的時候,下列應答包必須立刻轉發。
- 任何非100(trying)的臨時應答
- 任何2xx應答。
如果收到一個6xx應答,那么就不立刻進行轉發,如果是有狀態的proxy,那么還需要cancel所有的依賴于這個事務的客戶端(在10節中描述的那樣),并且不能在上下文中創建新的分支。
在服務端事務上發送了終結應答之后,下列的應答應當立刻被發送:
- 任何給INVITE請求的2xx應答。
一個有狀態的proxy必須不能立刻轉發其他的應答。特別是,一個有狀態的poxy必須不能轉發任何100(Trying)應答。這些應答是作為后續將被轉發”最佳”應答的候選,通過上邊的”在上下文中增加應答”的步驟增加到應答上下文中。
(6)選擇最佳的應答 (略)
(8)Record-Route
如果最終發送的應答中包含Record-Route頭域值,并且是這個proxy所原創提供的值,那么在發送這個應答前,proxy可能需要重寫這個值。
(9)轉發應答
當”合并認證頭域”和”Record-Route”步驟完成以后,proxy可以對這個應答做其他的附加處理。但是這個proxy不能增加、修改、刪除消息體。并且除非另有指示,除了Via頭域值之外,proxy不能刪除任何頭域值。
proxy必須把應答傳遞到跟這個應答上下文相關的服務端事務。這會導致應答發送到最上的Via頭域值的地方。
6Proxy Route處理的總結
在沒有本地策略的情況下,proxy對于包含Route頭域的請求處理可以歸結于如下的步驟:
1、proxy會檢查Request-URI。如果它指向的是本proxy所負責的區域,那么proxy會用位置服務的結果來替換這個URI。否則,proxy不改變這個URI。
2、proxy會檢查Route頭域的最上URI。如果這個URI指向這個proxy,這個proxy從Route頭域中移除(這個路由節點已經到達)。
3、proxy會轉發請求到最上的Route頭域值所標志的URI,或者Request-URI(如果沒有Route頭域)。proxy通過RFC3263的步驟來產生地址,端口,通訊協議等等用來轉發請求所必須的參數。
如果在請求的路徑中,沒有嚴格路由節點,Request-URI會始終標志著請求的目的地。
7無狀態的Proxy
當作為無狀態的時候,proxy就是一個簡單的消息轉發者。很多無狀態的處理步驟和有狀態的時候很類似。不同的地方在下邊描述。
一個無狀態的proxy并沒有事務的概念,或者用于描述有狀態proxy行為的應答上下文。相反的是,無狀態的proxy處理消息,無論是請求還是應答,都是直接從通訊層處理的。當然,無狀態proxy自己也不重發這些消息。他們只是轉發他們收到的任何重發的消息(他們本身并沒有能力來分辯那些消息是重發的,那些消息是原始消息)。進一步說,當無狀態的處理一個請求的時候,這個節點并不產生它自己的100(Trying)或者其他臨時應答。
總結
以上是生活随笔為你收集整理的SIP代理服务器(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为畅享50处理器揭秘:99%可能中芯国
- 下一篇: 嵌入式的基础知识