用户代理行为
用戶代理分兩種:UAC和UAS。區分的依據在于請求方和響應方。
當一個請求發生之時,即使用某個方法,根據請求方和響應方產生了UAC和UAS,從而可以建立起事務(Transaction)來。所以UAC和UAS是對某個事務而言,或某個請求而言。
UAC和UAS的處理由兩個特點。第一,基于請求或者應答是否在一個對話里,第二,基于請求的方法(method)。
?
UAC特性
1 產生一個請求
一個合法的SIP請求必須至少包含如下頭域:TO,FROM,Cseq,Call-ID,Max-Forwards,Via;這些字段在所有SIP請求中必須包含。這6個字段是SIP消息的基本組成部分,他們提供了用于路由用的核心信息,包含了消息的地址,響應的路由,消息傳遞次數,詳細的順序,事務的唯一標志。
1.1 Request-URI
最開始的Request-URI頭域應該是TO頭域的的值。
1.2 Call-ID
Call-ID是一個在一系列消息中,區分一組消息的唯一標志。在對話中的任一UA的所有請求和所有應答的Call-ID必須一致。在UA的每次注冊中,都應該是一樣的。在會話外的時候,UAC發起一個新的請求,這個Call-ID頭域必須由UAC產生一個全局(在時間和空間上都是)唯一的Call-ID,除非是請求頭的方法(method)指明了別的產生方式。所有的SIPUA都必須保證自己產生的Call-ID不會和其他UA產生的Call-ID重復。
我們強烈建議用密碼亂序隨機串(RFC1750)來產生Call-ID。實現中,可以用類似”localid@host”這樣的格式產生。Call-ID是大小寫敏感的,并且通過簡單字節/字節的來進行比較。
1.3 Cseq
Cseq頭域是用來區分和做位事務的順序使用的。他由一個方法(method)和一系列的順序號碼組成。方法(method)必須和請求的方法一致。對于對話外的非REGISTER請求來說,順序號碼可以是任意的。這個順序號碼必須可以由32位的無符號整數表達,必須小于2^31。
1.4 Via
Via頭域是標志了用于事務傳輸的傳輸設備,并且也標志了應答送回的地址。只有當需要通過選擇傳輸設備到達下一個節點(hop)的時候,才需要在頭域中包含Via域。。當UAC創建一個請求,它必須在頭域中添加一個Via域。protocol名字和protocol版本必須分別是SIP和2.0。Via頭域必須包含一個分支(branch)參數。這個參數用于區分請求創建的事務。這個參數客戶端和服務器都會使用。除了CANCEL和給非2xx應答的ACK以外,branch參數對UA發出的所有的請求來說,在時間和空間上必須唯一。CANCEL請求的branch參數必須和他所取消的請求的branch參數一致。給非2xxx(non-2xx)應答的ACK必須和其對應的的INVITE請求有相同的branchID。
1.5 Contact
Contact頭域提供了訪問后續請求的特定UA實例的聯系方法.在任何會建立一個對話的請求中,Contact頭域必須提供和包含一個SIP或者SIPSURI。在這個規范中定義的方法中,只有INVITE請求會建立一個會話。
1.6 Supported和Require
如果UAC支持服務端響應請求的SIP擴展,UAC應該在請求的時候包含一個Supported頭域說明optionstags描述那些SIP擴展。optiontags中出現的擴展說明必須是遵循RFCs的標準擴展說明。
如果UAC要求UAS能夠支持擴展,以便UAS能夠處理UAC的特定請求,那么它必須在請求頭中增加一個Require頭域來說明處理本特定請求需要什么樣的一個擴展optiontags。如果UAC需要請求經過的所有proxy都支持它發出的某個請求的擴展部分,它必須增加一個Proxy-Require頭域來說明需要Proxy支持何種optiontag擴展。
?
2 發送請求
于是,我們就開始查找請求發送的目標。除非有其他的特定說明,目標必須是通過DNS來查找的,處理過程由RFC3263來定義。。如果路由表(routeset)中的第一個元素表明這是一個嚴格路由,那么這些過程必須在請求的Request-URI中說明。否則,這些過程在請求中被應用于第一個Route頭域中(如果存在),或者在請求的Request-URI中(如果Route頭域不存在)。這樣一些過程產生了一系列的地址,端口,和用于傳輸的傳輸器。
本地策略可以指定一套額外的目的地用于發送。例如簡單的外發(outbound)proxy的事前路由的選擇。如果請求包含了Route頭域,請求應該發送到Route頭域最上邊的一個位置,但是請求也可能被發給由本文檔約定的Route或者Request-URI所指定的服務器(同RFC2543定義的相反)。特別的,一個配置了外發proxy的UAC應該首先嘗試把請求發送給由第一個Route頭域值指定的位置,而不是采用把所有消息都發給外發proxy的策略。這就保證了外發的proxy通過不增加Record-Route頭域而不參與后續請求的路徑。這個也允許讓不能分析第一個RouteURI的終端,把請求交給外發proxy來發送。
?
3 處理應答
3.1 transaction層的錯誤
在某些情況下,從transaction層返回的應答不一定是一個SIP消息,而是一個transaction層的錯誤。當從transaction層收到一個timeout錯誤的時候,必須將這個timeout錯誤當作是收到了一個狀態碼是408(請求timeout)的應答。如果transport層報告了一個嚴重錯誤(通常取決于UDP傳輸中的嚴重的ICMP錯誤,或者是TCP連接中的錯誤),必須把這個錯誤當作是狀態碼503(服務未提供)的錯誤。
3.2 未知的應答
UAC必須把自己不認識的所有最終應答當作是x00的那類應答,當然UAC也必須能夠處理所有的類別應答的x00的應答。并且,UAC必須能夠處理所有的不認識的非終結應答響應當作是183(sessionprogress)。一個UAC必須能夠處理100和183應答。
3.3 Vias
如果在應答中,有不只一個Via頭域值存在,那么UAC應該丟棄這個消息。包含超過一個Via頭域值的消息是因為被錯誤的路由或者消息被破壞。
3.4 處理3xx應答
由于接收到一個重定向的應答(比如,狀態碼是301的應答),客戶端應該用在Contact頭域中的URI(s)來組織一個或者多個基于重定向以后的新請求。客戶發起請求的時候只有一個目標URI,就是原始請求中的Request-URI。如果客戶端想在這個請求基礎上重構一個基于3xx類別應答的新請求,那么就需要把這個需要嘗試的URIs放到目標集合中去。
3.5 處理4xx應答
某個4xx應答碼要求特定的UA處理,和請求的方法無關。
UAS特性
UAS在處理對話外的請求的時候,有一組規則需要遵守,這組規則與方法無關。
UASs應當遵循本節所規定的順序來處理請求。(就是說,首先是身份認證,然后是方法判定,然后是頭域,然后按照本文規定處理剩余部分)
1 方法判定(略)
2包頭判斷
如果UAS不認識請求中的包頭域(就是說,包頭域不在本規范中定義或者不在任何擴展中定義),那么服務器必須忽略掉這個包頭域并且繼續處理本請求。UAS必須忽略任何處理本請求所不需要的長得畸形的包頭域。
2.2 合并的請求
如果請求的To頭域中沒有tag標志,UAS的處理核心必須檢查基于正在進行的transactions上的請求。如果接收到的請求和正在處理的transaction的請求中的頭域Fromtag,Call-ID,CSeq精確匹配了,但是請求并不匹配那個事務,UAS核心應該產生一個482(檢測到循環)應答并且給服務器的transaction層發送。
2.4 應用擴展
如果UAS希望應用一部分SIP擴展,那么不可以在產生應答的時候做SIP擴展,除非這個擴展是在請求中的Supported頭域中指明了的。如果這個擴展并沒有在本請求的Supported頭域中指明,那么服務端必須基于基準SIP給出應答,或者給出已知客戶端支持的擴展應答。在極少數情況下,如果服務端不用擴展就無法處理請求,那么服務端應該發送421(需要擴展支持)應答。這個應答說明如果沒有適當的擴展就無法給出正確的應答。在應答中需要的擴展必須在應答中的Require頭域中指出。我們并不推薦這個方法,因為它會降低協同工作的能力。
2.6 產生應答
2.6.1 發送一個臨時響應
很多情況下,在與方法無關的應答規范中,在非INVITE請求的情況下,我們都要求UAS不應該發送臨時應答給請求者。在這種情況下,UAS應該盡快發送一個終結應答給非INVITE請求。
2.6.2 包頭和Tags
應答中的Via頭域必須和請求中的Via頭域相等,而且順序也必須相等。如果請求中包含了Totag,那么應答中的To頭域必須和請求中的To頭域相等。如果請求中的To頭域并不包含Tag,那么應答中的To頭域的URI必須和請求中的TO頭域的URI相等;此外,UAS還必須增加一個Tag到To頭域上(100(trying)應答是一個例外,在100中可能已經存在了一個tag)。這就提供了一個UAS正在應答的標志,也許就是對話ID的一部分。對同一個請求來說,它的應答必須有相同的tag標志,包括終結應答和臨時應答(同樣100(trying)除外)。
2.7 無狀態UAS行為
無狀態UAS就是說UAS本身不保持事務的狀態。
無狀態的UAS有下列重要的特性:
o 無狀態的UAS不許發送臨時應答(1xx)
o 無狀態的UAS必須忽略ACK請求
o 無狀態的UAS必須忽略CANCEL請求
3 發送應答
服務端事務使用最上邊的Via頭域值來決定把應答發送到哪里。
?
注:
所有的SIP實現必須支持SIP URI的實現。任何支持TLS的實現必須支持SIPSURI的實現。
總結
- 上一篇: “天价”配件喜加一:苹果推出340元多彩
- 下一篇: 首款200W快充骁龙8+旗舰!iQOO