在使用SIP注册代理的场景中,经常遇到 FS向注册代理服务器请求外呼时,由于注册代理服务器的地址为内网,所以FS的请求SDP会自动切换为内网,这是使得FS的媒体不能直接和客户端进行RTP通信。
所以有些场景会需要FS固定SDP为公网地址,代理服务器进行媒体绕过,FS直接和客户端进行媒体通信。
增加一个通道变量 fix_extrtpip ,设为 true时,呼叫发起是则强制SDP的地址为 external_rtp_ip配置的值。
源码中增加该变量的控制
freeswitch 1.10.1 版本 switch_core_media.c -> switch_core_media_choose_port 函数。
增加的代码是红色部分:
if(switch_channel_var_true(session->channel, "fix_extrtpip")){
use_ip = smh->mparams->extrtpip;
}else{
/* No NAT traversal required, use the profile's rtp ip */
use_ip = smh->mparams->rtpip;
}
在源码中的大致位置 8214 行:
/* Check if NAT is detected */
if (!zstr(smh->mparams->remote_ip) && switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
/* Yes, map the port through switch_nat */
switch_nat_add_mapping(engine->local_sdp_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE);
switch_snprintf(vname, sizeof(vname), "rtp_adv_%s_ip", tstr);
/* Find an IP address to use */
if (!(use_ip = switch_channel_get_variable(session->channel, vname))
&& !zstr(smh->mparams->extrtpip)) {
use_ip = smh->mparams->extrtpip;
}
if (use_ip) {
if (switch_core_media_ext_address_lookup(session, &lookup_rtpip, &sdp_port, use_ip) != SWITCH_STATUS_SUCCESS) {
/* Address lookup was required and fail (external ip was "host:..." or "stun:...") */
return SWITCH_STATUS_FALSE;
} else {
/* Address properly resolved, use it as external ip */
use_ip = lookup_rtpip;
}
} else {
/* No external ip found, use the profile's rtp ip */
use_ip = smh->mparams->rtpip;
}
} else {
+ //add by aominle [20211021] : 强制sdp为公网IP
+ if(switch_channel_var_true(session->channel, "fix_extrtpip")){
use_ip = smh->mparams->extrtpip;
+ }else{
/* No NAT traversal required, use the profile's rtp ip */
use_ip = smh->mparams->rtpip;
}
}
用法:
在发起呼叫是增加通道变量 {fix_extrtpip=true}