作者:gnuhpc
出處:http://www.cnblogs.com/gnuhpc/
1.SIP這玩意是怎麼走來和如何構建的?
通俗的說,SIP就是一個輕量級信令協議,它可以作為音頻、視頻、及時資訊的信令。
說到SIP是怎麼出來的就要提H.323,而提到這個標準由不得不提到ITU-T,我們就先說說指定SIP的IETF(Internet Engineering Task Force)和制定H.323的ITU-T(International Telecommunications Union–Telecommunications Standard Sector)之間一些小趣事吧。ITU-T和IETF想事兒總是不一樣的,它們倆往往從兩個不同的角度來進行。ITU-T作為一個隸屬於美國的國際標準組織,傳承了美國政策的一致性和試圖完成維護世界和平的角色,所以它制定出來的標準一定是經過無數輪的反覆和草案,花了N年制定出一個最終的,廣為接受的結果。而恰恰相反,IETF則更趨近於實用主義,信奉“rough consensus and running code”,也就是說能用進行,邊用邊補充唄。因此在大多數時候,IETF標準制定的周期要比ITU-T短一些,這可能也歸因於IETF每年舉辦三次開放性論壇。這些春季、夏季、秋季會議會安排在世界各地,並且向各個對此感性趣的組織開放(去瞅一瞅吧:http://www.ietf.org/meetings/meetings.html )多個IETF工作群組在這些會議上相聚,針對他們現在的系統開發敲定一些技術細節,對於要是到了會議結束時還是沒有解決的問題那就幾個月後的下次開會繼續研究唄。簡而言之,IETF以一種實際實用的角度去完善體系架構和協議設計。
說了這麼多可能你還沒有意識到我在扯這些是為了什麼,但是請記住這些正是SIP(Session Initiation Protocol)架構所體現的核心思想——先用著,再擴充。SIP的結構是建立於兩個常用協議之上的:在RFC 2821中的SMTP 協議(Simple Mail Transfer Protocol )——它定義了電子郵件的訊息格式,以及定義在RFC 2616的HTTP協議 (Hypertext Transfer Protocol )——它定義了基於Web的多媒體通訊訊息。另外,SIP又使用了定義在RFC 3550中的RTP/RTCP協議(Real Time Transport Protocol/Real Time Control Protocol )——它定義了在IP網上的多媒體包格式,還使用了定義在RFC 2327的SDP協議(Session Description Protocol )——它定義了一個多媒體會話的參數和特徵。因此,SIP是建立在其他IETF提出的協議之上的,這有點像H.323建立在諸如H.225.0和H.245等ITU-T制定的協議之上,它的兩個比較基礎的RFC分別是版本1.0 RFC2543和版本2.0 RFC3261。當然,SIP還運行於其他IETF定義的傳輸協議之上,比如TCP(Transport Control Protocol ), UDP(User Datagram Protocol ) 和IP (Internet Protocol )等。這樣,這麼多著名的,並且被廣泛應用的協議為SIP提供了超於H.323的簡單明了的特性。
在網上看到了這樣三個MindMap,覺得很能表達SIP的基本核心思想:
關於SIP的架構,我們一定要知道這玩意不是什麼新鮮玩意,你看看它基於什麼就知道了,這麼個拼出來的東東架構能嶄新到什麼地步呢?我的粗淺理解是SIP的主要架構其實就是一個典型的C-S架構:一個Client用戶端在RFC3261中定義為一個發送SIP請求並接收SIP回應的網路元素,這個Client可能與也可能不與人進行互動。對應的,一個Server伺服器是接受SIP請求並且給予其回應的網路元素。比如最典型的是一個SIP請求INVITE,邀請一個使用者或者伺服器參與會話,若得到的是肯定的響應的話,那麼則會返迴響應SUCCESS。要是再深入一點,我們可以將這樣一個簡單的分類進行細分:
Client分為兩類:
使用者代理程式用戶端User Agent Client :它是一個邏輯功能,它建立請求、並且使用這個功能實體的一些具體功能發送出請求。
代理Proxy :中文翻譯過來還是代理,但是這個與上邊的Agent不一樣,它是一個中間裝置,既作為Client,也作為Server ,可以解釋、翻譯、改寫一個請求,並將請求轉寄給其他的伺服器,完成路由功能。有時候有狀態和無狀態Proxy,所謂有狀態就是Proxy根據不同的情形作出不同的處理,這些處理具有前後的相關性,比如三個人傳數字,A要通過B給C傳一個數字,一種情況是不管A說什麼,B都說同一數字給C,這叫做無狀態Proxy;另一種狀態是A說1的話,B就傳給C數字2,要是A說2的話,B就傳給C數字3,這樣就是一個有狀態的Proxy。有些資料上有所為B2BUA,實質與Proxy很相似,只不過更加靈活。
Server分類三類:
使用者代理程式伺服器User Agent Server: 它是一個邏輯功能,它對一個請求產生應答。
重新導向伺服器Redirect Server: 一個將用戶端的請求重新導向去聯絡另一個伺服器以完成請求的伺服器。
註冊伺服器Registrar :一個接受REGISTER 註冊請求,並將資訊放置於位置伺服器的伺服器。
注意:我們在書上常常看到的UA是一個概括的說法,之所以區分UAS和UAC只是從邏輯上區分,實質上不一定是獨立物理實體。
2.SIP該在哪,能幹啥?
我們學習SIP就要知道它的地位,有個宏觀的瞭解才能知道N多協議之間的關係:
既然根據RFC 3261,SIP是基於STMP和HTTP的,並且底層使用了IP、UDP和TCP,那麼它就是一個應用程式層協議,也就是說,它能為End User提供服務,你能看得見摸得著。描述SIP應用服務的單位是會話,也就是英文中Session一詞,意為在兩個或多個參與者之間有順序的交換資訊,更深入一點,SIP必須先去扮演建立會話的角色,然後再在通訊中管理會話。大家更關注的有三點:
a.多於兩個的參與者就意味著呼叫可能是多點的,而不僅僅是點對點的那樣子。
b.End User可能總不是從相同的地點發起呼叫的,我們需要添加追蹤這些End User的功能。
c.End User可能會使用文字、音頻、視頻等的混合媒體類型,這些在網路中對網路的頻寬、最大傳輸延時等都有不同的要求和限制。SIP還需要對此進行有效處理。
針對以上的Concerns,RFC 3261主要定義了五個方面的SIP多媒體會話管理能力:
· 使用者位置管理:決定哪一個端系統用於這次通訊。
· 使用者可用性:決定被叫端是不是願意參與這次通訊。
· 使用者容量:決定用於這次通訊的媒體以及其參數。
· 會話建立:在被叫和主叫兩端建立會話參數。
· 會話管理: 包含轉接和終止會話、修改會話參數、調用會話業務。
3. SIP依靠怎麼運作?
既然SIP是建立在SMTP和HTTP上的,那麼其訊息格式也有巨大的相似性,但是注意到一個SIP會話的資源是通訊資源,而不是頁面或者網頁資源,這是與HTTP不同的地方。一個身份或者叫做一個定址體制必須在請求/響應集有效建立之前建立。身份標識就是所謂的SIP URI(SIP Uniform Resource Indicator),其中包含了充足的資訊來初始化一個會話。使用這個標識的資源的例子(RFC 3261中提供的)有:有線上業務的使用者、在一個訊息系統中的一個郵箱,在一個組織中的一組邏輯使用者(例如銷售部門),一個PSTN電話號碼等等。SIP URI與電子郵件地址類似,這也是借用了SMTP協議中的規定:典型的包含兩部分,第一部分為使用者名稱,第二部分為主機名稱,sip:huangpc@bupt.cn, 這是RFC 2543所介紹的最通常的格式。 當然SIP URI還有其他的一些格式,比如在RFC 3261中引入的安全SIP URI:sips:huangpc@bupt.cn, 這個是在TCP上的TLS作為安全傳輸層的一種方式。
定義了使用者標識後,我們就可以定義請求的標識了——SIP中稱為方法(Method)。其他的擴充方法在後續的RFC中都有定義。
· REGISTER: 用於與SIP伺服器進行註冊。
· INVITE: 用於表明使用者或者伺服器被邀請參與這個會話。這個訊息體中將包含一個對被叫端的會話描述。
· ACK: 僅用了INVITE請求,表明收到請求。
· CANCEL: 用於取消一個pending 的請求。
· BYE: User Agent Client使用者代理程式用戶端發送,來告訴伺服器它希望結束通話。
· OPTIONS: 向伺服器查詢它的能力。
定義完請求,很自然我們需要回應的語言規範:包含狀態代碼和描述性短語。分為六類:
· 1xx: 暫時性回應,表明已經接收到,正在處理之中。
· 2xx: 成功回應,表明動作已經被接收,理解並且接受了。
· 3xx: 重新導向回應,需要進一步的動作來處理處理這個請求。
· 4xx: 用戶端錯誤回應,請求中文法不對,不能被伺服器接受。
· 5xx: 伺服器錯誤回應,伺服器不能處理這個有效請求。
· 6xx: 全域錯誤回應,這個請求不能被任何伺服器接受。
你現在可能比較納悶,這都是些關於SIP會話建立和拆除的部分,但關於這個會話中要傳的文字、音視頻等的格式等雙方是怎麼知道的呢?在INVITE中,就帶有了這些資訊,這個資訊的格式則又引出了另一個RFC,RFC 2327,會話描述協議(Session Description Protocol (SDP))。
SIP和其他協議一樣都有這樣的一個要求:在會話開頭時兩端要有充分的資訊交流。使用的兩個協議就是定義在RFC 2974中的SAP(Session Announcement Protocol )和定義在RFC 2327的SDP (Session Description Protocol)。簡單來說,SAP提供了一種定期宣傳多媒體會話,向有意參與會話者傳遞相關會話資訊的機制。使用它來支援Mbone(Internet Multicast Backbone),因此關興趣的各方都會清楚的指導目前進行中的一些會話。而SDP則定義了描述一個通訊會話的格式,同樣的,它也可以用於不同的傳輸協議,比如SAP、SIP、HTTP或其他等傳輸協議。學習時要注意SDP的載體是SIP。RFC 2327專門註明了一些SDP能提供的比較關鍵的資訊:
會話名和目的。
會話啟用的時間。
構成會話的媒體。
怎麼樣接收這些媒體(地址、連接埠號碼、格式等)
而另一些資訊則是可選附帶的,例如會議使用的頻寬,負責這個會話的那個人的連絡方式等等。
說到這些你可能覺得很抽象,我們趕緊那個例子RFC 2327中的例子來看看:
v=0
o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
s=SDP Seminar
i=A Seminar on the session description protocol
u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
e=mjh@isi.edu (Mark Handley)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 31
m=application 32416 udp wb
a=orient:portrait
我們看到SDP格式包含多行文本,都是以 = 的格式書寫的,RFC中的星號*指的是選擇項。我們主要有三類的會話描述:會話描述、時間描述、媒體描述,具體你可以參看RFC 2327。注意這個例子中,兩個m開頭的行,定義了音視頻的概要,這些概要是在RFC 3550 Real Time Protocol (RTP)中的第13節和RFC 3551 RTP Profile for Audio and Video Conferences with Minimal Control 中的第6節,在編碼最後的那個0和31,這是在後續RTP幀中要使用的負載類型值,用來確定媒體和編碼類別型。49170和51372都是接收者的連接埠,寄件者連接埠分別加1,也就是說在這個例子中49171和51373是寄件者的連接埠。
4.SIP到底怎麼運作?
一個最簡單的例子是在SIP呼叫建立兩個直接相連的端對端的通話過程。發起者會發起一個INVITE訊息給對端來發起會話,接著會收到Ringing和OK訊息。被叫端返回ACK表明串連完成,可以進行資訊交流了。當不需要這個串連時,任何一端發送BYE訊息給對端,對端返回OK來結束通話。
注意,SIP訊息和具體的媒體流並不是在一個層面運作的。例如,一個VoIP電話是先通過SIP信令完成互動後再開始具體媒體流的傳輸的,如,SIP的根本作用的完成點對點(或多點)的媒體流傳輸的前序工作。
在RFC 3261中描述了一個比較複雜的例子:使用了Proxy 伺服器作為通訊通路。SIPProxy 伺服器代表其他的Client發起請求,並且在許多時候作為路由模式,將SIP請求轉寄給另一個距離最終目的地(也就是被叫端)較近的裝置。因此,SIPProxy 伺服器扮演著兩個角色——在接收請求時是server角色,在發送請求時是client角色。注意,Proxy 伺服器必須可以解釋一個SIP訊息,並且需要的時候轉寄這條訊息前對其進行重寫,大的網路中可能有多個Proxy 伺服器。在RFC3261中的第四節中有個比較有趣的例子,描述了兩個SIP終端通過兩個Proxy 伺服器建立呼叫的過程。在這個例子中,兩個終端位於兩個不同的城市:Atlanta and Biloxi,因此是在兩個相互隔離的網路中。每個網路有它自己的Proxy 伺服器,分別稱為atlanta.com 和 biloxi.com。 若在Atlanta的Alice想呼叫在Biloxi的Bob,那麼Alice的電話就會發送以下的INVITE訊息給它的Proxy 伺服器atlanta.com:
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob
From: Alice ;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 142
當這個訊息通過網路轉到Bob後Bob要是願意接受這個呼叫那麼它就會返回一個OK,這個訊息會先到biloxi.com 代理:
SIP/2.0 200 OK
Via: SIP/2.0/UDP server10.biloxi.com
;branch=z9hG4bKnashds8;received=192.0.2.3
Via: SIP/2.0/UDP bigbox3.site3.atlanta.com
;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
Via: SIP/2.0/UDP pc33.atlanta.com
;branch=z9hG4bK776asdhds ;received=192.0.2.1
To: Bob ;tag=a6c85cf
From: Alice ;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 131
我們注意到有相同的Call-ID來保證這個會話的單一性。更多的細節參看RFC 3261裡的這個例子的具體解釋。
5.SIP中的信令和媒體之間的關係:
SIP等於為媒體的建立進行實現的溝通,打個比喻,只有你知道你要說話的那個人在那,並且兩個人都要找到彼此暢通的語言,這樣才能更有效溝通。
而真正開始兩人滔滔不絕的傾心交談了,就與前邊這些對話前的相互瞭解和基本溝通沒有關係了。
6.幾個重要的概念:
呼叫(call): 呼叫是一個非正式的術語,用來表示一個多媒體會話,用Call-ID來標識;不論兩方通話還是在多方通話中,在每個UA中是使用同一個Call-ID;
事務(transaction): 請求(UAC)+最終響應(相鄰的UAS),SIP基於事務。所謂相鄰就是說transaction存在於相鄰的SIP實體,而不是存在於兩個UA之間。CSeq標識。一個事務中包含一個請求訊息、0個或多個臨時響應訊息、1個或多個最終響應訊息(2xx~6xx)。SIP是事務性的協議。事務的區分通過Via欄位棧頂的Branch的值來確定,這是由於對於請求訊息每經過一個有事務狀態的Proxy的時候,該Proxy需要為這個事務建立一個伺服器端事務和一個用戶端事務,並且將自己的URI添加到Via的棧頂,並產生一個Global ID做為Branch的值,以此值來表示一個與之相對應的事務。SIP在事務層面定義了狀態機器和定時器來實現重傳。
是一個回複200 OK的成功的INVITE事務:是不是INVITE事務區別在於 UAC需要為每個INVITE最終請求(2xx~6xx)產生ACK響應,而其他的請求訊息(INFO,OPTION,etc)則不必如此。因為INVITE的地位比較重要, 所以需要這樣一個三向交握的機制來保證會話的雙方都能夠確保事務的完整性,這一點和TCP串連建立的三向交握比較像。
注意在這兩個UA中,每一個Proxy 伺服器都將自己的地址加入返回的ACK的Via頭域中,而非成功的transaction則不會加入,見RFC 3261 (p.24)。CSeq頭域的值必須與INVITE相同,並且CSeq的方法必須是ACK。中間響應訊息 1xx 的使用則是為了節省網路開銷設計的,一旦 UC 收到任何一個中間響應訊息,則 UC 必須停止訊息重發定時器,不再從發這個請求訊息,反之則直到收到最終響應訊息或重發定時器逾時。一旦用戶端UAC的事務在Calling狀態收到任何中間響應訊息1xx,事務則自動切換到Processing狀態,停止請求訊息的重發。並且需要將中間響應訊息傳送給TU事務使用者。在呼叫業務中,TU以及上層應用可以根據中間響應訊息在使用者介面上提示使用者。一旦事務切換到Processing狀態,任何其他中間響應訊息也都要傳送給TU。
而非INVITE事務則如下:
當UAC發出非INVITE請求時,它就會在交易管理子層上開啟定時器F(TCP)或者是E(UDP),確保逾時的時候進行重傳。這適用於除了 ACK請求外的其他非INVITE請求。每次逾時重傳時E的時間都被翻倍,直到最大的4秒。而F逾時時,UAC就會認為是Timeout,這個事務將被刪除。
對話(dialog/leg): 代表著兩個SIP UA之間持續一段時間的端到端的聯絡(如:一段通話)。也就說僅僅存在於端到端的信令關係。當一個UAS發出對於INVITE(或者REFER)的非失敗最終響應<=>200OK(BYE),則Dialog建立,同時這也是session的開始。UA和SIPProxy 伺服器之間不會有對話。在SIP中呼叫中包含一個或多個Dialog(這僅僅存在於多方通話中)。Dialog終結於任意一端發出 BYE。Early Dialog可以通過UAC發出的CANCEL進行終結,更確切的說,所有早期對話在接收到非2XX最終響應時就被終結了。 Call-ID-value、To、From進行標識。Forking時體現明顯。
在這個Forking的例子中,這個使用者註冊了三個裝置,在使用者被呼叫時,INVITE的Contact頭域就被轉換為三個INVITE發往三個裝置。後邊的q指的是優先順序,q越小,優先順序越高。其中的SIP註冊伺服器相當於一個Forking代理,儘管這個實體接收到兩個ACK,但是除了這些ACK外,它與主叫方的信令互動都是屬於一個transaction的,而與被叫方則分別建立了Transaction。另外,被叫方收到的兩個ACK由分別建立了Transaction。注意Device3返回了488這樣的非成功響應,SIP註冊伺服器(ForkingProxy 伺服器)沒有將該響應發回主叫方,這是SIP代理一個重要的特徵,SIP代理還能自行發出Request:CANCEL訊息。
UAS對話層接收到一個新的對話請求INVITE訊息後,在建立會話的響應訊息2xx中,將請求訊息裡面的所有Route-Record欄位拷貝到2xx訊息中,並且UAS的對話層必須添加一個Contact欄位使得對話中後續的響應(INVITE在2xx響應的情況下也包括ACK訊息)、請求訊息可以直接和本UA聯絡。當UAC收到UAS的INVITE的2xx響應訊息後,如果2xx中不包含任何Route-Record欄位的,則UAC可以選擇直接發送ACK到Contact中地址&連接埠。
會話(session): 多方使用者的媒體關係,在對話的控制下建立。
是Early dialog、Session、Dialog、Transaction等的在一個UA-UA的呼叫中的體現:
在這個例子中,通過INVITE事務而成功建立起來的dialog必須有一個ACK進行回應,這是第二個transaction的開始,儘管ACK並沒有回複,但是由於新的 branch-value被填入,所以這個ACK代表了一個新的Transaction的開始。注意,此時 transaction number (CSeq) 並沒有根據INVITE而增加--也就是說若收到的最終響應不是2XX(是3XX--6XX),則該transaction中包含ACK,若最終響應是2XX,則ACK屬於一個新的transaction(此處存疑,國外有資料將其視為一個新的transaction,但是RFC3261中的意思卻是ACK不屬於INVITE Transaction,也不建立新的Transaction,但會重新計算Transaction參數--branchID)。早期對話是UAS以一個1XX響應作為回應時建立的。這樣做的好處是在UAC可能在早期對話中發出諸如UPDATE這樣的SIP請求。
7.線上狀態(Presence)
有人譯為“呈現”,個人覺得譯為線上狀態比較貼切,這是一種激動人心的SIP應用,它使您能夠確定使用者位置,並判斷是否能夠通過電話、電子郵件/文本或視頻與其進行通訊。人員和應用都可以利用狀態資訊,從而使企業有機會將通訊整合到商務程序之中。IETF指定了許許多多的SIP擴充來支援線上狀態這個功能,我們列舉如下:
· RFC 2778: A Model for Presence and Instant Messaging
· RFC 2779: Instant Messaging/Presence Protocol Requirements
· RFC 3261 SIP: Session Initiation Protocol
· RFC 3856: A Presence Event Package for the Session Initiation Protocol
· RFC 3859: Common Profile for Presence
主要的組成有:
Presence Agent(PA):PA為SIP使用者的代理人,能夠接收和處理Presence的訊息。它也能夠回應和重新整理其它的訊息(如公開的訊息或SIP以外的任何訊息)。當一個使用者改變其狀態時,它還能給訂閱者發送通知。其可以與 SIP proxy server放在一起實現,也可以作為一個獨立實體存在。
Presence User Agent (PUA) :查詢更新PA。
8.全網看SIP
在非IMS網路中,拓撲結構如下:
在這個結構中,有三個主要的部分:
公網與業務定製者節點:這是PSTN網路以及在使用者層面的裝置。
DMZ地區:對接外網的一些網路元素,用於安全方面。
核心網:網路訊息處理的核心地區。
需要的注意是:
1.在核心網部分的媒體伺服器有時候也可以扮演UA的角色,比如你定製語音信箱這個業務,那麼這個媒體伺服器就負責播放提示音和錄音。網關在某個層面上也是扮演了UA的角色。
2.IP PBX是一種B2BUA,另外,SBC也是一種B2BUA,負責隱藏內網拓撲結構。應用伺服器也是一種B2BUA,供修改業務參數等操作使用。
9.NAT問題
所示SIP可能會出現的NAT問題:
目前商用的方法是使用Session Border Controller (SBC),也就是說在應用程式層提供NAT服務,SBC監聽SIP請求,當得到一個請求時,它不僅檢查IP頭以便路由這個包,它也查看SIP訊息內部的contract地址,並且在將其路由到下一跳之前將該地址改為一個可路由的地址,這個可路由的地址不一定是公網地址,只要下一個節點可以路由即可,如所示: