openSIPS路由規則使用幾種類型的路由。每種路由是被一中特定時間觸發,並且允許你處理一種確定類型的消息。(請求或者應答)
1.主路由--route
由route{...}或者route[0]{...}來標識
觸發條件:SIP請求
處理:SIP請求
類型:初始的時候無狀態,後面可能會由TM模塊函數變爲有狀態。
默認動作:如果請求沒有被轉發或者回復,會被丟棄。
2.分支路由--branch_route
請求的分支路由塊,它包含了對於一個SIP請求每個分支的一系列動作
觸發條件:準備一個請求的新分支,這個分支已經完整但並未被髮送出去
處理:帶有分支特徵的SIP請求(比如requset URI,分支標誌等)
類型:有狀態
默認動作:如果分支中沒有使用drop,則默認會將請求發送出去
例子:它是由TM模塊中的t_on_branch("branch_route_index")來執行調用的
route {
lookup("location");
t_on_branch("1");
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
}
}
branch_route[1] {
if(uri=~"10\.10\.10].10") {
# discard branches that go to 10.10.10.10
drop();
}
}
3.失敗路由--failure_route
錯誤處理路由。裏面有當傳輸中任何分支收到錯誤應答(>=300)時所應該採取的動作。
觸發條件:任何分支中的傳輸錯誤
處理:被發出去的初始request
類型:有狀態
默認動作:如果裏面沒有走新的分支路由,或者沒有應答被強制結束,將獲得的回覆轉發給UAC
例子:由TM模塊中的t_on_failure("fail_route_index")來執行
route {
lookup("location");
t_on_failure("1");
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
}
}
failure_route[1] {
if(is_method("INVITE")) {
# call failed - relay to voice mail
t_relay("udp:voicemail.server.com:5060");
}
}
4.應答路由--onreply_route
應答路由塊。對於每個SIP應答所採取的動作
觸發條件:接收到網絡中應答
處理:reply
類型:有狀態(傳輸相關)或者無狀態(全局應答)
默認動作:如果未被丟棄(只有臨時應答可能會被),會由傳輸引擎來處理
有三種類型的應答路由:
(1)global
全局應答路由,捕獲所有openSIPS收到的應答,不需要特殊操作。使用:onreply_route{...}或者onreplay_route[0]{...}
(2)per request/transaction
每次請求/傳輸對應應答路由,捕獲某個確定傳輸過程中的所有應答,由t_on_reply()請求時在請求路由中執行。使用:onreply_route[n]{...}
(3)per branch
每個分支對應應答路由,捕獲某個確定分支中的應單,由t_on_reply()請求時在分支路由中執行。使用:onreply_route[n]{...}
例子:
route {
seturi("sip:[email protected]"); # first branch
append_branch("sip:[email protected]"); # second branch
t_on_reply("global"); # the "global" reply route
# is set the whole transaction
t_on_branch("1");
t_relay();
}
branch_route[1] {
if ($rU=="alice")
t_on_reply("alice"); # the "alice" reply route
# is set only for second branch
}
onreply_route {
xlog("OpenSIPS received a reply from $si\n");
}
onreply_route[alice] {
xlog("received reply on the branch from alice\n");
}
onreply_route[global] {
if (t_check_status("1[0-9][0-9]")) {
setflag(1);
log("provisional reply received\n");
if (t_check_status("183"))
drop;
}
}
5.錯誤路由--error_route
解析SIP請求中出現語法錯誤時所應採取的動作。
觸發條件:解析錯誤
處理:失敗的請求
類型:無狀態(需要)
默認動作:丟棄請求
例子:
error_route {
xlog("--- error route class=$(err.class) level=$(err.level)
info=$(err.info) rcode=$(err.rcode) rreason=$(err.rreason) ---\n");
xlog("--- error from [$si:$sp]\n+++++\n$mb\n++++\n");
sl_send_reply("$err.rcode", "$err.rreason");
exit;
}
6.本地路由--local_route
在一個SIP請求由TM模塊產生而非UAC時執行,它用來做消息檢查,賬戶認證和更新消息頭。路由和信令函數不能在這裏面執行。
觸發條件:TM模塊生成新請求
處理:新請求
類型:有狀態
默認動作:發出請求
例子:
local_route {
if (is_method("INVITE") && $ru=~"@foreign.com") {
append_hf("P-hint: foreign request\r\n");
exit;
}
if (is_method("BYE") ) {
acc_log_request("internally generated BYE");
}
}
在原始請求上進行封裝。
7.起始路由--startup_route
在opensSIPS啓動後到監聽進程運行中間時,做出必要的初始化動作,不處理SIP信息。
觸發條件:openSIPS啓動後
處理:初始函數
例子:
startup_route {
avp_db_query("select gwlist where ruleid==1",$avp(i:100));
cache_store("local", "rule1", "$avp(i:100)");
}
8.定時路由--time_route
定期自動執行的路由,不處理SIP信息。
觸發條件:定時器
處理:做刷新動作的函數
例子:
timer_route[gw_update, 300] {
avp_db_query("select gwlist where ruleid==1",$avp(i:100));
$shv(i:100) =$avp(i:100);
}
9.事件路由--event_route
當事件發生時,openSIPS Event接口來執行腳本。名字是由路由來處理的事件的名字。
觸發條件:當一個Event被拋出時由event_route觸發
處理:該event
類型:無狀態(需要)
默認動作 :event發生時不執行任何腳本
例子:
event_route[E_PIKE_BLOCKED] {
xlog("The E_PIKE_BLOCKED event was raised\n");
}