2018年11月25日 星期日

SIP Header fields

SIP 信頭欄位 [RFC3261 §20]

有些信頭欄位只在特定請求或回應有意義,不該出現的或不認識的都忽略。一些常見的信頭欄位名稱也定義了 compact (abbreviated ) 形式,當整個訊息過長造成問題時使用,例如使用 UDP 時超過 MTU。compact form 可以在任何時候使用,也可以混合使用。

完整信頭欄位見 https://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml#sip-parameters-2

信頭欄位相關於 method 和 proxy 處理的資訊如下表。
Header fieldwhereproxyACKBYECANINVOPTREGPRACK
Accept請求
-o-om*oo
2xx
---om*o-
415
-c-cc cc
Accept-Encoding請求
-o-oo oo
2xx
---om*o-
415
-c-cc cc
Accept-Language請求
-o-oo oo
2xx
---om*o-
415
-c-cc cc
Alert-Info請求ar---o- --
180ar---o- --
Allow請求
-o-oo oo
2xx
-o-mm*oo
回應
-o-oo oo
405
-m-mm mm
Authentication-Info2xx
-o-oo oo
Authorization請求
ooooo oo
Call-IDcopyrmmmmm mm
Call-Info任何ar---oo o-
Contact請求
o--mo o-
1xx
---m- --
2xx
---mo o-
3xxd-o-oo oo
485
-o-oo oo
Content-Disposition任何
oo-oo oo
Content-Encoding任何
oo-oo oo
Content-Language任何
oo-oo oo
Content-Length任何arttttt tt
Content-Type任何
**-** **
CSeq複製rmmmmm mm
Date任何aooooo oo
Error-Info300-699a-oooo oo
Expires任何
---o- o-
From複製rmmmmm mm
In-Reply-To請求
---o- --
Max-Forwards請求ammmmmm mm
Min-Expires423
----- m-
MIME-Version任何
oo-oo oo
Organization任何ar---oo o-
Priority請求ar ---o - --
Proxy-Authenticate407ar -m-m m mm
401ar -ooo o oo
Proxy-Authorization請求dr oo-o o oo
Proxy-Require請求ar -o-o o oo
Record-Route請求ar oooo o -o
2xx,18xmr -ooo o -o
Reply-To任何
---o - --
Require任何ar -c-c c cc
Retry-After404,413,480,486
500,503
600,603

-ooo o oo
Route請求adrcccc c cc
Server回應
-ooo o oo
Subject請求
---o - --
Supported請求
-oom*o oo
2xx
-oom*m*oo
Timestamp任何
oooo o oo
To複製(1)r mmmm m mm
Unsupported420
-m-m m mm
User-Agent任何
oooo o oo
Via請求amrmmmm m mm
回應,複製dr mmmm m mm
Warning回應
-ooo o oo
WWW-Authenticate401ar -m-m m mm
407ar -o-o o oo
  • where 欄表示用在請求、回應、特定回應、或是任何請求和回應。複製是指由請求複製到回應,(1) 含可能的 tag 一起複製。
  • proxy 欄表示在 proxy 可進行的動作:
    • a (add):如沒有可新增或 concatenate
    • m (modify):可修改。
    • d (delete):可移除。
    • r (read):必須可讀,所以不能加密。
  • 各個 method 欄說明是否要有:
    • c (conditional):視訊息內容需要。
    • m (mandatory):必要,且接收端必須了解。
    • m*:應該要有,但接收端沒收到時要能處理。
    • o (optional):選擇性的。可有可無,接收端可忽略,例外是 RFC 3261 §20.32 的 Require。
    • t:應該要有,但接收端沒收到時要能處理。如果 transport 用 stream-based 協定 (例如 TCP),則是必要的。
    • *:有訊息 body 時必要。見 RFC 3261 §20.14、§20.15 和 §7.4。
    • -:不能有,接收端遇到的話忽略。
UA 忽略不認識的 extension header parameters。

如果 Contact、From、和 To 包含的 URI 有「,」、「?」、或「;」,必須 用 < and > 包起來。沒包在內的「;」是分割出 header 參數,不是 URI 參數。

Accept

指定回應內容可接受的媒體類型,預設是「application/sdp」,空的 Accept 欄位值表示不接受任何格式,其它語法和語意依循 HTTP Accept

譬喻:
Accept: application/sdp;level=1, application/x-private, text/html

Accept-Encoding

類似 Accept,但限制回應內容可接受的編碼,一般是指壓縮方式。語意跟 HTTP Accept-Encoding 相同。

空的 Accept-Encoding 相當於「Accept-Encoding: identity」,也就是沒有編碼。
沒有 Accept-Encoding 欄位預設 identity。

註:在 HTTP,沒有 Accept-Encoding 欄位表示任何編碼都可以,但偏好 identity。

譬喻:
Accept-Encoding: gzip

Accept-Language

用在請求表示回應訊息內容的 reason phrases、session descriptions、或 status responses 的偏好語言,如果沒有則假設接受任何語言。

依循 HTTP Accept-Language 語法,包括 "q" 參數 (quality) 的偏好順序。

譬喻:
Accept-Language: da, en-gb;q=0.8, en;q=0.7

Alert-Info

在 INVITE 請求,提供不同的鈴聲給 UAS。在 180 (Ringing),提供不同的回鈴音給 UAC。典型用途是 proxy 用來提供不同聲音識別用。

Call-Info 一樣存在安全風險,被放入惡意音訊。應該提供使用者可關閉此功能。

譬喻:
Alert-Info: <http://www.example.com/sounds/moo.wav>

Allow

告知對方所有支援的 Method 列表。沒有 Allow 代表沒講支援哪些 Method,不是不支援任何 Method。

在 method OPTIONS 以外的回應提供 Allow 欄位,減少需要的訊息數目 (???)。

例如:
Allow: INVITE, ACK, OPTIONS, CANCEL, BYE

Authentication-Info

提供跟 HTTP Digest 的相互認證,UAS 可以在成功認證請求的 2xx 回應放這個 header,使用基於 Authorization 的 digest。

語法和語意遵循 RFC 2617

譬喻:
Authentication-Info: nextnonce="47364c23432d2e131a5fb210812c"

Authorization

UA 的認證憑證。RFC 3261 Section 22.2 概述 Authorization 的使用,Section 22.4 說明和 HTTP 認證一起使用時的語法和語意。

Authorization (和 Proxy-Authorization) 多個信頭欄位值不能合併成逗號分隔的列表,要分成多個信頭欄位行。

下面列子,Digest 參數沒用引號刮起來。

Authorization: Digest username="Alice", realm="atlanta.com",
  nonce="84a4cc6f3082121f32b42a2187831a9e",
  response="7587245234b3434cc3412213e5f113a5"

Call-ID (i)

Call 的唯一識別碼,所有 SIP 訊息都需要,關聯的 SIP 訊息都會有相同的值。
  • 一個 UA 註冊應該都使用相同的 Call-ID。
  • dialog 內所有 SIP 訊息的 Call-ID 都相同。Call-ID 加上 From tag 及 To tag 形成一個 peer-to-peer 的 SIP 關係,稱為一個 dialog。一個 Call 可能有多個 dialog。
  • 其它可能的特殊 Method 行為。
Call-ID 用字串比對是否符合,需減少無意的碰撞可能性。 
建議產生方式:由隨機字串加上 UAC 的主機名或 IP 位址組合而成。
使用加密的亂數識別碼 (RFC 1750)
https://tools.ietf.org/html/rfc1750
https://tools.ietf.org/html/rfc4086
實作可使用 "localid@host" 的 form. 
使用加密亂數提供一些保護 against session hijacking (為什麼???)。

一個多媒體會議可能需要多個不同 Call-ID 的呼叫。

譬喻:
Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@biloxi.com
i:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@192.0.2.4

Call-Info

提供發話者 (請求) 或受話者 (回應) 額外資訊的 URI,在其 "purpose" 參數說明目的:
  • "icon" 表示適合顯示為 icon 的影像。
  • "info" 是用戶一般描述,例如經由網頁。
  • "card" 提供 vCardLDIF 等格式的名片。
使用 Call-Info 存在安全風險,而被放入惡意訊息,可能是 peer UA,也可能是中間的 proxy。建議只有在放 Call-ID 的設備可以驗證真偽,並且是可信任的,才顯示資訊。

譬喻:
Call-Info: <http://wwww.example.com/alice/photo.jpg> ;purpose=icon,
   <http://www.example.com/alice/> ;purpose=info

Contact (m)

後續請求的接洽窗口 URI,其意義依據所在的請求或回應。可以包含顯示名稱、URI 參數、header 參數。如果有顯示名稱、或 URI 參數、或者 URI 含有「,」「;」「?」時,URI 和 URI 參數要用「<」和「>」包起來。沒包起來的參數都視為 header 參數。顯示名稱可以是 token,要較大的字元集的話用一個 quoted string。這些規則也應用在 To 和 From。

URI 通常有 username,位於某個 FQDN 或者沒註冊的 domain names 則用 IP 位址。

Contact 和 HTTP 的 Location 有類似的角色,然而 HTTP 只允許一個 unquoted 位址。

Contact 參數 "q" 和 "expires" 只用在 REGISTER 請求和回應,或者 3xx 回應。

格式

STAR / (contact-param *(COMMA contact-param))
contact-param  = (name-addr / addr-spec) *(SEMI contact-params)
contact-params = "q" EQUAL qvalue / "expires" EQUAL 1*DIGIT / generic-param
qvalue         =  ( "0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] )
譬喻:
Contact: "Mr. Watson" <sip:watson@worcester.bell-telephone.com>
   ;q=0.7; expires=3600,
   "Mr. Watson" <mailto:watson@bell-telephone.com> ;q=0.1
m: <sips:bob@192.0.2.4>;expires=60
  • UAC 建立 dialog 的請求 (在 RFC 3261 只有 INVITE),必須提供只有一個 URI 的 Contact,無論後續請求在不在 dialog 內都可以作為接受請求使用。
  • 如果 Request-URI 或 top Route 含有一個 SIPS URI,Contact 也必須是 SIPS URI。
  • REGISTER
  • Contact alias
  • 只有 * 允許 comma-separated list
註:m 意思 moved。
比較:Via

Content-Disposition

訊息體或其中 multipart 的部署,擴展 RFC 2183 的 MIME Content-Type

Content-Disposition 在 RFC 3261 新增,並在 IANA 註冊了 4 種新 disposition-types:
  • alert:alert 使用者的客製化鈴聲。
  • icon:顯示給使用者的 icon 影像。
  • render:顯示給使用者。
  • session :作為通話媒體的 session 描述,如 SDP
為了向前相容,如果沒 Content-Disposition, Content-Type 是 application/sdp 時假設為 "session",其它為 "render"。

如果收到不了解的 Content-Type 或 Content-Disposition,參數 handling 說明 UAS 應
該如何反應。 有定義的值有 "optional" 和 "required",預設是 "required"。handling 參數說明在 RFC 3204。

譬喻:
Content-Disposition: session

Content-Encoding (e)

訊息體的編碼,需要解壓縮或解碼才能得到 Content-Type 所參照的 media-type 時才需要,可依序列出多個施加的編碼。

Content-Encoding 欄位值不分大小寫,登記在 IANA。
https://tools.ietf.org/html/rfc2616#section-3.5 定義的語法。

Client 可對請求的訊息體編碼。
Server 可用列在請求 Accept-Encoding 的編碼,對回應的訊息體編碼。

譬喻:
Content-Encoding: gzip
e: tar

Content-Language

訊息體的語言,見 https://tools.ietf.org/html/rfc2616#section-14.12

譬喻:
Content-Language: fr

Content-Length (l)

訊息體的長度。十進位數字表示位元組數目,不含分隔 body 的 CRLF,0 以上的 值都是 valid。如果使用 stream-based transport 協定 (例如 TCP) 是必要的。沒 body 時,Content-Length 是 0。

能夠省略 Content-Length 簡化建立動態產生回應的像 cgi scripts。

譬喻:
Content-Length: 349
l: 173

Content-Type (c)

訊息體媒體類型,有 message-body 時是必要的。

譬喻:
Content-Type: application/sdp
c: text/html; charset=ISO-8859-4

CSeq

Command Sequence,每個 SIP 訊息都要有,包含一個序號及一個 Method 名稱,譬喻:
CSeq: 314159 INVITE
序號是某個 UAC 在同一個 Call-ID 下 Command 的順序,大致來講就是 Transaction 的順序,一開始是比 231 小的亂數,後續每次發出仝款 Call-ID 的新請求時,序號就加 1,讓 UAS 辨別是新的 Transaction 還是重傳。
  • 例外是 ACK 和 CANCEL,他們算是 INVITE 的延伸,沿用 INVITE 的序號。PRACK 序號會加 1。
  • 一個 UA 的 REGISTER 原則上開機後都使用仝款 Call-ID,CSeq 序號是註冊請求的順序。

Date

請求或回應首次送時的 GMT 日期和時間。不同於 HTTP/1.1,SIP 只支援最新的 RFC 1123 格式的日期,但如同 HTTP/1.1,SIP 限制時區為 "GMT"。RFC 1123 Date 有分大小寫。

Date 可讓沒 battery-backed clock 的簡易終端系統獲得目前時間。

譬喻:
      Date: Sat, 13 Nov 2010 23:29:00 GMT

Expires

訊息或內容從接收到請求開始的過期時間,值是 0 到 (2**32)-1 之間的秒數,精確的意思
視 Method 而定。

INVITE 的過期不影響邀請成功後實際 session 可使用的時間。session 可使用的時間限制
可表達在 Session 描述協定裡。

Error-Info

提供關於錯誤狀態回應的額外資訊。

UAC 用戶界面可能從有彈出式視窗和聲音的 PC softclients,到透過 gateway 連接、只有聲音的「黑」話機或端點。與其強迫 server 選擇在 Reason-Phrase 傳送細節還是播放錄音,Error-Info 允許兩者都送,由 UAC 選擇用哪種呈現給發話者。

UAC 可視 Error-Info 的 SIP 或 SIPS URI 如同 redirect 的 Contact 產生新 INVITE 得到錄音,非 SIP URI 可呈現給用戶。
譬喻:
  SIP/2.0 404 The number you have dialed is not in service
  Error-Info: <sip:not-in-service-recording@atlanta.com>

From (f)

請求的發出端。可能跟請求建立 dialog 的發出端不同。和 Contact 有相同規則的顯示名稱、URI、URI 參數、和信頭參數。 

選擇性的顯示名稱用來顯示在人機界面,要隱藏的話用「Anonymous」。

格式是 name-addr 或 addr-spec 加上 tag 參數,和其它參數

( name-addr / addr-spec ) SEMI "tag" EQUAL token *( SEMI generic-param )

addr-spec 是 name-addr 的簡化,不能有 display-name、「,」、「?」、「;」。

兩個 From 相等:URI 且參數 match。擴充參數一個沒有則忽略。display name 和有無 angle bracket 不影響是否相等。

譬喻:
From: "A. G. Bell" <sip:agb@bell-telephone.com> ;tag=a48s
From: sip:+12125551212@server.phone2net.com;tag=887s
f: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8

Organization

送出請求或回應的 SIP 元件所屬組織名稱。Client 可用來過濾呼叫。

譬喻:
Organization: Boxes by Bob

Record-Route

格式
rec-route *(COMMA rec-route)
rec-route = name-addr *( SEMI generic-param )

Reply-To

格式
( name-addr / addr-spec ) *( SEMI generic-param )

Route

格式
route-param *(COMMA route-param)
route-param = name-addr *( SEMI generic-param )

To (t)

格式
( name-addr / addr-spec ) *( SEMI to-param )
to-param  =  "tag" EQUAL token / generic-param

Via (v)

一開始的 UAC 和後續途經的每個 proxy 都會加一個 Via 放 transport 及位址,依序作為回應的路徑。

格式 sent-protocol host[:port];branch=branch[;參數...]

  • sent-protocol 格式是「SIP/2.0/transport」,transport 可以是 UDPTCPTLSSCTP 等。
  • host 可以是主機名稱或網路位址,可以加上 port number。(沒用途?)
  • 參數 branch:
    • 意思是分支。在 RFC3261 以「z9hG4bK」開頭,是必要的。值對某個 UAC 而言是時空上唯一,用來快速識別 Transaction,但在 CANCEL 和 INVITE 失敗的 ACK 是沿用原始請求的 branch。
    • 在 RFC2543,forking proxy 插入 branch 用來區分不同分支,同一個 call 在不同 proxy 可能用相同的 branch 值,沒有唯一的特性,不適合作為 Transaction ID。某種程度上不會產生「z9hG4bK」開頭的值。
    • Proxy 也用來偵測 loop。
  • 參數 sent-by:Client Transport 紀錄送出的位址「host:port」,host 建議 FQDN。port 可省略,預設值依據傳輸協定,UDP/TCP/SCTP 是 5060、TLS 是 5061。在 用來送回應。
    • 收到請求的 Via 中有 sent-by 且 branch 符合自己送的,
  • 參數 received: Server Transport 收到請求檢查頂頭 Via 的 sent-by,
    如果是網域主機名稱,或不同於封包的來源 IP 位址時,紀錄封包的來源位址,助於之後 server transport 送回應。
  • 參數 maddr:Client Transport 紀錄
  • 參數 ttl:Client Transport 紀錄
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
比較:Contact

沒有留言:

張貼留言

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...