概述
在笔者的场景下,多台FreeSWTICH依靠OpenSIPS作信令的负载均衡。
OpenSIPS对外开放SIP端口,FreeSWITCH对外开放RTP端口。
这种网络拓扑结构下,FS发送的INVITE以及回复的200OK中,SDP携带的是内网IP,如下图:
我们可以借助OpenSIPS的fix_nated_sdp函数将其中的内网IP翻译为公网IP,该函数使用文档:
https://opensips.org/docs/modules/3.1.x/nathelper.html#func_fix_nated_sdp
需要修复SDP的地方一共有三处(省略了前后无关配置),
1. 外呼时的INVITE
else if (is_method("INVITE")) {
if ($fU == "022xxxxxxxx") {
sethostport("121.43.xxx.xxx:5060");
t_check_trans();
record_route();
if (check_address(1,"$si",0,"",$avp(ctx))) {
xlog("fix callout invite, si:$si, set:$avp(ctx)n");
fix_nated_sdp(10,$avp(ctx));
}
route(RELAY);
}
}
2. REINVITE
if (has_totag()) {
if (is_method("INVITE")) {
if (check_address(1,"$si",0,"",$avp(ctx))) {
xlog("fix reinvite, si:$si, set:$avp(ctx)n");
fix_nated_sdp(10,$avp(ctx));
}
}
}
3. 200OK
onreply_route[save_status] {
if (t_check_status("200")) {
if (check_address(1,"$si",0,"",$avp(ctx))) {
xlog("fix 200 OK, si:$si, set:$avp(ctx)n");
fix_nated_sdp(10,$avp(ctx));
}
}
}
因为笔者的场景下有多个FreeSWITCH,不可能把每个FS的公网IP都配置到配置文件里。所以上面借助了address表,将FS的公网IP存到了address表的context列中,在修复SDP之前,先从数据库中根据FS的内网IP读出FS的公网IP。
这算是一个小技巧吧,不过要注意,check_address函数是不能在ONREPLY_ROUTE块中使用的,所以要稍微改动下代码:
static cmd_export_t cmds[] = {
{"check_address", (cmd_function)check_addr,
{ {CMD_PARAM_INT, NULL, NULL},
{CMD_PARAM_STR, NULL, NULL},
{CMD_PARAM_INT, NULL, NULL},
{CMD_PARAM_STR, fix_proto, NULL},
{CMD_PARAM_VAR|CMD_PARAM_OPT, NULL, NULL},
{CMD_PARAM_STR|CMD_PARAM_OPT, fix_str2s, free_str2s},
{CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, fix_part, NULL},
{0 , 0, 0}
},
REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE|BRANCH_ROUTE|
STARTUP_ROUTE|TIMER_ROUTE|EVENT_ROUTE|ONREPLY_ROUTE
},
}
加上ONREPLY_ROUTE宏。
如果有更好的保存FS内外网IP关系的方法,请留言!
最后
以上就是机灵楼房为你收集整理的OpenSIPS修复SDP中内网IP(NAT穿越问题)的全部内容,希望文章能够帮你解决OpenSIPS修复SDP中内网IP(NAT穿越问题)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复