SIP協議解析與實現(c和c++使用osip) 7

處理4xx應答

某個特定的4xx應答需要特定的UA處理,而不依賴於請求的方法。

如果接收到一個401(Unauthorized)或者407(Proxy Authentication Required)應答,UAC應該按照授權處理流程(RFC3261第22.2節和22.3節)攜帶憑證再次嘗試請求。

如果接收到一個413(請求實體過長)應答(RFC3261第21.4.11節),說明該請求包含的實體長於UAS限制的實體長度。如果可能,UAC應該忽略消息體或者使用更短的實體重新嘗試請求。

如果接收到一個415(不支持的媒體類型)應答(RFC3261第21.4.13節),說明請求包含了UAS不支持的媒體類型。UAC應該僅僅使用在應答的Accept頭域列出的類型,使用的編碼在應答的Accept-Encoding頭域列出,語言在應答的Accept-Language頭域列出。

如果接收到一個416(不支持的URI模式)應答(RFC3261第21.4.14節),說明Request-URI使用了一個服務器不支持的URI模式。客戶端應該使用SIP URI模式重新嘗試。

如果接收到一個420(錯誤的擴展)應答(RFC3261第21.4.15節),說明請求在Require或Proxy-Require頭域列出了一個不被代理或者UAS支持的擴展選項。UAC應該忽略在應答的Unsupported頭域中列出的擴展並重新嘗試。

在所有上述的情況中,請求被相應的進行修改並創建新的請求。這個新的請求創建一個新的事務,其中Call-ID, To, 和From頭域與前一個請求一致,而CSeq頭域應該包含一個大於原來的新的順序號。

對於其它的4xx應答,是否嘗試重新發送新的請求依賴於請求的方法和用例。

第二節 UAS行爲

當一個對話外請求被一個UAS處理,有一系列要遵循的與請求方法無關的規則。RFC3261第12節對一個UAS如何對對話內或對話外請求進行應答做了指導。

注意,請求處理是自動進行的。如果一個請求被接受,與它相關的所有狀態必須改變爲接受。如果一個請求被拒絕,那麼與它相關的所有狀態必須改變爲拒絕。

所有的UAS必須按照本節給出的步驟處理請求(即,從驗證開始,然後檢查方法、頭域和其它所有本節提到的內容)。

方法檢查

一但一個請求被驗證(或者不需要驗證),UAS必須檢查請求的方法。如果UAS認識但不支持這個方法,他必須創建一個405應答(方法不被允許)。創建應答的方式在RFC3261第8.2.6節描述。UAS必須同事添加一個Allow頭域到405應答。Allow頭域必須列出UAS支持的方法。Allow頭域在RFC3261第20.5節介紹。

如果請求的方法被服務器支持,則繼續處理。

頭域檢查

如果UAS不能明白一個在請求中的頭域(這說明,這個頭域沒有在這個手冊或者其它擴展中定義),服務器必須忽略該頭域並繼續處理這個請求。UAS應該忽略任何處理該請求所不需要的頭域。

To頭域和Request-URI頭域

To頭域包含由From頭域標識的發送者發送的請求的原始接收者。原始接收者可能是也可能不是要處理這個請求的UAS,因爲會有呼叫轉移或者其它代理操作。當一個請求的To頭域與UAS不同時,UAS可能用任何策略來決定是否接受請求。儘管如此,UAS即使在To頭域中是不認識URI模式(例如,一個tel的URI)或者To頭域沒有標識一個此UAS認識的或有效的用戶,但是推薦接受該請求。如果UAS決定拒絕請求,它應該構造一個狀態碼是403(Forbidden)的應答,並且將該應答交給服務器的事務層去傳輸。雖然Request-URI頭域標識處理請求的UAS。如果Request-URI使用一個UAS不支持的模式,它應該使用416(Unsupported URI Scheme)應答來拒絕該請求。如果Request-URI標識一個UAS不希望接受的地址,它應該使用404(Not Found)應答。一個UA使用REGISTER方法綁定它的address-of-record到一個特定的contact地址,將能夠接收到Record-URI等於這個contact地址的請求。其它可接收到Request-URI的潛在的資源包括被UA用來建立或者刷新會話的請求或者應答的Contact頭域。

合併請求

如果一個請求的To頭域不包含tag,UAS必須檢查當前事務上的請求。如果請求的From頭域的tag標誌、Call-ID和CSeq與被該請求的事務的這些項完全匹配,但是請求與這個事務不匹配(基本的匹配規則在RFC3261第17.2.3節介紹)。UAS內核應該構造一個482(Loop Detected)應答並傳遞給服務器的事務。

一個相同的請求從不同的路徑被髮送到UAS多次,這多因爲有分支。UAS處理第一個接收到的請求併發送一個482(Loop Detected)應答來消除它們。

Require頭域

假定UAS是合適處理這個請求的元素,如果有的話,檢查Require頭域。

Require頭域被UAC用於告訴UAS關於SIP擴展的,這些擴展是UAC希望UAS爲了能夠正確地處理處理請求而支持的。它的格式在RFC3261第20.32節描述。如果UAS不認識一個在Require頭域中列出的可選標記,它將創建併發送一個狀態碼爲420(Bad Extension)的應答。這個UAS必須增加一個Unsupported頭域,並且將它在Require頭域中不認識的選項列在列出來。

注意,Require頭域和Proxy-Require頭域不能在一個SIP的CANCEL請求,或者一個對應於非2xx應答的ACK中使用。這些頭域如果出現在這些請求中,那麼必須被忽略。

一個對應於2xx應答的ACK必須只包含出現在初始請求中的Require頭域和Proxy-Require的值。

例如:

      UAC->UAS:   INVITE sip:[email protected] SIP/2.0
                  Require: 100rel

      UAS->UAC:   SIP/2.0 420 Bad Extension
                  Unsupported: 100rel

這個行爲是在所有選項都被雙方認識時,保證客戶端服務器可以無延時的交互。在選項不是全部都被雙方認識(例如上面的例子)時會使交互減慢。對於一對匹配的客戶端服務器對,相互交互非常快,因爲保存了往返協商的過程。此外,這也消除了服務器不認識客戶端擴展引起的含糊。一些特性只應用於特定的終端,例如呼叫管理域。

內容處理

如果UAS認識任何被客戶端請求的擴展,UAS要檢查消息體和消息的頭域。如果有任何消息體的類型(由Content-Type標識),語言(由Content-Language標識)或者編碼(由Content-Encoding標識)不被認識,並且這個消息體部分不是可選的(由Content-Disposition頭域標識),UAS必須使用一個415(Unsupported Media Type)應答來拒絕請求。當請求包含的消息體類型有不被UAS所認識的時候,應答必須包含一個Accept頭域,並列出所有它認識的消息體類型。如果消息體的編碼不被UAS認識,應答必須包含一個Accept-Encoding頭域列出能夠被UAS識別的所有編碼。如果請求包含的消息體的語言不能被UAS認識,應答必須包含一個Accept-Language頭域指出UAS認識的語言。除了這些檢查,消息體的處理還依賴於方法和類型。關於處理content-specific頭域的信息請參看RFC3261第7.4節和第20.11節到20.15節。

應用擴展

能夠應用擴展的UAS不能在產生應答的時候使用擴展,除非在請求的Supported頭域說明支持此擴展。如果擴展是不被支持的,那麼服務器必須只依賴標準的SIP或者客戶端支持的擴展來構造應答。在一些特殊環境下,服務器不使用擴展就不能處理請求,那麼服務器應該發送421(Extension Required)應答。這個應答說明如果不使用一個特定的擴展服務器就不能構造正確的應答。要被使用的擴展必須在421應答的Require頭域中指定。這個處理是不被推薦的,因爲這將破壞客戶端與服務器間的相互工作。

任何應用於非421應答中的擴展必須列在應答的Require頭域中。當然,服務器不能使用沒有列在請求的Supported頭域中的擴展。因此,應答中Require頭域僅僅包含在標準RFC中的擴展。

處理請求

假設通過了前面各節描述的所有的檢查,那麼UAS下面的處理將根據不同的方法而不同。RFC3261第10節講述REGISTER請求,第11節講述OPTIONS請求,第13節講述INVITE請求,第15節講述BYE請求。

創建應答

當UAS要爲一個請求構造應答時,它將按照下面各節講述的一般創建過程來做。根據特定的應答狀態碼需要的特定的行爲也是需要的,但它不在本章介紹。

發送一個臨時應答

一個主要的與方法無關的創建應答的方針是,UAS不能向一個非INVITE請求發送臨時應答。取而代之,UAS應該立即發送一個最終應答給非INVITE請求。

當創建了一個100(Trying)應答,任何在請求中出現的Timestamp頭域必須拷貝到這個100(Trying)應答中。如果構造應答有延時,UAS應該在應答的Timestamp頭域中加上這個延時。這個延時必須包含發送應答和接收請求的差值,以秒爲單位。

頭域和Tag

應答的From頭域必須等於請求的From頭域。應答的Call-ID頭域必須等於請求的Call-ID頭域。應答的CSeq頭域必須等於請求的CSeq頭域。應答的Via頭域必須等於請求的Via頭域,並且維持相同的順序。

如果請求的To頭域有tag標籤,那麼應答中的To頭域必須等於請求中的To頭域。儘管如此,如果請求中的To頭域不包含tag標籤,應答中To頭域的URI必須等於請求中To頭域的URI;此外,UAS必須嚮應答的To頭域添加tag標籤(100(Trying)應答是個例外,它可能已經有tag標籤了)。服務器用此作爲UAS正在應答的標誌,它也是對話中對話ID的組成部分。對一個請求的所有應答,包括最終應答和臨時應答(除了100(Trying)),必須使用相同的tag標籤。創建tag標籤定義在RFC3261第19.3節。

無狀態UAS行爲

一個無狀態UAS是一個不維持事務狀態的UAS。它一般對請求進行回覆,但是在送了最終應答後,它將廢棄所有在UAS保留的狀態。如果一個無狀態的UAS接收到一個重發的請求,它會重新創建應答併發送它,就像答覆一個第一次發送的請求。除非對於請求的方法來說,相同的請求總是得到相同的應答,否則UAS不能是無狀態的。這個規則使註冊服務不能是無狀態的。無狀態UAS不使用事務層;它直接從傳輸層接收請求並直接把應答發送給傳輸層。

無狀態UAS主要是處理無須驗證的請求並且對這個請求的應答是可以預期確定的。如果不需要驗證的請求被有狀態的UAS處理,那麼大量的不需要驗證的請求將創建大量的事務將減慢或者完全使UAS停止處理。這就形成了拒絕服務環境。更多信息參看RFC3261第26.1.5節。

無狀態UAS主要的行爲是:

    o 一個無狀態UAS必須不發送臨時(1xx)應答。

    o 一個無狀態UAS必須不重複傳輸應答。

    o 一個無狀態UAS必須忽略ACK請求。

    o 一個無狀態UAS必須忽略CANCEL請求。

    o 應答的To頭域tag必須被構造爲無狀態方式 - 這種方式將爲相同的請求構造相同的tag。構造tag的介紹請參看RFC3261第19.3節。

在所有其它方面,一個無狀態的UAS的行爲與有狀態的UAS相同。一個UAS能夠用有狀態和無狀態兩種模式操作每一個新的請求。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章