

rr 模块包含的函数不算多,但不容易理解。本文试图分享笔者这方面的经验。
record_route()
调用 record_route() 函数,在 Request 消息里面增加 Record-Route 头。
增加 Record-Route 头的目的是后续该对话内的所有消息都要经过 Kamailio。
一般情况下的处理是: Request 方法是 INVITE 或者 SUBSCRIBE,并且没有 to 标签时调用 record_route()。
record_route() 是 Kamailio 感知网络拓扑,自动增加。下面是一个例子:
Record-Route: <sip:192.168.1.100;lr=on>record_route_preset()
record_route_preset() 也是增加 Record-Route 头。
但跟 record_route() 不同的的是,可以控制 Record-Route 头的内容。请看下面的例子:
record_route_preset("sbc.xswitch.cn:5061;transport=tls", "192.168.1.100:5060;transport=tcp");
add_rr_param(";r2=on");产生 Double RR 头:
Record-Route: <sip:192.168.1.100;transport=tcp;r2=on;lr=on>
Record-Route: <sip:sbc.xswitch.cn:5061;transport=tls;r2=on;lr=on>UAC 访问第二个 Record-Route 头,UAS 访问第一个 Record-Route 头。
那么问题来了,什么时候用 record_route(),什么时候用 record_route_preset() 呢?
有的局向要求比较特别,不接受 IP 地址,只接受域名,这种情况只能用record_route_preset()。
record_route_advertised_address()
record_route_advertised_address() 跟 record_route() 相似,但给的是外网地址。
笔者在工程中没用过这个函数。
loose_route()
字面意思是松散路由,但其实先测试严格路由,如果严格路由失败,再测试松散路由。
所谓严格路由就是 R-URI 是 myself。
所谓松散路由则是检查顶层 Route 头是不是 myself,如果不是 myself 就返回失败,
如果是 myself,那么先删除顶层 Route,如果还有 Route,就把请求发到 Route;如果没有 Route,就把请求发到 R-URI。
还有 Double RR 头的处理。这里不再赘述,可查相关手册。
松散路由非常复杂,需要多看规范多看案例。
一般是 Kamailio 收到 ACK/BYE/Re-INVITE 等对话内请求时调用 loose_route()。
loose_route_mode()
loose_route_mode(0) 跟 loose_route() 完全等效。
loose_route_mode(1) 不做严格路由,只做松散路由。
add_rr_param()
add_rr_param() 增加 rr 参数。 前面讲 Double RR 时已经提到了。
常见的处理可能是:
if (is_request()) {
if (!has_totag() && isbflagset(FLB_NATB)) {
add_rr_param(";nat=yes");
}
}产生的 Record-Route 为:
Record-Route: <sip:192.168.1.100;lr=on;nat=yes>check_route_param()
检查路由参数。
比如收到 ACK 时,Route 为:
Route: <sip:192.168.1.100;lr=on;nat=yes> 对应的路由脚本为:
if (is_request()) {
if(has_totag()) {
if(check_route_param("nat=yes")) {
setbflag(FLB_NATB);
}
}
}is_direction()
检查方向。
UAC 到 UAS 为 downstream, UAS 到 UAC 为 upstream。
rr 模块的 append_fromtag 参数需要配置为 1 才能调用此函数。
rr 模块自动把 from 标签加到 rr 头的 ftag 参数。
熟悉 SIPp scenarios XML 的都知道, UAS 发送的 UPDATE/BYE/Re-INVITE 等都需要把 from 标签和 to 标签反过来,is_direction 就是根据这个特点进行判断的。
loose_route_preloaded()
检查是否为预加载路由。
Kamailio 收到 INVITE 消息时,有 Route 头,并且 Route 头为 myself,这就是预加载路由。
JsSIP 可以配置是否支持预加载路由。
还有一种情况就是,Kamailio 收到注册请求时调用 add_path() 函数,并把请求转给 FreeSWITCH,FreeSWITCH 呼叫注册用户时会自动带 Route 头。这也是预加载路由。
remove_record_route()
remove_record_route() 用于删除由record_route()函数添加的内部数据块,可用来撤销之前添加的 Record-Route 头。
笔者没用过这个函数。
rr_next_hop_route()
如果下一跳还是 Route 就返回成功,否则就返回失败。
本文分享自 FreeSWITCH中文社区 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!