• <strike id="fdgpu"><input id="fdgpu"></input></strike>
    <label id="fdgpu"></label>
    <s id="fdgpu"><code id="fdgpu"></code></s>

  • <label id="fdgpu"></label>
  • <span id="fdgpu"><u id="fdgpu"></u></span>

    <s id="fdgpu"><sub id="fdgpu"></sub></s>
    您當前的位置是:  首頁(yè) > 資訊 > 文章精選 >
     首頁(yè) > 資訊 > 文章精選 >

    關(guān)于SIP Proxy處理中的八大疑問(wèn)討論

    2019-03-25 14:00:46   作者:james.zhu   來(lái)源:CTI論壇   評論:0  點(diǎn)擊:


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

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

    專(zhuān)題

    CTI論壇會(huì )員企業(yè)

    亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩 太仓市| 义乌市| 伊春市| 兴化市| 安仁县| 石门县| 宁明县| 岱山县| 东城区| 渭源县| 榆林市| 满城县| 哈密市| 民县| 高平市| 修文县| 宝应县| 惠州市| 浑源县| 玉林市| 麦盖提县| 华池县| 英吉沙县| 克山县| 金华市| 东方市| 淮阳县| 柳江县| 屏山县| 都兰县| 柏乡县| 黔东| 且末县| 四川省| 雷州市| 建湖县| 琼结县| 云安县| 文化| 龙里县| 武平县| http://444 http://444 http://444 http://444 http://444 http://444