8.1.1.10 Additional Message Components
在一個新的請求創(chuàng)建以后,前面提到的那些頭域已經(jīng)被構(gòu)建。添加任何額外的可選頭域,需要指定具體的method。
SIP請求可以包含一個 MIME解碼的消息體。無論在請求中包含什么樣的消息體,某些頭域必須進(jìn)行規(guī)范化處理,進(jìn)行內(nèi)容中的字符整合。更多關(guān)于這些頭域的說明,參考章節(jié) 20.11 到 20.15。
8.1.2 Sending the Request
請求的目的地是通過計算獲得的。除非,在發(fā)送請求的路徑存在一個邏輯策略強(qiáng)制操作,否則請求目的地必須是通過DNS處理流程來處理,具體處理描述參考 [4]。如果在route set的第一個要素表示是嚴(yán)格路由的話(導(dǎo)致重構(gòu)請求,具體描述在Section 12.2.1.1), 這個處理流程也必須使用在請求的Request-URI中。否則,這個流程使用在請求中的第一個Route頭中(如果存在的話)或如果當(dāng)前沒有Route的時候,使用在請求的Request-URI。這些流程產(chǎn)生了按序的設(shè)置組,包括了地址,端口和參數(shù)方式。在處理流程中,URL作為輸入數(shù)據(jù),他們的處理流程不依賴于URL本身,如果Request-URI設(shè)置了一個SIPS的源,UAC必須遵從處理流程 [4],輸入的URL是一個SIPS URI。
本地策略可以設(shè)定一系列可選的目的地地址。如果Request-URI包含一個SIPS URI,任何可選目的地地址必須支持TLS連接。除此之外,如果請求中沒有包含Route頭的話,對可選目的地沒有任何限定設(shè)置。對于已存在的route set來說,通過這樣的方式,它可以提供一個簡單可選 方式來設(shè)定一個outbound proxy 代理。但是,不推薦使用那種方式來設(shè)置一個outbound proxy;應(yīng)該通過一個單URL使用一個已存在的route set替代設(shè)置方式。 如果一個請求中包含一個Route頭的話,這個請求應(yīng)該被發(fā)送到最頂部的Route地址,但是這個請求也可以被發(fā)送到任何服務(wù)器,只要UA認(rèn)可其身份,其身份設(shè)置是通過Route和Request-URI 策略設(shè)定的。具體的策略設(shè)定在此規(guī)范中(相反的規(guī)范設(shè)置RFC 2543)。尤其是一個UAC配置了outbound proxy,它應(yīng)該嘗試發(fā)送請求到一個地址,這個地址應(yīng)該是第一個Route頭域地址 ,而不是調(diào)整發(fā)送策略,這個策略發(fā)送所有消息到這個outbound proxy。
這樣做的目的可以確保outbound proxies不添加Record-Route頭域值,這些頭值將會被丟出后續(xù)的請求路徑。它允許不能解析第一個Route URI的終端對outbound proxy代表執(zhí)行任務(wù)。
UAC應(yīng)該遵從對stateful要素定義的處理流程,這個流程在[4]有具體的定義,UAC應(yīng)該一直嘗試每個地址直到連接到一個服務(wù)器地址。 每個嘗試連接都構(gòu)成一個新的事務(wù),并且因此每個攜帶最頂部Via頭值的傳輸都會有一個新的branch參數(shù)值。進(jìn)一步說,在Via頭中的傳輸值被設(shè)置為傳輸方式設(shè)定的值。無論這個值怎么設(shè)置,這個值是傳輸方式針對目的地服務(wù)器決定的。
8.1.3 Processing Responses
響應(yīng)消息首先是通過傳輸層進(jìn)行處理,然后在傳輸?shù)绞聞?wù)層。事務(wù)層執(zhí)行自己的處理流程,然后再傳遞回TU處理。在TU中的大部分響應(yīng)處理流程是和具體的method相關(guān)的。但是,一些基本的處理方式不依賴于methods本身。
8.1.3.1 Transaction Layer Errors
在一些情況下,一些由事務(wù)層返回的響應(yīng)消息不是SIP消息,是一個事務(wù)層錯誤。當(dāng)從事務(wù)層收到一個超時錯誤時,它必須被作為一個408錯誤。如果由傳輸層報告了一個致命的傳輸錯誤(通常情況下,是因為一個UDP中的致命ICMP錯誤或TCP的連接錯誤),這種狀態(tài)必須被視為一個503錯誤代碼(服務(wù)不可用)。
8.1.3.2 Unrecognized Responses
UAC必須處理任何無類別等級的最終響應(yīng)消息,并且UAC也必須可以處理任何x00類別的響應(yīng)消息。例如,如果一個UAC收到一個無類別響應(yīng)代碼是431的響應(yīng)消息,此UAC可安全地認(rèn)為可能在請求中有什么錯誤發(fā)生。一個UAC必須視臨時響應(yīng)消息是不同于100響應(yīng)的,它也不會被視為183響應(yīng)消息。UAC必須能夠處理100響應(yīng)和183響應(yīng)消息。
8.1.3.3 Vias
如果在響應(yīng)消息中出現(xiàn)了一個以上的Via頭域值,此UAC應(yīng)該丟棄這個消息。
多個出現(xiàn)的Via頭域值是請求發(fā)起方置入的值,這些消息是錯誤設(shè)置或者配置文件損害導(dǎo)致。
8.1.3.4 Processing 3xx Responses
對于轉(zhuǎn)發(fā)協(xié)議的處理上(例如,301響應(yīng)狀態(tài)碼),客戶端應(yīng)該基于轉(zhuǎn)發(fā)請求,在Contact頭中使用URL(s)重新構(gòu)建一個或多個新的請求。這個過程類似于代理對3xx類別響應(yīng)的遞歸處理,具體的細(xì)節(jié)參考16.5和16.6章節(jié)?蛻舳藛訒r攜帶初始的目標(biāo)地址列表,其中包含完整的URL。這是初始請求的Request-URI。 如果客戶端希望基于3xx重構(gòu)新的請求,它會置入這些URLs在目標(biāo)列表中。在此規(guī)范中,對象的限制是,一個客戶端可以選擇哪個URLs可以置入到目標(biāo)組設(shè)置。當(dāng)代理遞歸發(fā)生時,客戶端處理3xx類別響應(yīng)時,它一定不能再次添加任何已給定的URL到目標(biāo)組中。如果初始的請求已經(jīng)在Request-URL中有一個SIPS URL,客戶端可以選擇遞歸到一個非-SIPS URI,但是應(yīng)該通知轉(zhuǎn)發(fā)用戶,這是一個不安全的URL。
任何新請求可以接收3xx響應(yīng),這些響應(yīng)自己包含初始的URL,這些URL作為contact?梢耘渲脙蓚地址互相轉(zhuǎn)發(fā)。在目標(biāo)地址組置入一個給定的URL,其目的是防止無限轉(zhuǎn)發(fā)環(huán)路發(fā)生。
當(dāng)目的地組設(shè)置增加時,客戶端可以以任何順序?qū)RLs生成新的請求。一般的機(jī)制是在Contact頭中設(shè)置一個"q"參數(shù)值來表示順序。對URL生成的請求可以是并行方式或連續(xù)生成方式。一種方式是通過連續(xù)方式處理遞減的q-值組,并且以并行方式處理在每個q-值組的URL。另外一種方式是按照遞減的q-值順序,僅執(zhí)行連續(xù)處理,在相同q-值的contacts之間任意選擇一個值。
如果連接在列表中的contact失敗,繼續(xù)連接列表中的下一個地址,直到列表地址連接全部失敗。如果地址連接全部失敗的話,那么這個請求就已經(jīng)失敗。
失敗結(jié)果應(yīng)該通過失敗響應(yīng)碼來檢測(響應(yīng)碼高于399);對網(wǎng)絡(luò)錯誤來說,客戶端事務(wù)層將會對事務(wù)層用戶報告?zhèn)鬏攲铀l(fā)生的錯誤。注意,一些響應(yīng)碼(詳情參見8.1.3.5)表示請求可被重新獲;重新發(fā)送到請求不應(yīng)該被認(rèn)為是失敗響應(yīng)。
當(dāng)收到針對某個特定contact地址的失敗時,客戶端應(yīng)該嘗試下一個contact地址。這樣就會導(dǎo)致針對發(fā)送的新請求創(chuàng)建一個新客戶事務(wù)。
為了在3xx響應(yīng)中基于一個contact地址創(chuàng)建一個請求,除了“method-param”和 “header”URI(參考 Section 19.1.1 章節(jié)對參數(shù)的定義)以外,UAC必須從目標(biāo)組中拷貝所有URL到Request-URI。它使用“header”參數(shù)為新請求創(chuàng)建header頭值,覆蓋和轉(zhuǎn)發(fā)請求中相關(guān)的頭域值,具體操作規(guī)范參考Section 19.1.5。
注意,在一些例子中,在contact地址中,已經(jīng)構(gòu)成通信關(guān)系的頭可以替換追加到已存在的請求的頭中,這些請求的頭是在初始轉(zhuǎn)發(fā)請求中的頭。作為一個一般規(guī)則,如果頭域可以接受以逗號隔離的域值列表,那么新的頭值可以追加到初始轉(zhuǎn)發(fā)到請求中。如果頭域不能接受支持追加多個值的話,初始轉(zhuǎn)發(fā)請求中的值可以被在contact地址中已經(jīng)構(gòu)成通信關(guān)系的頭域值覆蓋。例如,如果返回的contact地址攜帶了如下值的話:
sip:user@host?Subject=foo&Call-Info=http://www.foo.com
那么,在初始轉(zhuǎn)發(fā)請求中的Subject頭可以被覆蓋,但是這個HTTP URL很少被追加到任何已存在的Call-Info頭值中。
規(guī)范推薦UAC重用在初始轉(zhuǎn)發(fā)請求中同樣的To,F(xiàn)rom和Call-ID,但是UAC例如也可以選擇更新Call-ID支持新的請求。
最后,一旦一個新的請求生成以后,新請求使用一個新客戶端事務(wù)發(fā)送這個請求,因此,它必須在最頂部的Via頭中生成一個新的branch ID。關(guān)于這一討論,參考Section 8.1.1.7。
從其他角度所期望的,轉(zhuǎn)發(fā)響應(yīng)接收方發(fā)送到請求應(yīng)該重用初始請求的頭域和消息體。
在一些例子中,Contact頭域值可能在UAC端被臨時或永久緩沖保存,這取決于收到的狀態(tài)碼和內(nèi)部超時設(shè)置狀態(tài)。查看21.3.2 和21.3.3章節(jié)介紹。
未完繼續(xù)……
關(guān)注微信公眾號:asterisk-cn,獲得有價值的Asterisk行業(yè)分享
Asterisk freepbx,F(xiàn)reeSBC技術(shù)文檔:www.freepbx.org.cn
融合通信商業(yè)解決方案,協(xié)同解決方案首選產(chǎn)品:www.hiastar.com
Asterisk / FreePBX / FreeSBC中國合作伙伴,官方qq技術(shù)分享群(3000人):589995817