前面我們很多文章是從比較大的寬泛的角度來(lái)討論SIP呼叫。關(guān)于proxy代理的定義,我們需要從官方的定義做尋找答案。根據(jù)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)題,今天,我們從比較細(xì)節(jié)的流程來(lái)分析呼叫處理流程的創(chuàng)建。首先,結(jié)合上面的圖例,我們需要了解proxy在對(duì)下游UA繼續(xù)發(fā)送INVITE之前,它需要做哪些方面的處理?事實(shí)上,proxy在對(duì)下游發(fā)起INVITE之前,它需要做一些預(yù)處理工作。因?yàn)樾枰鲞@些工作,所以會(huì)導(dǎo)致我們對(duì)proxy產(chǎn)生的六大疑問(wèn),這也是比較重要的關(guān)于SIP創(chuàng)建呼叫所經(jīng)常面對(duì)的終極問(wèn)題。這八個(gè)終極問(wèn)題涉及了Route header,Request URL,MAX-Forwards,Via header,100 Trying,ACK直接互發(fā)。下面,我們逐一針對(duì)這些常見(jiàn)的問(wèn)題進(jìn)行比較細(xì)致的分析。
1、為什么移除Route header
在討論Route功能之前,我們首先說(shuō)明一下Route的基本概念。在RFC3261中規(guī)定,此頭是用來(lái)強(qiáng)制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
如果用戶需要了解具體的測(cè)試場(chǎng)景,用戶可以下載任意一個(gè)開源平臺(tái)的測(cè)試環(huán)境來(lái)進(jìn)行測(cè)試。
在前面的文章中我們已經(jīng)介紹過(guò),如果UAC需要發(fā)起一個(gè)呼叫的話,可以通過(guò)INVITE的地址request URL來(lái)查詢定位服務(wù)器和注冊(cè)服務(wù)器,然后進(jìn)行呼叫。實(shí)際上,我們這里忽略了一個(gè)非常核心的header-Route。大家現(xiàn)在看看這個(gè)基本的示例:
在實(shí)際發(fā)起請(qǐng)求的過(guò)程中,如果Route存在的話,request其實(shí)首先根據(jù)Route對(duì)代理服務(wù)器發(fā)起請(qǐng)求,然后再發(fā)送INVITE中的具體賬號(hào)信息。這里,Route可以是FQDN格式,此頭則通過(guò)DNS查詢來(lái)獲得IP地址。
這個(gè)請(qǐng)求抵達(dá)下一個(gè)proxy以前,此Route地址會(huì)在proxy中移除。因?yàn),這個(gè)Route的任務(wù)已經(jīng)完成。另外,從雙方的INVITE消息中可以看出,針對(duì)這個(gè)INVITE的請(qǐng)求中,UAS端的消息中已經(jīng)移除了Route header。
因此,筆者提醒讀者必須理解以下“黃金定律”:
- Route 頭決定proxy下一跳的路由地址
- 繼續(xù)下一跳之前,移除Route header
- Route頭比request URL具有更高優(yōu)先級(jí)
- 如果Route不存在,則使用request URL
- Route header支持FQDN查詢處理,解析為IP地址
- 路由總是使用最頂端Route header地址(后面介紹)
在以前的介紹中,我們已經(jīng)介紹了Route header, request URL,Contact address和Via 地址,F(xiàn)在,筆者簡(jiǎn)單總結(jié)幾個(gè)路由地址的區(qū)別:
- Route header是針對(duì)下一跳的路由,如果有此頭,則request會(huì)根據(jù)此header被路由到下游
- Request URL:如果Route header不存在的話,則請(qǐng)求根據(jù)此header路由。
- Contact header:終端IP地址,為其他終端提供subsequent requests返回路由,例如ACK或者BYE消息發(fā)送。
- Via header: 支持UAC地址或者proxy地址,為下游設(shè)備提供返回響應(yīng)的路由,總是從Via 頂部地址優(yōu)先路由,proxy在轉(zhuǎn)發(fā)到下游前移除自己的地址。
這里我們可以看到,經(jīng)過(guò)proxy到達(dá)UAS時(shí),Route需要移除,然后根據(jù)request URL來(lái)對(duì)UAS做呼叫路由。所以,必須移除Route header,否則,協(xié)議處理的流程會(huì)發(fā)生沖突。
2、為什么需要替換Request URL
在以前的很多討論中,我們討論了如何通過(guò)AOR查詢對(duì)應(yīng)的Contact地址,然后進(jìn)行呼叫的多個(gè)示例,F(xiàn)在,讓我們?cè)倩仡櫼淮魏艚械牧鞒烫幚恚?/div>
首先,呼叫方發(fā)起INVITE以后,定位服務(wù)器會(huì)一步步查詢所屬domain地址,然后查詢注冊(cè)表,如果有注冊(cè)的數(shù)據(jù)內(nèi)容,進(jìn)行AOR和Contact的地址解析,然后proxy替換這個(gè)request URL,對(duì)Contact進(jìn)行INVITE請(qǐng)求。當(dāng)然,處理過(guò)程中也涉及了如果不在正常處理流程中的其他處理方式,我們這里不做進(jìn)一步討論。
根據(jù)以上處理流程我們可以看出,首先,定位服務(wù)器需要查詢此呼叫的AOR是否存在或者屬于此定位服務(wù)器支持的domain。如果此domain存在的話,則進(jìn)行AOR解析,然后替換成Contact地址,proxy最后呼叫這個(gè)具體的Contact地址或request URL。但是,這里讀者一定要注意,proxy做了兩個(gè)主要的工作。為了滿足前面我們提到的Route 頭優(yōu)先路由和無(wú)Route header情況下的處理原則,proxy在對(duì)對(duì)端發(fā)送INVITE之前,proxy需要移除Route header,只有這樣,INVITE請(qǐng)求才能根據(jù)Request URL進(jìn)行路由。在以下示例消息中,當(dāng)proxy再次對(duì)被呼叫方發(fā)起INVITE之前,已經(jīng)移除了Route header,終端路由根據(jù)請(qǐng)求地址來(lái)路由。
因此,proxy對(duì)下游UAC發(fā)送INVITE之前,替換了AOR地址,使用了請(qǐng)求地址,而且移除了Route header,替換為request URL,這樣可以保證請(qǐng)求時(shí)通過(guò)請(qǐng)求URL地址路由。
3、為什么MAX-Forwards需要遞減
在比較復(fù)雜的SIP呼叫環(huán)境中,一個(gè)呼叫可能經(jīng)過(guò)多個(gè)domain和定位服務(wù)。如果其中一個(gè)proxy設(shè)置錯(cuò)誤的話,可能導(dǎo)致一個(gè)定位查詢的回環(huán),這樣UAC就會(huì)收到482 Rejected 的消息。為了防止回環(huán)的發(fā)送,在定位查詢過(guò)程中,每成功通過(guò)一個(gè)proxy,Max-Forwards的計(jì)數(shù)器就會(huì)自動(dòng)減一,直到抵達(dá)最終UAC。
在SIP消息中,如果出現(xiàn)了大量的Via header的話,讀者一定要注意,這可能發(fā)生了回環(huán)。導(dǎo)致這樣錯(cuò)誤可能是某些地址設(shè)置問(wèn)題。讀者需要檢查具體的配置文件。
以下是一個(gè)檢測(cè)到回環(huán)的流程,經(jīng)過(guò)多個(gè)接點(diǎn)的檢查以后,Max-Forwards可能最后遞減成了0,這樣說(shuō)明檢測(cè)到了loop。經(jīng)過(guò)一點(diǎn)時(shí)間檢查,最后對(duì)UAC發(fā)送482 消息。
4、為什么proxy增加一個(gè)Via header
為了讓下游UA獲悉自己的返回地址,每經(jīng)過(guò)一個(gè)proxy,proxy必須自己主動(dòng)添加自己的地址作為一個(gè)新的Via header。如果呼叫請(qǐng)求經(jīng)過(guò)了多個(gè)proxy以后,那么這個(gè)Via 記錄就會(huì)不斷增加,并且,Via 頭根據(jù)順序來(lái)進(jìn)行增加,最新的Via header會(huì)出現(xiàn)在Via 頭最頂端。所有的Via 添加類似于一個(gè)隊(duì)列處理。在增加了一個(gè)新的Via以后,proxy必須對(duì)最頂端(Via header)返回一個(gè)100 Trying? 為什么呢? 因?yàn),proxy必須對(duì)上游proxy說(shuō)明自己的狀態(tài),通知上游proxy已經(jīng)收到了proxy的請(qǐng)求。
如果雙方呼叫通過(guò)了多個(gè)跳轉(zhuǎn)以后,每經(jīng)過(guò)一個(gè)proxy會(huì)增加一個(gè)自己的Via header,直到抵達(dá)最后的UAC地址。最后的UAC地址則包含了多個(gè)Via header。底部是最起始的地址,最頂部是最近地址。
當(dāng)UAC接聽呼叫后,返回響應(yīng)消息時(shí),則按照請(qǐng)求路徑的相反的處理流程依次進(jìn)行處理。首先,通過(guò)頂部第一個(gè)Via地址返回到 proxy 3, proxy 然后從Via header 移除自己的地址,按照Via 地址,返回到proxy 2。最終返回到發(fā)起呼叫的UAC地址。每經(jīng)過(guò)一跳就移除自己本身的Via地址。
5、為什么100 Trying沒(méi)有返回
在前面的章節(jié)中,我們通過(guò)一封信的方式解釋了INVITE請(qǐng)求中幾個(gè)主要的頭字段的功能說(shuō)明。Via header就是其中之一,其主要作用下游終端知道通過(guò)這個(gè)地址返回進(jìn)一步的響應(yīng)消息,負(fù)責(zé)返回響應(yīng)的路由路徑管理。根據(jù)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
根據(jù)RFC3261的定義和我們以前的介紹,本身100 Trying就是一個(gè)可靠性傳輸?shù)捻憫?yīng)機(jī)制,其主要目的就是讓保證上下游之間的可靠性傳輸,沒(méi)有承擔(dān)其他的功能角色。
如果經(jīng)過(guò)多個(gè)proxy處理時(shí),怎么能夠保證雙方之間的通信是可靠的? 100 Trying是一個(gè)高效的方式來(lái)實(shí)現(xiàn)這個(gè)簡(jiǎn)單的功能。如果proxy對(duì)下游proxy發(fā)送一個(gè)INVITE以后,對(duì)端對(duì)自己上游發(fā)送一個(gè)100 Trying,說(shuō)明自己已經(jīng)接收到了這個(gè)請(qǐng)求,proxy就知道對(duì)端的狀態(tài)。因此,proxy此刻的任務(wù)已經(jīng)完成。因此,proxy也不會(huì)對(duì)上游UAC發(fā)起方發(fā)送100 Trying,避免了資源浪費(fèi)。另外,回顧我們以前的討論,100 Trying不能再次重復(fù)轉(zhuǎn)發(fā),不像其他響應(yīng),例如180 ring。proxy仍然需要對(duì)上游UAC發(fā)送180 ring消息,保證會(huì)話的完整性。
6、為什么使用Route set路由
前面我們介紹過(guò)Route set和Via的區(qū)別,讀者可以回顧前面的討論來(lái)了解Via的作用。Proxy通過(guò)Via獲得了最終地址,雙方已經(jīng)確認(rèn)了地址消息,proxy完成了其工作。雙方確認(rèn)了狀態(tài)以后,UAC會(huì)保存對(duì)端的Contact地址作為響應(yīng)的直接地址。下來(lái),UA1 可以根據(jù)這個(gè)Contact地址,直接對(duì)UA2發(fā)送ACK確認(rèn)。
但是,讀者一定要注意,當(dāng)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í)現(xiàn),而不是Via 地址。
7、為什么UAC之間直接發(fā)送ACK
首先,我們需要理解proxy的角色,proxy的主要功能就是定位被呼叫方的Contact地址和進(jìn)行下一跳代理功能。為了協(xié)助UAC進(jìn)行通信,Proxy經(jīng)過(guò)多個(gè)定位和路由最終找到UAC,UAC已經(jīng)對(duì)proxy發(fā)送了100 Trying,其主要任務(wù)已經(jīng)完成。為了降低系統(tǒng)資源的負(fù)載,proxy不再參與其流程處理,雙方通過(guò)route set的地址可以直接發(fā)送ACK確認(rèn)消息,因此不再需要通過(guò)proxy繼續(xù)處理ACK或BYE消息。
注意,我們這里沒(méi)有涉及有狀態(tài)代理和無(wú)狀態(tài)代理的內(nèi)容,那是另外一個(gè)話題,不在我們這里討論的范圍。讀者不要對(duì)這里的討論產(chǎn)生疑惑,我們僅討論UAC之間ACK的發(fā)送問(wèn)題。
8、不同域名之間的呼叫處理
兩個(gè)不同域名用戶之間的呼叫中,proxy需要進(jìn)行地址查詢或定位查詢,找到相應(yīng)的domain定位服務(wù)器。如果被呼叫方用戶不屬于自己domain的用戶,則根據(jù)domain來(lái)查詢DNS,通過(guò)DNS獲得domain地址以后,再繼續(xù)查詢確認(rèn)好的定位服務(wù)器。定位服務(wù)器最終找到相應(yīng)的用戶帳戶。那么,現(xiàn)在的問(wèn)題來(lái)了,上游proxy如何處理這個(gè)AOR地址和路由呢?下面,我們看看具體的處理流程。首先,第一個(gè)proxy需要添加自己的地址,然后發(fā)送到下游定位服務(wù)器。
這里比較關(guān)鍵的服務(wù)是在第二個(gè)定位服務(wù)器和代理的處理上。第二個(gè)定位服務(wù)器在對(duì)自己終端發(fā)送INVITE之前,必須先移除Route地址,proxy使用request URL地址來(lái)做呼叫路由。為什么需要這樣處理?因?yàn),根?jù)前面講到的route header的使用原則,在最后的INVITE中如果沒(méi)有Route header,則使用request URL。因此,第二個(gè)proxy在發(fā)送INVITE之前,必須移除Route header,使用requerst URL做呼叫路由。這樣就完成了不同domain之間的呼叫。
9、總結(jié)
我們今天通過(guò)八個(gè)問(wèn)題的討論,基本上回答了很多SIP用戶的關(guān)于Proxy處理的疑惑。這八個(gè)終極問(wèn)題涉及了Route header,Request URL,MAX-Forwards,Via header,100 Trying,ACK直接互發(fā),和不同域名之間的呼叫流程。另外,筆者也針對(duì)幾個(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)注微信公眾號(hào):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中國(guó)合作伙伴,官方qq技術(shù)分享群(3000千人):589995817
Asterisk freepbx 中文官方論壇:http://bbs.freepbx.cn/forum.php
Asterisk freepbx技術(shù)文檔: www.freepbx.org.cn
融合通信商業(yè)解決方案,協(xié)同解決方案首選產(chǎn)品:www.hiastar.com
Asterisk/FreePBX中國(guó)合作伙伴,官方qq技術(shù)分享群(3000千人):589995817
【免責(zé)聲明】本文僅代表作者本人觀點(diǎn),與CTI論壇無(wú)關(guān)。CTI論壇對(duì)文中陳述、觀點(diǎn)判斷保持中立,不對(duì)所包含內(nèi)容的準(zhǔn)確性、可靠性或完整性提供任何明示或暗示的保證。請(qǐng)讀者僅作參考,并請(qǐng)自行承擔(dān)全部責(zé)任。
上一篇:呼叫中心系統(tǒng)應(yīng)用功能系列談(二)
下一篇:Genesys駱麗娟:Balance for Better,客戶與員工的融合智能體驗(yàn)場(chǎng)景設(shè)計(jì)
相關(guān)閱讀:
- ·再論SIP呼叫中的Call、Dialog和Transaction2019-04-10 09:43:20
- ·分叉呼叫(Fork) 具體處理流程分析2019-04-08 14:27:55
- ·深入理解SIP服務(wù)器的注冊(cè)和定位服務(wù)流程2019-03-19 09:12:59
- ·一封信讀懂SIP注冊(cè)消息關(guān)鍵詞2019-03-18 11:41:19
- ·SIP推送協(xié)議草案新版本發(fā)布2019-03-13 14:04:03
- ·關(guān)于SIP協(xié)議中ACK處理機(jī)制討論2019-03-11 13:43:47
- ·淺析SIP響應(yīng)消息100 Trying的作用和傳輸機(jī)制2019-03-04 15:27:31
- ·最常用的18個(gè)SIP呼叫業(yè)務(wù)流程詳解完整版(一)2019-01-29 15:42:30
- ·SIP語(yǔ)音環(huán)境中十大經(jīng)典問(wèn)題及解決辦法2018-12-28 09:37:18
- ·標(biāo)準(zhǔn)化SIP中繼的3個(gè)令人信服的理由2018-12-05 10:06:56