筆者在前面的章節(jié)中已經針對一些基礎概念做了比較全面的分析和詳解,通過對這些必要的基礎概念的分享,讀者可以對SIP的基礎骨干有了一個清晰的認識。萬里長征第一步。學習任何知識,都需要我們從基礎輪廓開始,慢慢接觸細節(jié)知識。我們在以前的學習中可以獲知,SIP協(xié)議實際上是基于HTTP協(xié)議發(fā)展而來的(SIP協(xié)議不是HTTP協(xié)議的擴展),因此,它的基本操作流程也同樣符合HTTP協(xié)議的基本原理。進一步來說,其基本的處理流程就是一個請求和響應的流程。如果讀者需要進一步了解其SIP流程和基本的概念,可以查閱:
SIP協(xié)議及新IP企業(yè)通信網絡技術概論-核心SIP技術介紹-2
SIP協(xié)議及新IP企業(yè)通信網絡技術概論-核心SIP技術介紹-2

我們按照以上圖例根據不同的呼叫業(yè)務可以進一步解讀出SIP消息中關于請求和協(xié)議的更多的技術細節(jié),最基礎的兩個大類就是請求methods和響應碼,請求methods可以支持不同的請求,響應碼也根據對端狀態(tài)支持了非常不同的響應碼。在請求和響應交互中,通過不斷變換的SIP頭進行進一步的協(xié)商來完成呼叫流程。所以,我們在本章節(jié)的討論中,我們將對SIP消息核心知識進行全面討論,主要包括通常使用的請求methods(13或者14種methods),響應碼(1xx-6xx)和SIP頭。在具體實戰(zhàn)的操作過程中,技術人員同樣需要通過雙方的交互信息來對流程做相應的處理,也需要這些交互消息來排查問題。
注意,我們這里所說的SIP消息和SIP規(guī)范中的message有著非常明顯的不同。此消息和彼消息是完全不同的內涵。一般來說,SIP消息就是請求和響應的消息,客戶端對服務器端發(fā)送請求消息,服務器端對客戶端返回響應消息。我們這里通常所說的SIP消息是指一般的SIP請求和響應消息,而在SIP規(guī)范中的message是SIP規(guī)范的一種擴展的method,它允許SIP終端之間發(fā)送即時消息(instant message)。
1、SIP請求methods和響應碼
請求和響應是SIP響應的兩大核心要素。這兩大要素結合SIP頭決定著呼叫的最終結果。在具體的SIP請求中,根據RFC3261,SIP請求根據SIP呼叫請求的不同環(huán)境,SIP請求又細分6種不同的methods,這6種methods是RFC3261規(guī)范所規(guī)定的methods,另外還有8種常用的擴展SIP methds,這8種methods不是RFC3261的規(guī)范規(guī)定的methods,它們是通過SIP的擴展協(xié)議獲得的支持。所以,我們這里總共介紹14種不同的常用的SIP請求方式。
在SIP請求methods中,我們經常遇到的SIP請求methods包括:
- REGISTER:用來注冊一個用戶代理,通過臨時綁定一個用戶代理的URI到AOR地址,這樣服務器端能夠獲悉其用戶代理的位置。簡單來說,它負責注冊contact消息。
- INVITE,通過邀請一個用戶參與到會話來發(fā)起一個呼叫。另外,INVITE也可以修改會話。
- ACK,一個acknowledgement或者消息確認是作為一個對200 OK響應或其他響應的一個確認響應。這些響應是初始INVITE請求的結果,此時應該會產生會話,ACK僅對INVITE負責或者(re-INVITEs)。
- CANCEL用來取消待處理的請求。
- BYE用來指示結束呼叫或者會話。
- OPTIONS 負責查詢服務器端的媒體支持能力。
- INFO,負責mid-session的SIP信令消息之間的通信,它是一個RFC3261的擴展協(xié)議,具體規(guī)范參考RFC2976。具體使用示例包括PSTN網關的PSTN信令消息,傳輸會話中中需要傳輸的DTMF,計費賬號余額,無線移動端的無線信號狀態(tài),會話之間傳輸圖片或者其他非媒體的數據。
- PRACK,其全稱是Provisional ACK,從字面意思可以看出,它本身是一個臨時的ACK。因為它是一個臨時的響應,所以它僅用來對1xx臨時響應做出響應。在某些情況下,如果初始INVITE請求沒有攜帶SDP消息體的話,在1xx臨時響應后,PRACK可以包含相關的SDP消息體。另外需要注意,為了驗證其可靠性,每個臨時響應(例如從UAS來的183響應)都給定一個序列號,通過響應消息中的RSeg頭來傳輸,從UAC來的PRACK的消息中包含一個RAck頭,表示一個針對臨時響應的序列號的確認。它也是通過一個RFC3261規(guī)范的擴展協(xié)議來支持,具體規(guī)范參考RFC3262。
- Refer 用來轉接呼叫,也可以用來聯(lián)系外部資源。Refer method是SIP規(guī)范的擴展協(xié)議。具體關于定義Refer method規(guī)范,讀者可以查閱RFC3515。
- SUBSCRIBE用來在稍晚時間請求一個事件提醒或一系列事件。常見的示例是用來訂閱一個請求提示(Notification),當某人的IM在線狀態(tài)發(fā)生改變(離線,在線,忙狀態(tài)等)以后,對其發(fā)送提示事件。關于訂閱的擴展協(xié)議,讀者可以查閱RFC3265。
- NOTIFY用來對已訂閱的事件發(fā)送notify提示消息,它也可以通過SIP服務器端對SIP客戶端發(fā)送客戶端事件提示,例如語音郵箱留言等。讀者也可以按照RFC3265的規(guī)范進一步了解notify提示method。
- Update用來支持客戶端更新會話協(xié)商中的一些參數,例如媒體流的參數以及編碼等。注意,update不會影響dialog的狀態(tài)。關于更多update method,讀者可以參考SIP的擴展協(xié)議RFC3311。
- Publish發(fā)布和注冊一樣,它也允許用戶創(chuàng)建,修改和移除狀態(tài),不同的是它負責發(fā)布事件狀態(tài),用戶可以根據事件本身狀態(tài)來提示訂閱用戶。具體規(guī)范查閱RFC3903。
- Message method是SIP的擴展協(xié)議,用來傳輸請求的消息體中的即時消息。通過SIP 初始會話技術,結合在線狀態(tài)和即時消息構成了當前最強大的即時通訊系統(tǒng)。目前,即時消息或者IM使用已經非常普及,包括我們的QQ等。但是,SIP的強大之處在于提供了在線狀態(tài)應用,對基于會話初始應用機制提供支持,但是對即時消息支持不是SIP的優(yōu)勢。因此,讀者可以看到,在SIP應用中即時消息的使用仍然不是市場主流。關于SIP 消息的規(guī)范讀者可以查閱RFC3428,關于在線狀態(tài)和即時消息規(guī)范讀者可以查閱RFC2778和RFC2779。
關于以上SIP method的其他深入討論,讀者可以查閱參考鏈接,或者閱讀筆者的歷史文檔。因為篇幅原因,這里不再介紹。一些比較常見的method,例如, 100rel/PRACK,讀者可以查閱歷史文檔:
SIP拓展協(xié)議RFC3262概述和100rel/PRACK詳解
2、SIP請求和響應中的header
前面我們介紹了SIP的methods和它的一些控制協(xié)議支持的methods。在各種methods中,INVITE是我們最常用的method。在這些methods中需要通過各種header來進行通信協(xié)商。在本章節(jié)我們重點介紹一下method中的header和其響應中的header。因為篇幅所限,我們這里僅介紹INVITE method和其響應,讀者可以查閱SIP規(guī)范和其具體擴展協(xié)議深入了解更多的用途說明。以下是根據RFC3261官方介紹的一個基本的示例

INVITE的SIP頭 |
INVITE 200 OK響應的SIP頭 |
||
頭名稱 | 說明 | 頭名稱 | 說明 |
Request-Line | 表示請求類型,INVITE中包含目的地UA的SIP URI和其SIP以及版本 2.0 | Status-Line | 表示正在使用SIP 2.0, 返回 200 OK。 |
Via | 表示傳輸層協(xié)議使用,使用UDP,包含響應返回的IP地址和端口,branch ID(不可修改的)確認事務的唯一性,和RPORT | Via | 服務器端插入的頭,支持回環(huán)檢測,允許 200 OK找到返回到終端的路徑。返回此請求的響應,要注意,如果有route的話,應該發(fā)route;如果沒有route,則發(fā)Contact返回響應;如果沒有Contact,則發(fā)From返回。 |
From | 顯示呼叫方信息,呼叫方SIP URI,事實上是呼叫方的caller ID | From | 初始呼叫方信息和其SIP URI |
To | 顯示被呼叫方的信息 | To | 初始被呼叫方UA |
Call-ID | 是一個全局ID,針對具體某個dialog,在此dialog中,所有請求和響應事務都具有此同一Call-ID。 | Call-ID | 是一個全局ID,針對具體某個dialog。 |
CSeq | 用來確認事務和其事務的處理順序。在呼叫中,每個呼叫對象會維護自己的CSeq,并且會根據成功狀態(tài)會依次遞增。 | CSeq | 用來確認事務和其事務的處理順序。在呼叫中,每個呼叫對象會維護自己的CSeq,并且會根據成功狀態(tài)會依次遞增。 |
Contact | 顯示一個SIP URI,表示在后續(xù)請求中可以使用這個SIP URI聯(lián)系到此agent。 | Contact | 顯示一個SIP URI,表示在后續(xù)請求中可以使用這個SIP URI聯(lián)系到此agent。 |
Allow | 此agent支持的一個methods 列表 | Allow | 此agent支持的一個methods 列表 |
Max-Forwards | 用來限定代理或者網關前轉到下一跳的最大數量,每經過一個代理或者網關此值會遞減1,默認推薦值為70. | ||
Content-Type | 描述在此應用中的內容,應用,SDP類型。 | Content-Type | 描述在此應用中的內容,應用,SDP類型。 |
Proxy-Authorization |
用來支持對proxy代理的安全信息。 | ||
Supported | 描述此agent支持的擴展,例如100rel,timer,replaces 等等。 | ||
User-Agent | 表示具體的代理信息 | User-Agent | 表示具體的代理信息 |
Content-Length | 表示SDP消息體的長度,以byte為單位。 | Content-Length | 表示SDP消息體的長度,以byte為單位。 |
Record-Route | 代理插入的頭域值,強制在此dialog中的后續(xù)請求通過此代理路由 |
響應中的Via,From,To,Call-ID,CSeq是完全從請求中拷貝過來的。
To,From不會在請求和響應的交互中發(fā)生替換。
不同的服務提供商或者SIP終端發(fā)送的頭信息順序可能不同,這是符合規(guī)范的,例如CSeq和Call-ID的位置順序發(fā)生變化。
Supported/Reqiure的功能支持,客戶端通知服務器端需要支持的列表,服務器端返回require的功能列表。
關于以上問題的詳解,讀者可以進一步了解:
除了以上的關于SIP頭的一些介紹以外,在一些對帶寬非常敏感的網絡環(huán)境中,為了節(jié)省帶寬,SIP協(xié)議可以支持SIP頭的壓縮格式或者縮寫,具體的格式如下:
縮寫 | Header | 定義協(xié)議 | 原始含義 |
---|---|---|---|
a | Accept-Contact | draft-ietf-sip-callerprefs | -- |
b | Referred-By | -refer- | "by" |
c | Content-Type | RFC 3261 | |
e | Content-Encoding | RFC 3261 | |
f | From | RFC 3261 | |
i | Call-ID | RFC 3261 | |
k | Supported | RFC 3261 | "know" |
l | Content-Length | RFC 3261 | |
m | Contact | RFC 3261 | "moved" |
o | Event | -event- | "occurance" |
r | Refer-To | -refer- | |
s | Subject | RFC 3261 | |
t | To | RFC 3261 | |
u | Allow-Events | -events- | "understand" |
v | Via | RFC 3261 |
有時,在某些比較特殊的部署環(huán)境中,我們可能會看到一些帶X前綴的拓展的頭參數值。例如,有時需要對每個終端的聲音增益進行調整時,可以通過其擴展到X頭來調整。如果需要對話單用戶進行定義時,也可以通過X擴展頭來定義。這樣操作帶來的問題是,一些系統(tǒng)如果對X頭不支持的話,服務器端可能直接丟棄,并且拒絕解析這些字段,導致很多兼容性問題。因此,RFC6684規(guī)范對X擴展進行了說明,X頭將不再進行支持。
除了X頭以外,P header是一個仍然普遍使用的頭域值。它一方面使用在計費消息中,另外一方面主要使用在網絡穿越的環(huán)境設置中包括SBC用戶場景。例如,計費使用的P-Charge-Info,在可信網絡環(huán)境中P-Asserted-Identity傳輸用戶認證信息。特別在FCC強制要求美國運營商部署STIR/SHAKEN規(guī)范時,P-Asserted-Identity是必要的頭之一。關于STIR/SHAKEN,讀者可以查閱:
關于SIP P擴展頭的完整規(guī)范說明,讀者可以查閱RFC3325和RFC3455規(guī)范。
4、總結
在本文章中,筆者主要介紹了SIP協(xié)議中的14個核心的methods,另外根據一般用戶場景,我們也介紹了請求和響應中的SIP頭主要的頭域值介紹。筆者通過最常見的INVITE請求method結合其響應碼為大家簡單介紹了其頭值的具體內容。另外,筆者也討論了頭值的狀態(tài)變化,在這些header頭值中,一些關鍵的頭值在交互中不會發(fā)生變化或者修改,這些問題筆者也要注意。
除了RFC3261中一些標準的SIP頭以外,SIP支持其他的擴展頭,包括X頭和P頭值擴展,這些頭值可以進一步完善具體或者特殊用戶場景多其他參數的支持。
雖然筆者盡量在討論中涵蓋SIP規(guī)范的關于SIP methods和響應碼以及SIP擴展頭的全部內容,但是,因為篇幅所限和實際應用示例非常繁多,用戶只能通過最常見的INVITE和響應來為讀者解讀SIP核心概念,希望起到一個拋磚引玉的作用,其他的methods可以根據讀者提供的RFC規(guī)范線索做深入了解。
參考資料:
- https://datatracker.ietf.org/doc/html/rfc2976
- https://www.ietf.org/rfc/rfc3262.txt
- https://datatracker.ietf.org/doc/html/rfc3311
- https://www.ietf.org/rfc/rfc3428.txt
- https://datatracker.ietf.org/doc/html/rfc2976
- https://datatracker.ietf.org/doc/html/rfc3265
- https://www.ietf.org/rfc/rfc3903.txt
- https://datatracker.ietf.org/doc/html/rfc6648
- https://datatracker.ietf.org/doc/html/rfc3455