2021年12月11日 星期六

SIP URI

SIP 最基本的 URI scheme 是 sip:,TLS 加密用 sips:,像 email 格式,用在 SIP 請求行及批頭值等,整個會使拆著 4 個部份:

格式sip:user:password@host:port;uri-parameter?header
4 個部份
帳號主機URI 參數URI 批頭
ABNF
userinfohostporturi-parametersheaders

其中只有主機的 host 是必要的。URI 可作為 addr-spec,但有 URI 參數時,需要整個用 <> 包起來成為 name-addr,才能區別「批頭參數」。

ABNF 格式:

SIP-URI    = "sip:" [ userinfo ] hostport uri-parameters [ headers ]
SIPS-URI   = "sips:" [ userinfo ] hostport uri-parameters [ headers ]

有「@」表示在主機有帳號,「@」之前就是帳號部份,分大小寫,可用 user 或 telephone-subscriber。帳號內如果有「:」表示含有密碼 password,毋過有安全問題不建議用。

userinfo   = ( user / telephone-subscriber ) [ ":" password ] "@"

user 大多字元都可以使用,即使「,」「;」「?」也可以。「@」區別帳號不能使用,「:」表示有密碼也不行,可用「% 跳脫」。

user            =  1*( unreserved / escaped / user-unreserved )
user-unreserved =  "&" / "=" / "+" / "$" / "," / ";" / "?" / "/"

telephone-subscriber 是電話號碼,由 tel URI 來,可視為 user 的特例,可用 URI 參數 user=phone 明確表示用電話號碼。電話號碼本身可能包括「;」開頭的參數,這是出現在「@」之前,和主機之後的 URI 參數是不同的。電話號碼參數在 tel URI 是不分大小寫的,且不同順序是相同的。轉遮 SIP/SIPS URI 愛換遮小寫,isub 排頭前,賰的照字母順序排,這樣比較才會一致。例如:

tel:+358-555-1234567;tsp=a.b;phone-context=5

變成

sip:+358-555-1234567;phone-context=5;tsp=a.b@foo.com;user=phone

密碼也大多字元都可以使用,只比 user 少了「;」「?」和「/」。(為什麼需要少這 3 個?)

password        =  *( unreserved / escaped /
                   "&" / "=" / "+" / "$" / "," )

主機可以是網域名稱或 IP 網址,如果有「:」表示含有 port。

hostport       = host [ ":" port ]
host           = hostname / IPv4address / IPv6reference
hostname       = *( domainlabel "." ) toplabel [ "." ]
domainlabel    = alphanum / alphanum *( alphanum / "-" ) alphanum
toplabel       = ALPHA / ALPHA *( alphanum / "-" ) alphanum
IPv4address    = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
IPv6reference  = "[" IPv6address "]"
IPv6address    = hexpart [ ":" IPv4address ]
hexpart        = hexseq / hexseq "::" [ hexseq ] / "::" [ hexseq ]
hexseq         = hex4 *( ":" hex4)
hex4           = 1*4HEXDIG
port           = 1*DIGIT

URI 參數可有多個,每個以「;」開始,格式是 名稱=值,名稱不能重複,有 transport、maddr、ttl、user、method、lr 等。和批頭參數是不同的東西。整個 URI 可作為 addr-spec,可用到「,」、「?」、和「;」,但為了跟信頭參數的「;」區別,整個 URI 需要用 <> 包起來成為 name-addr

uri-parameters = *( ";" uri-parameter)
uri-parameter     = transport-param / user-param / method-param
                    / ttl-param / maddr-param / lr-param / other-param
transport-param   = "transport="
                    ( "udp" / "tcp" / "sctp" / "tls"
                    / other-transport)
other-transport   = token
user-param        = "user=" ( "phone" / "ip" / other-user)
other-user        = token
method-param      = "method=" Method
ttl-param         = "ttl=" ttl
maddr-param       = "maddr=" host
lr-param          = "lr"
other-param       = pname [ "=" pvalue ]
pname             = 1*paramchar
pvalue            = 1*paramchar
paramchar         = param-unreserved / unreserved / escaped
param-unreserved  = "[" / "]" / "/" / ":" / "&" / "+" / "$"

說明

  • user=phone:特別表示帳號是電話號碼。

「?」表示有 header,每個用「&」格開。

headers        = "?" header *( "&" header )
header          =  hname "=" hvalue
hname           =  1*( hnv-unreserved / unreserved / escaped )
hvalue          =  *( hnv-unreserved / unreserved / escaped )
hnv-unreserved  =  "[" / "]" / "/" / "?" / ":" / "+" / "$"

其它 scheme URI,可以是網路路徑、絕對路徑等。

absoluteURI    =  scheme ":" ( hier-part / opaque-part )
scheme         =  ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
hier-part      =  ( net-path / abs-path ) [ "?" query ]
net-path       =  "//" authority [ abs-path ]
authority      =  srvr / reg-name
srvr           =  [ [ userinfo "@" ] hostport ]
reg-name       =  1*( unreserved / escaped / "$" / ","
                  / ";" / ":" / "@" / "&" / "=" / "+" )
query          =  *uric
abs-path       =  "/" path-segments
opaque-part    =  uric-no-slash *uric
uric           =  reserved / unreserved / escaped
uric-no-slash  =  unreserved / escaped / ";" / "?" / ":" / "@"
                  / "&" / "=" / "+" / "$" / ","
path-segments  =  segment *( "/" segment )
segment        =  *pchar *( ";" *pchar )
pchar          =  unreserved / escaped /
                  ":" / "@" / "&" / "=" / "+" / "$" / ","

參考

  1. RFC3261 §19.1
  • SIP/SIPS URL follow RFC3986 guideline

沒有留言:

張貼留言

SIP header Via

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