天天透天天干,欧美福利在线,国产三级网站,色婷婷综合网,亚洲欧美成人一区二区,亚洲国产精品成人久久久麻豆,国产剧情久久久

您當前的位置是:  首頁 > 資訊 > 文章精選 >
 首頁 > 資訊 > 文章精選 >

關于SIP Proxy處理中的八大疑問討論

2019-03-25 14:00:46   作者:james.zhu   來源:CTI論壇   評論:0  點擊:


  在SIP呼叫過程中,SIP代理服務器具有非常重要的作用。呼叫雙方通過SIP代理對呼叫定位管理,在通過代理時,代理服務器可能刪減一些必要的字段,也可能修改一些請求的字段,滿足完成呼叫的必要條件,達成一個完整的呼叫流程。那么,為什么SIP代理服務器會修改這些需求?筆者歸納了八個非常核心的問題,理解了這基本的八個問題會幫助讀者徹底了解代理的角色和修改的原因。
  前面我們很多文章是從比較大的寬泛的角度來討論SIP呼叫。關于proxy代理的定義,我們需要從官方的定義做尋找答案。根據RFC3261的定義,SIP proxy是:
  SIP proxies are elements that route SIP requests to user agent . servers and SIP responses to user agent clients.  A request may traverse several proxies on its way to a UAS.  Each will make routing decisions, modifying the request before forwarding it to the next element.
  https://tools.ietf.org/html/rfc3261#section-16
  為了回答這幾個核心的問題,今天,我們從比較細節(jié)的流程來分析呼叫處理流程的創(chuàng)建。首先,結合上面的圖例,我們需要了解proxy在對下游UA繼續(xù)發(fā)送INVITE之前,它需要做哪些方面的處理?事實上,proxy在對下游發(fā)起INVITE之前,它需要做一些預處理工作。因為需要做這些工作,所以會導致我們對proxy產生的六大疑問,這也是比較重要的關于SIP創(chuàng)建呼叫所經常面對的終極問題。這八個終極問題涉及了Route header,Request URL,MAX-Forwards,Via header,100 Trying,ACK直接互發(fā)。下面,我們逐一針對這些常見的問題進行比較細致的分析。
  1、為什么移除Route header
  在討論Route功能之前,我們首先說明一下Route的基本概念。在RFC3261中規(guī)定,此頭是用來強制request路由多個proxy,很多環(huán)境環(huán)境可能經過多個proxy來處理呼叫。
  The Route header field is used to force routing for a request through  the listed set of proxies.
  https://tools.ietf.org/html/rfc3261#section-20.34
  如果用戶需要了解具體的測試場景,用戶可以下載任意一個開源平臺的測試環(huán)境來進行測試。
  在前面的文章中我們已經介紹過,如果UAC需要發(fā)起一個呼叫的話,可以通過INVITE的地址request URL來查詢定位服務器和注冊服務器,然后進行呼叫。實際上,我們這里忽略了一個非常核心的header-Route。大家現在看看這個基本的示例:
  在實際發(fā)起請求的過程中,如果Route存在的話,request其實首先根據Route對代理服務器發(fā)起請求,然后再發(fā)送INVITE中的具體賬號信息。這里,Route可以是FQDN格式,此頭則通過DNS查詢來獲得IP地址。
  這個請求抵達下一個proxy以前,此Route地址會在proxy中移除。因為,這個Route的任務已經完成。另外,從雙方的INVITE消息中可以看出,針對這個INVITE的請求中,UAS端的消息中已經移除了Route header。
  因此,筆者提醒讀者必須理解以下“黃金定律”:
  1. Route 頭決定proxy下一跳的路由地址
  2. 繼續(xù)下一跳之前,移除Route header
  3. Route頭比request URL具有更高優(yōu)先級
  4. 如果Route不存在,則使用request URL
  5. Route header支持FQDN查詢處理,解析為IP地址
  6. 路由總是使用最頂端Route header地址(后面介紹)
  在以前的介紹中,我們已經介紹了Route header, request URL,Contact address和Via 地址,F在,筆者簡單總結幾個路由地址的區(qū)別:
  • Route header是針對下一跳的路由,如果有此頭,則request會根據此header被路由到下游
  • Request URL:如果Route header不存在的話,則請求根據此header路由。
  • Contact header:終端IP地址,為其他終端提供subsequent requests返回路由,例如ACK或者BYE消息發(fā)送。
  • Via header: 支持UAC地址或者proxy地址,為下游設備提供返回響應的路由,總是從Via 頂部地址優(yōu)先路由,proxy在轉發(fā)到下游前移除自己的地址。
  這里我們可以看到,經過proxy到達UAS時,Route需要移除,然后根據request URL來對UAS做呼叫路由。所以,必須移除Route header,否則,協(xié)議處理的流程會發(fā)生沖突。
  2、為什么需要替換Request URL
  在以前的很多討論中,我們討論了如何通過AOR查詢對應的Contact地址,然后進行呼叫的多個示例。現在,讓我們再回顧一次呼叫的流程處理:
  首先,呼叫方發(fā)起INVITE以后,定位服務器會一步步查詢所屬domain地址,然后查詢注冊表,如果有注冊的數據內容,進行AOR和Contact的地址解析,然后proxy替換這個request URL,對Contact進行INVITE請求。當然,處理過程中也涉及了如果不在正常處理流程中的其他處理方式,我們這里不做進一步討論。
  根據以上處理流程我們可以看出,首先,定位服務器需要查詢此呼叫的AOR是否存在或者屬于此定位服務器支持的domain。如果此domain存在的話,則進行AOR解析,然后替換成Contact地址,proxy最后呼叫這個具體的Contact地址或request URL。但是,這里讀者一定要注意,proxy做了兩個主要的工作。為了滿足前面我們提到的Route 頭優(yōu)先路由和無Route header情況下的處理原則,proxy在對對端發(fā)送INVITE之前,proxy需要移除Route header,只有這樣,INVITE請求才能根據Request URL進行路由。在以下示例消息中,當proxy再次對被呼叫方發(fā)起INVITE之前,已經移除了Route header,終端路由根據請求地址來路由。
  因此,proxy對下游UAC發(fā)送INVITE之前,替換了AOR地址,使用了請求地址,而且移除了Route header,替換為request URL,這樣可以保證請求時通過請求URL地址路由。
  3、為什么MAX-Forwards需要遞減
  在比較復雜的SIP呼叫環(huán)境中,一個呼叫可能經過多個domain和定位服務。如果其中一個proxy設置錯誤的話,可能導致一個定位查詢的回環(huán),這樣UAC就會收到482 Rejected 的消息。為了防止回環(huán)的發(fā)送,在定位查詢過程中,每成功通過一個proxy,Max-Forwards的計數器就會自動減一,直到抵達最終UAC。
  在SIP消息中,如果出現了大量的Via header的話,讀者一定要注意,這可能發(fā)生了回環(huán)。導致這樣錯誤可能是某些地址設置問題。讀者需要檢查具體的配置文件。
  以下是一個檢測到回環(huán)的流程,經過多個接點的檢查以后,Max-Forwards可能最后遞減成了0,這樣說明檢測到了loop。經過一點時間檢查,最后對UAC發(fā)送482 消息。
  4、為什么proxy增加一個Via header
  為了讓下游UA獲悉自己的返回地址,每經過一個proxy,proxy必須自己主動添加自己的地址作為一個新的Via header。如果呼叫請求經過了多個proxy以后,那么這個Via 記錄就會不斷增加,并且,Via 頭根據順序來進行增加,最新的Via header會出現在Via 頭最頂端。所有的Via 添加類似于一個隊列處理。在增加了一個新的Via以后,proxy必須對最頂端(Via header)返回一個100 Trying? 為什么呢? 因為,proxy必須對上游proxy說明自己的狀態(tài),通知上游proxy已經收到了proxy的請求。
  如果雙方呼叫通過了多個跳轉以后,每經過一個proxy會增加一個自己的Via header,直到抵達最后的UAC地址。最后的UAC地址則包含了多個Via header。底部是最起始的地址,最頂部是最近地址。
  當UAC接聽呼叫后,返回響應消息時,則按照請求路徑的相反的處理流程依次進行處理。首先,通過頂部第一個Via地址返回到 proxy 3, proxy 然后從Via header 移除自己的地址,按照Via 地址,返回到proxy 2。最終返回到發(fā)起呼叫的UAC地址。每經過一跳就移除自己本身的Via地址。
  5、為什么100 Trying沒有返回
  在前面的章節(jié)中,我們通過一封信的方式解釋了INVITE請求中幾個主要的頭字段的功能說明。Via header就是其中之一,其主要作用下游終端知道通過這個地址返回進一步的響應消息,負責返回響應的路由路徑管理。根據RFC3261的規(guī)定,Via 頭的定義是:
  The Via header field indicates the transport used for the transaction and identifies the location where the response is to be sent.
  https://www.ietf.org/rfc/rfc3261.txt
  根據RFC3261的定義和我們以前的介紹,本身100 Trying就是一個可靠性傳輸的響應機制,其主要目的就是讓保證上下游之間的可靠性傳輸,沒有承擔其他的功能角色。
  如果經過多個proxy處理時,怎么能夠保證雙方之間的通信是可靠的? 100 Trying是一個高效的方式來實現這個簡單的功能。如果proxy對下游proxy發(fā)送一個INVITE以后,對端對自己上游發(fā)送一個100 Trying,說明自己已經接收到了這個請求,proxy就知道對端的狀態(tài)。因此,proxy此刻的任務已經完成。因此,proxy也不會對上游UAC發(fā)起方發(fā)送100 Trying,避免了資源浪費。另外,回顧我們以前的討論,100 Trying不能再次重復轉發(fā),不像其他響應,例如180 ring。proxy仍然需要對上游UAC發(fā)送180 ring消息,保證會話的完整性。
  6、為什么使用Route set路由
  前面我們介紹過Route set和Via的區(qū)別,讀者可以回顧前面的討論來了解Via的作用。Proxy通過Via獲得了最終地址,雙方已經確認了地址消息,proxy完成了其工作。雙方確認了狀態(tài)以后,UAC會保存對端的Contact地址作為響應的直接地址。下來,UA1 可以根據這個Contact地址,直接對UA2發(fā)送ACK確認。
  但是,讀者一定要注意,當UAC2收到UAC1 的地址后,在返回200 OK時,UAC2會把自己的地址添加到Contact中作為Contact地址,這樣做的目的是通知UAC1,UAC2的地址就是200 OK中的這個Contact地址。UAC雙方最終的通信是通過Route set來進行,雙方保存了Contact地址以后,雙方可以直接通過Contact地址發(fā)送ACK或者BYE消息。
  因此,這里UAC之間的直接通信是通過Route set來實現,而不是Via 地址。
  7、為什么UAC之間直接發(fā)送ACK
  首先,我們需要理解proxy的角色,proxy的主要功能就是定位被呼叫方的Contact地址和進行下一跳代理功能。為了協(xié)助UAC進行通信,Proxy經過多個定位和路由最終找到UAC,UAC已經對proxy發(fā)送了100 Trying,其主要任務已經完成。為了降低系統(tǒng)資源的負載,proxy不再參與其流程處理,雙方通過route set的地址可以直接發(fā)送ACK確認消息,因此不再需要通過proxy繼續(xù)處理ACK或BYE消息。
  注意,我們這里沒有涉及有狀態(tài)代理和無狀態(tài)代理的內容,那是另外一個話題,不在我們這里討論的范圍。讀者不要對這里的討論產生疑惑,我們僅討論UAC之間ACK的發(fā)送問題。
  8、不同域名之間的呼叫處理
  兩個不同域名用戶之間的呼叫中,proxy需要進行地址查詢或定位查詢,找到相應的domain定位服務器。如果被呼叫方用戶不屬于自己domain的用戶,則根據domain來查詢DNS,通過DNS獲得domain地址以后,再繼續(xù)查詢確認好的定位服務器。定位服務器最終找到相應的用戶帳戶。那么,現在的問題來了,上游proxy如何處理這個AOR地址和路由呢?下面,我們看看具體的處理流程。首先,第一個proxy需要添加自己的地址,然后發(fā)送到下游定位服務器。
  這里比較關鍵的服務是在第二個定位服務器和代理的處理上。第二個定位服務器在對自己終端發(fā)送INVITE之前,必須先移除Route地址,proxy使用request URL地址來做呼叫路由。為什么需要這樣處理?因為,根據前面講到的route header的使用原則,在最后的INVITE中如果沒有Route header,則使用request URL。因此,第二個proxy在發(fā)送INVITE之前,必須移除Route header,使用requerst URL做呼叫路由。這樣就完成了不同domain之間的呼叫。
  9、總結
  我們今天通過八個問題的討論,基本上回答了很多SIP用戶的關于Proxy處理的疑惑。這八個終極問題涉及了Route header,Request URL,MAX-Forwards,Via header,100 Trying,ACK直接互發(fā),和不同域名之間的呼叫流程。另外,筆者也針對幾個主要的路由地址歸納了幾個不同,方便讀者進一步清晰地了解SIP路由的概念。最后,筆者需要讀者重點掌握SIP頭路由的幾個黃金定律,它們是決定如何路由的前提條件。
  參考資料:
  https://www.tutorialspoint.com/session_initiation_protocol/session_initiation_protocol_proxies_and_routing.htm
  https://www.slideshare.net/JonasBorjesson/aboutsip-routing
  https://tools.ietf.org/html/draft-byerly-sip-hide-route-00
   
  關注微信公眾號:asterisk-cn,獲得有價值的Asterisk行業(yè)分享
  Asterisk freepbx 中文官方論壇:http://bbs.freepbx.cn/forum.php
  Asterisk freepbx技術文檔: www.freepbx.org.cn
  融合通信商業(yè)解決方案,協(xié)同解決方案首選產品:www.hiastar.com
  Asterisk/FreePBX中國合作伙伴,官方qq技術分享群(3000千人):589995817
 

【免責聲明】本文僅代表作者本人觀點,與CTI論壇無關。CTI論壇對文中陳述、觀點判斷保持中立,不對所包含內容的準確性、可靠性或完整性提供任何明示或暗示的保證。請讀者僅作參考,并請自行承擔全部責任。

專題

CTI論壇會員企業(yè)