专注于VoIP,Opensips,Kamailio等技术,QQ群:QQ群:293697898
三、路由类型 OpenSIPS 路由逻辑使用多种类型的路由。每种类型的路由都由特定事件触发,并允许您处理特定类型的消息(请求或回复)。
请求路由块。它包含要对 SIP 请求执行的一组操作。
触发者:接收来自网络的外部请求。
处理:触发 SIP 请求。
类型 :最初是无状态的,可以使用 TM 函数强制为有状态。
默认操作:如果请求既没有转发也没有回复,路由将简单地在最后丢弃请求。
由“route{...}”或“route[0]{...}”标识的主“路由”块为每个SIP请求执行。
执行主路由块后的隐式操作是丢弃 SIP 请求。若要发送回复或转发请求,必须在路由块内调用显式操作。
用法示例:
route {
if(is_method("OPTIONS")) {
# send reply for each options request
sl_send_reply(200, "OK");
exit();
}
route(1);
}
route[1] {
# forward according to uri
forward();
}
请注意,如果从“branch_route[Y]”调用“route(X)”,则在“route[X]”中只是处理每个单独的分支,而不是像主路由中发生的那样将所有分支一起处理。
请求的分支路由块。它包含要对 SIP 请求的每个分支执行的一组操作。
触发者:准备(请求的)新分支;分支已形成,但尚未发出。
处理:SIP 请求(具有分支特性,如 RURI、分支标志)
类型 : 有状态
默认操作:如果分支没有被删除(通过“drop”语句),分支将自动发出。
它仅在通过t_on_branch(“branch_route_index”)武装后由TM模块执行。
用法示例:
route {
lookup("location");
t_on_branch("1");
if(!t_relay()) {
sl_send_reply(500, "Internal Server Error");
}
}
branch_route[1] {
if($ru=~"10\.10\.10\.10") {
# discard branches that go to 10.10.10.10
drop();
}
}
失败的事务路由块。它包含一组要执行的操作,每个事务仅收到所有分支的否定答复 (>=300)。
触发者:接收或生成(内部)完成交易的否定回复(所有分支都以否定回复终止)
处理:原始 SIP 请求(已发送)
类型 : 有状态
默认操作:如果没有生成新的分支或没有强制回复,默认情况下,获胜的回复将发送回UAC。
“failure_route”仅在通过t_on_failure(“failure_route_index”)武装后由TM模块执行。
请注意,在“failure_route”中,正在处理发起事务的请求,而不是其回复。
用法示例:
route {
lookup("location");
t_on_failure("1");
if(!t_relay()) {
sl_send_reply(500, "Internal Server Error");
}
}
failure_route[1] {
if(is_method("INVITE")) {
# call failed - relay to voice mail
t_relay("udp:voicemail.server.com:5060");
}
}
回复路由块。它包含要对 SIP 回复执行的一组操作。
触发者:接收来自网络的回复
处理中:收到的回复
类型 :有状态(如果绑定到事务)或无状态(如果绑定到全局回复路由)。
默认操作:如果回复没有被删除(只能删除临时回复),它将由事务引擎注入和处理。
有三种类型的回复路由:
global - 它捕获 OpenSIPS 收到的所有回复,不需要任何特殊布防(简单的定义就足够了) - 名为 'onreply_route {...}' 或 'onreply_route[0] {...}'。注意:此路由无法识别 SIP 事务(回复与事务不匹配),因此此处没有可用的事务数据。
每个请求/事务 - 它捕获属于某个事务的所有收到的回复,并且需要在请求时(通过“t_on_reply()”)在请求路由中武装(通过“()”,名为“onreply_route[N] {...}”。
每个分支 - 它仅捕获事务中属于某个分支的回复。它需要在请求时武装(也通过“t_on_reply()”),但在分支路由中,当某个传出分支被处理时 - 名为“onreply_route[N] {...}”。
某些“onreply_route”块可以由TM模块执行以进行特殊回复。为此,“onreply_route”必须为SIP请求做好准备,SIP请求的回复应通过t_on_reply(“onreply_route_index”)在其中处理。
route {
seturi("sip:bob@opensips.org"); # first branch
append_branch("sip:alice@opensips.org"); # 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;
}
}
当 SIP 请求处理期间发生解析错误或脚本断言失败时,将自动执行错误路由。它允许管理员决定在此类错误情况下要做什么。
重要提示:由于这仅适用于 SIP 请求,因此 OpenSIPS 必须能够正确解析 SIP 消息的第一行。因此,第一行中的任何语法错误都不会触发此路由(因为OpenSIPS将无法判断是回复还是请求)。
触发者:“路由”中的解析错误
正在处理:请求失败
类型 : 无状态(推荐)
默认操作:放弃请求。
在error_route中,以下伪变量可用于访问错误详细信息:
$(err.class) - 错误类(现在是解析错误的“1”)
$(err.level) - 错误的严重性级别
$(err.info) - 描述错误的文本
$(err.rcode) - 推荐的回复代码
$(err.rreason) - 建议的回复原因短语
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;
}
当 TM 在内部(无 UAC 端)生成新的 SIP 请求时,将自动执行本地路由。此路由旨在用于邮件检查、记帐和对邮件头应用最后更改。不允许使用路由和信令功能。
触发者: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