本文摘抄自csdn博文sip route與 record_route /sip路由機制解析sip路由可以簡單分為請求訊息路由和響應訊息路由。invite、bye、ack、cancel等屬於請求訊息,200 ok、180、183、480等狀態返回碼屬於響應訊息。
響應訊息的路由非常簡單,就是完全依靠via來完成的,具體請見我關於rfc3261中會話流程的分析。
乙個sip訊息每經過乙個proxy(包括主叫),都會被加上乙個via頭域,當訊息到達被叫後,via頭域就記錄了請求訊息經過的完整路徑。被叫將這些via頭域原樣copy到響應訊息中(包括各via的引數,以及各via的順序),然後下發給第乙個via中的uri,每個proxy**響應消 息前都會把第乙個via(也就是它自己新增的via)刪除,然後將訊息**給新的第乙個via中的uri,直到訊息到達主叫。
via是為了給乙個請求訊息的響應訊息留後路。
在理解請求訊息路由的時候,首先應該了解什麼是嚴格路由?什麼是鬆散路由?
嚴格路由可以理解為比較「死板」的理由機制,這種路由機制在sip協議的前身rfc 2534中定義,其機制非常簡單。
要求接收到的訊息的request-uri必須是自己的uri,然後它會把第乙個route頭域「彈」出來,並把其中的uri作為新的request-rui,然後把該訊息路由給該uri。
該路由機制較為靈活,也是sip路由機制的靈魂所在,在sip根本大典rfc 3261中定義。
鬆散路由的proxy的路由決策過程:
proxy首先會檢查訊息的request-uri是不是自己屬於自己所負責的域。如果是,它就會通過定位服務將該位址「翻譯」成具體的聯絡位址並以此替換掉原來的request-uri;否則,它不會動request-uri。
proxy檢查第乙個route頭域中的uri是不是自己的,如果是,則移除之。
前面兩項都是準備工作,下面該進行真正的路由了。如果還有route頭域,則proxy會把訊息路由給該頭域中的uri,否則就路由給request-uri。至於如何從下一跳uri確定出ip位址,埠以及傳輸協議那是另外一回事了。
對於前面的3條規則,我們可以簡單總結為一句話:route的優先順序高於request-uri的。
乙個請求訊息的傳輸過程中,proxy也可能(純粹自願,如果它希望還能接收到本次會話的後續請求訊息的話)會新增乙個record-route頭域,這樣當訊息到達被叫後裡面就有會有0個或若干個record-route頭域。被叫會將這些record-route頭域併入路由集,隨後被叫在傳送請求訊息時就會使用該路由集構造一系列route頭域,以便對訊息進行路由。
被叫會像上面對待via頭域一樣,將record-route頭域全部原樣copy到響應訊息中返回給主叫。主叫收到響應訊息後也會將這些record-route頭域併入路由集,只是它會將其反序。該會話中的後續請求訊息的route頭域就會通過路由集構造。
注意:
場景描述:兩個ue間有兩個proxy,u1 -> p1 -> p2 -> u2,並且兩個proxy都樂意新增record-route頭域。
u1發出乙個invite請求給p1(p1是u1的外撥**伺服器)。
invite sip:[email protected] sip/2.0
contact: sip:[email protected]
p1不負責域domain.com,訊息中也沒有route頭域,因此通過dns查詢得到負責該域的proxy的位址並且把訊息**過去。這裡p1在**前就新增了乙個record-route頭域,裡面有乙個lr引數,說明p1是乙個鬆散路由器,遵循rfc3261中的路由機制。
invite sip:[email protected] sip/2.0
contact: sip:[email protected]
record-route:
p2負責域domain.com,因此它通過定位服務得到[email protected]對應的裝置位址是[email protected],因此用新的uri重寫request-uri。訊息中沒有route頭域,因此它就把該訊息**給request-uri中的uri,**前它也增加了 乙個record-route頭域,並且也有lr引數。
invite sip:[email protected] sip/2.0
contact: sip:[email protected]
record-route:
record-route:
位於u2.domain.com的被叫收到了該invite訊息,並且返回乙個200 ok響應。其中就包括了invite中的record-route頭域。
sip/2.0 200 ok
contact: sip:[email protected]
record-route:
record-route:
被叫此時也就有了自己的路由集:
(,)
通話完畢後,我們假設主叫先掛機,則主叫發出bye請求。
bye sip:[email protected] sip/2.0
route: ,
可以看到,bye的route頭域正是主機的路由集構造來的。由於p1在第乙個route中,因此bye首先發給p1。
p1收到該訊息後,發現request-uri中的uri不屬於自己負責的域,而訊息有route頭域,並且第乙個route頭域中的uri正是自己,因此刪除之,並且把訊息**給新的第乙個route頭域中的uri,也就是p2:
bye sip:[email protected] sip/2.0
route:
p2收到該訊息後,發現request-uri中的uri不屬於自己負責的域(p2負責的是domain.com,而不是u2.domain.com),第乙個route頭域中的uri正是自己,因此刪除之,此時已經沒有route頭域了,因此就**給了request-uri中的uri。被叫就會收到bye訊息:
bye sip:[email protected] sip/2.0
場景描述:u1->p1->p2->p3->p4->u2,其中,p3是嚴格路由的,其餘proxy都是鬆散路由的,並且4個proxy都很樂意增加record-route頭域。本例主要關注嚴格路由與鬆散路由的區別。
前面的過程省略,直接給出了到達被叫的invite訊息:
invite sip:[email protected] sip/2.0
contact: sip:[email protected]
record-route:
record-route:
record-route:
record-route:
中間的其他訊息省略,直接給出被叫最後發出的bye訊息:
bye sip:[email protected] sip/2.0
route:
route:
route:
route:
因為p4在第乙個route裡,因此被叫將bye訊息發給了p4。
p4收到該訊息後,發現自己不負責域u1.example.com,但是第乙個route頭域中的uri正是自己,因此刪除之。p4還發現新的第乙個 route頭域中的uri是乙個嚴格路由器,因此它把request-uri中的uri新增到最後乙個route的位置,並且將第乙個route「彈出」 並且覆蓋原來的request-uri。然後將訊息**給當前的request-uri,也就是p3。
bye sip:p3.middle.com sip/2.0
route:
route:
route:
p3收到該訊息後,直接把訊息作出如下變換並且發給p2:
bye sip:p2.example.com;lr sip/2.0
route:
route:
p2收到該訊息後,發現訊息中的request-uri是自己的,因此在進一步處理先首先對訊息做如下變換:
bye sip:[email protected] sip/2.0
route:
然後,p2發現自己不負責域u1.example.com,第乙個route中的uri也不是自己的,因此將訊息**給該uri,也就是p1。
p1收到該訊息後,發現自己不負責域u1.example.com,但是第乙個route頭域中的uri正是自己,因此刪除之。訊息變成下面的樣子:
bye sip:[email protected] sip/2.0
既然route頭域已經是空,因此p1把訊息發給u1.example.com。
SIP 路由機制
總的來說,sip中存在兩種路由場景 1,請求訊息的路由 2,響應訊息的路由 其中,響應訊息的路由非常簡單,就是完全依靠via來完成的,具體請見我關於rfc3261中會話流程的分析。下面我們只談sip請求訊息的路由。首先我們要搞清楚什麼是嚴格路由和鬆散路由。嚴格路由 strict routing 可以...
sip路由原理
sip是voip業務中,最為重要的協議之一,那麼對於這個協議,我們在之前的一些文章中個,也闡述過與之相關的一些基礎內容。這裡我們不在贅述。那麼今天的重點,就是講解一下sip路由機制的相關知識。總的來說,sip路由機制包括兩個場景 1,請求訊息的路由 2,響應訊息的路由 其中,響應訊息的路由非常簡單,...
SIP訊息路由機制
一 請求路由 鬆散路由 loose router 和嚴格路由 strict router 這是sip協議 rfc3261 中的乙個非常重要的概念。在sip訊息的route頭域或record route頭域中,攜帶的域值是sip uri或sips uri,如果這個uri帶有 lr 屬性值,那麼,就表示...