從《
kamailio 簡易命令檔》可理解到 kamailio 的設定檔就是如何處理
SIP 封包的命令檔,kamailio 讀取後會編譯成內部的 SIP 處理邏輯。撰寫命令檔需要對
SIP 協定有一些基本的了解。命令檔的語法類似 C 語言,使用 kamailio 內建及外掛模組的函數及變數。一般 kamailio 命令檔包括核心參數設定、模組載入、模組參數設定、以及 SIP 協定處理區塊這些部份,如果命令檔有修改,kamailio 需要重啟。
前置處理指引 (Preprocessor Directives)
類似 C 語言,kamailio 也有類似的前置處理。
#!include_file "path_to_file"
#!import_file "path_to_file"
- 跟 include_file 一樣,但檔案不存在沒關係
#!define, #!trydef, #!redefine
#!ifdef, #!ifndef, #!else, #!endif
#!subst "/regexp/subst/[flags]"
- 字串內的取代 (define 只能取代 ID -- alphanumeric tokens not enclosed in quotes)
- flags:'i' - ignore case; 'g' - global replacement
#!substdef "/ID/subst/":subst 加上 define ID subst
核心參數設定、模組載入、及模組參數設定
命令檔通常都有一些核心參數 (
core parameter) 設定,包含要載入哪些模組、以及模組的參數設定,也都是透過核心參數設定達成。有些核心參數會設定成全域變數,在 kamailio 或模組內部可以使用。
check_via (或指令參數 -K)
onsend_route_reply
- reply 也執行 onsend_route 區塊,預設 reply 是不執行 onsend_route
pv_buffer_size,
pv_buffer_slots
- 設定動態字串的 buffer。字串用到虛擬變數需要動態產生。
loadpath (或 mpath), loadmodule "modulepath", modparam:
- 模組相關,分別用來設定模組路徑、載入模組、及設定模組參數。有些模組有相依性而有載入先後的差別。
mhomed
server_header,server_signature
- 預設 kamailio 本身產生的 SIP reply 會含 header「Server: Kamailio (<version> (<arch>/<os>))」,server_header 可更改內容,server_signature=no 關閉不產生
其它還有 advertised_address advertised_port alias async_workers auto_aliases auto_bind_ipv6 children chroot
corelog
debug
description
disable_core_dump
disable_tls
enable_tls
exit_timeout
flags
force_rport
fork
fork_delay
group
http_reply_parse
latency_limit_action
latency_limit_db
latency_log
listen log_facility
log_name
log_prefix
log_stderror
maxbuffer
sql_buffer_size
max_recursive_level
max_while_loops
mcast_loopback
mcast_ttl
memdbg
memlog
mem_join
mem_safety
mem_summary mlock_pages
modinit_delay open_files_limit
phone2tel
pmtu_discovery
port
reply_to_via
server_id
shm_force_alloc
sip_warning (noisy feedback)
socket_workers
statistics
tos
udp_mtu
udp_mtu_try_proto
user
user_agent_header
workdir
SIP 協定處理區塊
kamailio 是個處理 SIP 封包的程式,SIP 封包分成請求 (SIP request) 跟回覆 (SIP reply) 兩類。基本上命令檔需要告訴 kamailio 如何處理進來的 SIP 請求封包,最後看是要轉送、產生回覆封包、還是要忽略等等。SIP 請求由命令檔中的 route (或 request_route) 區塊負責,有 SIP 請求進來就執行,有點像 C 語言內定的 main 函數。如果收到的是 SIP 回覆封包就執行另一個內定的區塊 -- onreply_route,但這部份不是必要的,因為 kamailio 對於 SIP 回覆預設會移除第一個 VIA,並依據第二個 VIA 的位址轉送。kamailio 還有其它內定的區塊,包括 onsend_route、branch_route、failure_route、及 event_route[module:event],其中 branch_route 跟 failure_route 搭配
tm 模組才會用到,event_route[module:event] 也需要搭配其它模組。
區塊內有內建函數 (function)、內建 keyword、內建 value 等可以利用,可透過載入模組來擴充函數。
Routing blocks
route 或 route[0] 或 request_route
- 收到 SIP 請求所要做的動作,需明確的處置,看是要回覆、轉送等等,不然預設是丟棄。
onreply_route
- 收到 SIP 回覆所作的動作,最後有個隱含的動作是依據 Via 轉送,結束、或者中途執行 exit 或 return(0) 而離開,都會執行。如果執行 drop 離開的話,不會執行隱含的動作,而直接丟棄。
onsend_route
- 送出 SIP 封包前執行,預設只有請求封包,如果命令檔參數 onsend_route_reply 有設,則包括回覆封包。能執行的指令有限制。
branch_route[name]
- 呼叫 tm 模組的 t_on_branch(name) 時所作的動作,最後隱含的動作是轉送
failure_route
event_route
內建函數
exit() 或 return(0)
return([retcode])
- 結束函數。回傳的值預設是 1,可用 $retcode 或 $? 取得,邏輯判斷正數為 true,負數為 false。
drop()
forward()
- stateless 依據 $du 轉送。$du 是 L3 IP 位址或 L4 port,跟 SIP 內容無關。
rewritehost("domain") 或 sethost, seth
rewriteport("port") 或 setport, setp
rewritehostport("domain:port") 或 sethostport, sethp
rewritehostporttrans("...") 或 sethostporttrans, sethpt
rewriteuser("user") 或 setuser, setu
rewriteuserpass("password") 或 setuserpass, setup
rewriteuri("uri") 或 seturi
- 這些改寫 request URI,包含 L3/L4 位址
revert_uri()
force_send_socket(ip [ :port] )
- 強制使用其它 listen 的 socket 送封包
route(name)
- 呼叫指定名稱的 route 區塊。指定名稱也可以是字串組合的表示式。
其它還有 add_local_rport
avpflags
break error
exec
force_rport
add_rport force_tcp_alias isavpflagset
isflagset
is_int
log
prefix
resetavpflag
resetflag set_advertised_address
set_advertised_port
set_forward_no_connect
set_forward_close
set_reply_no_connect
set_reply_close
setavpflag
setflag
strip
strip_tail
udp_mtu_try_proto(proto)
userphone
Keywords 及 values
keyword 就是 SIP 封包解析後的欄位,通常用在 if 描述 (唯讀?)。另外提供了 value 方便跟 keyword 比較。
af, dst_ip, src_ip, proto, dst_port, src_port, proto
- 這些是所收到 SIP 封包的 address family、目的/來源 IP 位址、目的/來源 port 及協定
- af 的值可能是 INET 或 INET6,proto 的值可能是 UDP、TCP、TLS、SCTP、WS、WSS。
method
- SIP 封包的 method
- 不確定是否包含 reply
msg:len
uri, status
- request uri 及 reply 的 status
- uri 可跟值 myself 作測試,看請求的對象就是自己、還是需要轉送給其它伺服器。myself 是個列表,由設定檔設定的 local IP addresses、hostnames 及 aliases 組成,也就是 kamailio 伺服器服務的 domains。命令檔參數 alias 可加 hostnames、IP addresses、及 aliases 到 myself 列表。
- $ru
to_ip, to_port, to_uri, from_uri
snd_af, snd_ip, snd_proto, snd_port
- 類似 af、src_ip、proto、src_port,但是封包要送出的狀況。
Script statements
if-else 或 while 表示式,包括
| == | 相等 |
| != | 不相等 |
| =~ | Posix 正規表示式比對。使用 [[:digit:]]{3} 取代 \d\d\d。 |
| > | 大於 |
| >= | greater or equal |
| < | 小於 |
| <= | less or equal |
| && | 邏輯 AND |
| || | 邏輯 OR |
| ! | 邏輯 NOT |
| [ ... ] | test operator - 裡面可以是任何算術式。 |
switch 虛擬變數
Script operations
Assignment (=) 的左邊可以是虛擬變數
- Unordered List Item AVPs - to set the value of an AVP
- 附在 SIP 訊息的 Attribute-value pair
- script variables ($var(…)) - to set the value of a script variable
- shared variables ($shv(…))
- $fs - to set send socket
- $br - to set branch
- $mf - to set message flags value
- $sf - to set script flags value
- $bf - to set branch flags value
字串用「+」串起來,算術運算支援類似 C 語言,有「+」「-」「*」「/」「mod」「|」「&」「^」「~」「<<」「>>」。
Operators
- (int), (str):type cast
- eq, ne:字串比較
- ieq, ine:整數比較
- ==, !=:字串或整數比較。原則上市轉換成左 operand 的 type,除非左 operand 是 undef
kamailio 的資料型態有整數 (int)、字串 (str)、及 null
一些例子
- 0 == "" (true)
- 0 eq "" (false,0 轉成字串是 "0")
- "a" ieq "b" (true: "a" 跟 "b" 轉成整數都是 0)
- "a == "b" (false)
其它
unordered list item AVPs
script variable
shared variable
$null
參考來源
- http://www.kamailio.org/wiki/cookbooks/4.2.x/core
- http://www.kamailio.org/wiki/cookbooks/4.2.x/pseudovariables
- kamailio source code
延伸閱讀