FreeSwitch公网语音对讲可以接通但没有声音问题探究

背景

公司业务用到对讲系统,采用FreeSWITCH自己搭对讲服务器。原本有一台对讲服务器部署在华为云,因为价格贵及经常受攻击的原因,要迁移到阿里云服务器。于是,运维人员在阿里云服务器部署一个FreeSWITCH,版本比原FreeSWITCH新,配置基本复制原FreeSWITCH。

问题

阿里云FreeSWITCH部署好后,我们发现局域网内2台对讲机可以相互呼通并通话,公网2台对讲机(比如一个在公司电脑的MicroSIP走公司外网、一个自己手机zoiper走运营商4G)可以相互呼叫,但接通后没有声音。华为云FreeSWITCH这2种情况都正常。

FreeSWITCH知识

相关协议

SIP 会话初始协议。SIP是负责建立和关闭会话的协议。SIP就类似建一条高速公路,只负责建路,路上跑什么不负责。
SDP 会话描述协议。放在SIP的body中,和SIP配合使用。用于媒体协商。类似说明公路上跑什么车。
RTP 实时传输协议。在SIP和SDP协商后,媒体数据通过RTP传输。类似公路上跑的车,而媒体数据就是货物。

SIP终端(MicroSIP、zopiper等)穿越NAT方案

STUN服务——即SIP终端先向STUN服务获取自己的外网IP和端口,再与FreeSWITCH通讯。
ICE——综合利用STUN和TURN(详细待研究)。

FreeSWITCH帮助终端穿越NAT方案

SIP穿越

配置sip_profiles/internal.xml

<param name="apply-nat-acl" value="nat.auto"/>

nat.auto是一个IP列表,里面包含RFC1918规定的私网地址,且去掉本地网络地址。

这样,SIP终端在注册时,FreeSWITCH对比这个IP列表和concat地址判断终端是否在NAT后面,如果是,就把concat地址换成数据来源包的网络地址。

在fs_cli终端,命令sofia status profile internal reg 查看注册信息,contact会有nat及外网信息。

Concat: <sip:21428506@10.11.64.109:51304;rinstance=004c0392b693c739;transport=tcp;fs_nat=yes;fs_path=sip:21428506@223.104.64.162:29310;rinstance=004c0392b693c739;transport=tcp>
RTP穿越

SIP终端没有采取穿越方案情况下,SDP信息的IP地址会是SIP终端私网地址,RTP包无法发到这些私网地址,语音就不通。

FreeSWITCH有RTP自动调整功能。基本流程如下,

1、SIP协商阶段,FreeSWITCH返回SIP终端一个公网RTP地址。
2、SIP终端往上述公网RTP地址发送一个RTP包。
3、FreeSWITCH获取2步骤的RTP包来源地址作为SIP终端RTP通讯地址。
4、后续FreeSWITCH就通过上述地址给这个SIP终端发送RTP包。

为防止步骤2被黑客攻击把RTP包引到自己那里,FreeSWITCH只允许在电话开始时做一次调整。

RTP自动调整功能默认开始。可以通过sip_profiles/internal.xml配置关闭。

<param name="disable-rtp-auto-adjust" value="true"/>

也可以指定某些呼叫禁止,设置呼叫通道变量rtp_auto_adjust=false。

FreeSWITCH日志一般存储在/var/log/freeswitch目录。FreeSWITCH会话日志显示RTP自动调整操作,样例如下,

[INFO] switch_rtp.c:7268 Auto Changing audio port from 10.11.64.109:33888 to 223.104.64.162:38179

FreeSWITCH服务器在NAT网络

设置sip_profiles/internal.xml文件ext-sip-ip和ext-sip-ip为服务器外网IP或者autonat:外网IP

<param name="ext-sip-ip" value="1.1.1.1"/>
<param name="ext-sip-ip" value="1.1.1.1"/>

<param name="ext-sip-ip" value="autonat:1.1.1.1"/>
<param name="ext-sip-ip" value="autonat:1.1.1.1"/>

配置成autonat:1.1.1.1,sofia status profile internal显示Auto-NAT为true。

分析

我们的情况是局域网有声音,公网无声音,应该是NAT问题。

能呼通,说明SIP穿越无问题,应该是RTP穿越问题。

我们的SIP终端没有采用任何穿越NAT方案,所以SDP包上的地址是私网地址,需要依赖FreeSWITCH服务器实现RTP穿越。

查看配置,disable-rtp-auto-adjust项设置是false,就是RTP自动调整功能是开启的。

查看无声音的会话日志,并没有RTP自动调整日志。难道还有其他参数影响?

通过fs_cli终端命令sofia status profile internal查看internal配置信息,对比2台FreeSWITCH配置信息,发现NOMEDIA项不同:
通话正常的NOMEDIA=false,通话无声音的NOMEDIA=true。

(如神来之笔?其实定位过程花了一天时间)

Freeswitch.org资料显示,NOMEDIA是由inbound-bypass-media参数控制,称为无媒体模式(no media mode)。说明如下,


无媒体模式是一个SDP传输控制参数,它允许2个终端可以直连它们的媒体会话,而FreeSWITCH只负责维护SIP相关操作。但它不能用于NA网络下的终端。

在终端有FreeSWITCH不支持的媒体编码协议或者想让FreeSWITCH高效处理SIP会话而不用关注RTP的应用场景下,可以考虑开启这个参数。

附一张图
在这里插入图片描述

开启inbound-bypass-media这个参数,终端的RTP通讯就是终端之间点对点传输,不再经过FreeSWITCH,不会执行RTP自动调整操作。而在NAT网络下终端相互不知道对方的外网地址,无法正常传输RTP数据,所以语音不通。

注释掉sip_profiles/internal.xml中inbound-bypass-media配置

<!--<param name="inbound-bypass-media" value="true"/>-->

重启FreeSWITCH,问题解决。

定位问题命令记录

fs_cli终端命令

  • 查看profile配置 sofia status profile internal

  • 查看注册用户 sofia status profile internal reg

  • 重启 fsctl shutdown restart

直接服务器终端运行命令 fs_cli -x fs_cli终端命令

freeswitch日志找到某次呼叫起始位置(21161498是电话账号)

grep -n 21161498 freeswitch.log |grep switch_core_state_machine|grep CS_NEW|less

总结

  • 定位问题,了解一定的原理可能事半功倍。
  • 用好已有的参照物。

参考资料

Bypass Media

FreeSWITCH配置手记

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值