Kamailio:调用set_contact_alias()之后,在原有的contact的后面增加参数,具体地说,就是网络地址,网络端口和transport,好处是收到后续请求之时可以恢复原有contact的内容(当然也有坏处,就是增加参数之后导致包大,可能超过MTU)
OpenSIPS:调用fix_nated_contact()之后,用网络地址和网络端口直接覆盖了在原有的contact,那么当收到后续请求时不太可能恢复原有contact的内容。窃以为,一定要慎重
比如,下图所示,OpenSIPS就不要修改uac的contact,显然如此
UAC--->第三方Proxy--->OpenSIPS--->FreeSWITCH
参考链接:
https://kb.smartvox.co.uk/opensips/nat-contact-and-via-fixing-in-sip-part-3/
当然,我们可以模仿set_contact_alias函数
route[set_contact_alias] {
if (is_present_hf("contact")) {
$var(sut) = $si + "~" + $sp + "~" + $socket_in(proto); # 远端网络地址
$var(ct) = $(ct{re.subst,/^(.*)<(.*)>/\2/}); # 取contact <> 里面的内容
# 更换成新的contact
$var(new_ct) = "<" + $var(ct) + ";my_alias=" + $var(sut) + ">";
remove_hf("contact");
insert_hf("Contact: $var(new_ct)\r\n", "Call-ID");
}
}
route[restore_contact_by_alias] {
if (!has_totag()) { # 对话内请求才能调用这个路由
return;
}
# xlog("***ru = $ru, du = $du\n");
if ($du != NULL) { # 如果已经设置了$du,那么不能再调用这个路由
return;
}
$var(my_alias) = $(ru{nameaddr.param,my_alias});
# xlog("***my_alias = $var(my_alias)\n");
if ($var(my_alias) != NULL) {
$var(ip) = $(var(my_alias){s.select,0,~});
$var(port) = $(var(my_alias){s.select,1,~});
$var(transport) = $(var(my_alias){s.select,2,~});
$var(url) = "sip:" + $var(ip) + ":" + $var(port) + ";transport=" + $var(transport);
# xlog("url = $var(url)\n");
setdsturi($var(url));
$ru = $(ru{re.subst,/^(sip:.*);my_alias=.*/\1/}); # 删除ru里面的my_alias以及内容
}
}
完整的路由脚本如下:
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next l