freeswithc 对接运营商落地网关

freeswithc “Auto Changing audio port from” 原理解析

整体环境

在对接外部运营商的落地网关的时候,流程图如下,core区的机器无法连接到外网,需要在外网区域增加一台转发服务器fs,来达到内网和外部手机的通信
dmz区IP:100.69.208.59
core区IP:100.69.216.126

对接所做配置文件修改

呼出的配置
在这里插入图片描述

  1. core区修改dialplan/default.xml ,添加如下,转接到dmz区的服务器上
<extension name="out-dmz">
  <condition field="destination_number" expression="^0(.*)$">
        <action application="bridge" data="sofia/external/sip:$1@100.69.208.59:5060"/>
      </condition>
    </extension>

  1. dmz区的external统一由dialplan/public/00_inbound_did.xml 来处理,添加 如下代码,转接到IMS网关上
<extension name="test-to-ims">
<condition field="destination_number" expression="^10(.*)$">
          <action application="set" data="domain_name=$${domain}"/>  
     <action application="bridge" data="sofia/gateway/ims/99$1"/>
   </condition>
 </extension>

  1. 增加了 IMS网关 增加sip_profiles/external/gateway.xml 文件,如下配置 ;
<include>
  <gateway name="ims"> 
	  <param name="username" value="075533614xxx"/>
	  <param name="password" value="none"/>
	  <param name="proxy" value="122.13.xx.xx:5060"/>
	  <param name="register" value="false"/>
  </gateway>
</include>

  1. 由于在呼出的时候invite 中的sdp会替换成dmz区的内网IP,所以需要在internal.xml中修改ext-rtp-ip为映射的外网IP如:112.xxx.xxx.xxx ;否者会出现呼叫能通但是没有语音

呼入的配置

在这里插入图片描述

  1. public下的xml 增加外部呼入的规则,如下我写定转接到core区的1000,也可以做一个IVR分机拨号的功能;
<extension name="test-to-core">
    <condition field="destination_number" expression="^(07553361xxxx)$">
      <action application="set" data="domain_name=$${domain}"/>  
      <action application="bridge" data="sofia/external/sip:1000@100.69.216.126:5060"/>
    </condition>
  </extension>

  1. core区的public下的xml增加1000的拨号规则,转到internal的1000上
<extension name="public_test">
    <condition field="destination_number" expression="^(10[01][0-9])$">     
      <action application="transfer" data="$1 XML default"/>
    </condition>
  </extension>
3. 由于在呼入的时候,回复invite 的包中的sdp会替换成dmz区的内网IP,所以需要在external.xml中修改ext-rtp-ip为映射的外网IP如:112.xxx.xxx.xxx ;否者会出现入能通但是没有语音

疑问点1:

呼出的时候dmz的internal.xml修改了回复invite中的sdp的IP信息为外网IP,按理说应该core区访问不了外网IP的。
解答:
在日志中看到如下日志,core区的freesiwtch会把dmz区的rtp-ip从外网112.95.xx.xx自动changing 到dmz内网IP:100.69.208.59,因为core区给126-》dmz,dmz会给126发送RTP包做一个auto changing port用

 [INFO] switch_rtp.c:7497 Auto Changing audio port from 112.95.xxx.xxx:20604 to 100.69.208.59:20604

原理:
freeswitch如下图
麻烦:当B处于NAT后,A的RTP流从freeswitch是不能到B的(因为B为内网的IP),而且交换信令的时候,不可能给出NAT后的B的RPT IP和端口
解决:前期freeswitch的RTP-IP给到B,B会给FS发rtp流,以便FS能知道B的真实NAT后的IP和端口(这也是auto changing port的原理),freeswitch会监听UDP的 IP和端口以便接受B发送过来的RTP流
在这里插入图片描述

rtp_common_read 代码中有设置switch_rtp_set_remote_address 设置RTP远程地址的操作

		if (bytes && rtp_session->flags[SWITCH_RTP_FLAG_AUTOADJ] && switch_sockaddr_get_port(rtp_session->rtp_from_addr)) {
			if (!switch_cmp_addr(rtp_session->rtp_from_addr, rtp_session->remote_addr)) {
				if (++rtp_session->autoadj_tally >= rtp_session->autoadj_threshold) {
					const char *err;
					uint32_t old = rtp_session->remote_port;
					const char *tx_host;
					const char *old_host;
					char bufa[50], bufb[50];
					char adj_port[6];

					tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtp_from_addr);
					old_host = switch_get_addr(bufb, sizeof(bufb), rtp_session->remote_addr);

					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO,
									  "Auto Changing %s port from %s:%u to %s:%u\n", rtp_type(rtp_session), old_host, old, tx_host,
									  switch_sockaddr_get_port(rtp_session->rtp_from_addr));
			  rtp_session->auto_adj_used = 1;
					switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->rtp_from_addr), 0, SWITCH_FALSE, &err);

疑问点2:

ext-sip-ip 设置成外网IP后,sip信令将使用外网IP来通信,导致core和dmz区不能正常sip交互

发布了39 篇原创文章 · 获赞 13 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览