解决xlite和freeswitch通话没有语音的问题
本文章转载至https://blog.****.net/hry2015/article/details/78388839
1. 概述
本文解决如下问题:xlite之间已经正常的进行sip协议的交互,并且1008和1018已经呼通,但是1008和1018互相之间无法听到声音。
主要涉及如下内容:
1. 语音不通的原因分析
2. SDP协议
2. NAT的问题
3. freeswitch如何实现NAT的穿越的问题
2. 案例环境说明
软电话使用x-lite,使用freeswitch的默认的两个号码1008和1018。
freeswitch部署在服务器的私网地址是172.23.4.92,公网地址115.aa.aa.aa。
1008的测试机器在私网上(IP为10.240.80.69),通过115.aa.aa.aa:5060注册freeswitch,但是出去后的公网地址是59.bb.bb.bb。
1018的测试机器在私网上,通过115.aa.aa.aa:5060注册freeswitch,但是出去后的公网地址是123.cc.cc.cc
在172.23.4.92上,使用tcpdump捕获通信过程中的所有包
为了安全,本文把真实环境的公网地址,全部使用假的地址进行替换
3. 原因分析
xlite之间已经正常的进行sip协议的交互,并且1008和1018已经呼通,但是1008和1018互相之间无法听到声音。
3.1 初步判断原因
- a. 正常的流程时,1008和1018之间使用sip协议建立通话后,1008和1018的语音包不直接发送给对方,而是都先发送到freeswitch,由freeswitch转发给对方。但是他们之间通话信息传输使用的却是rtp包或其他UPD包,并且rtp包或其他UPD包不是在已经建立的sip协议线路上传输数据,而是使用别外一条线路传输,所有猜测有可能1008和1018的包都没有成功传输到freeswitch,导致无法听到对方声音
- b. rtp包的传输使用的是UDP,且1008和1018都在内网,fs部署到公网,所以这里又涉及NAT的问题
3.2. SDP
第一个问题:1008和1018之间是如何知道对方的RTP包或其他UPD包交互的IP地址?答案是通过SDP相互知道的。SIP在建立会话时,SIP协议会包含相关的媒体(如视频和音频)的信息,媒体的相关的数据会包含在SDP中。SDP也会放在SIP协议的正文(body)中
3.3. 1008主叫的问题分析
1008 向freeswitch发起INVITE 消息包分析
No. Time Source Destination Protocol Length Info
267 15.676245 59.aa.aa.aa 172.23.4.92 SIP/SDP 968 Request: INVITE sip:[email protected]:5060
---------------------------------------------------------------------------------------------------------------------------------------
Frame 267: 968 bytes on wire (7744 bits), 968 bytes captured (7744 bits) Ethernet II, Src: ZteCorpo_60:22:21 (00:22:93:60:22:21), Dst: Vmware_83:02:4d (00:50:56:83:02:4d)
Internet Protocol Version 4, Src: 59.aa.aa.aa, Dst: 172.23.4.92
User Datagram Protocol, Src Port: 24576 (24576), Dst Port: 5060 (5060)
Session Initiation Protocol (INVITE)
Request-Line: INVITE sip:[email protected]:5060 SIP/2.0
Message Header 略..
Message Body
Session Description Protocol
Session Description Protocol Version (v): 0
Owner/Creator, Session Id (o): - 13153395802875591 1 IN IP4 10.240.80.69
Session Name (s): X-Lite release 4.9.8 stamp 84253
Connection Information (c): IN IP4 10.240.80.69
Time Description, active time (t): 0 0
Media Description, name and address (m): audio 64836 RTP/AVP 9 8 120 0 84 101
Media Attribute
(a): rtpmap:120 opus/48000/2 Media Attribute
(a): fmtp:120 useinbandfec=1; usedtx=1; maxaveragebitrate=64000 Media Attribute
(a): rtpmap:84 speex/16000 Media Attribute
(a): rtpmap:101 telephone-event/8000 Media Attribute
(a): fmtp:101 0-15 Media Attribute
(a): sendrecv
SDP协议的字段说明如下:
和通信地址相关的是:
- 1.Connection Information (c): IN IP4 10.240.80.69:告诉freeswitch本机的通信ip为10.240.80.69
- 2.Media Description, name and address (m): audio 64836 RTP/AVP 9 8 120 0 84 101:告诉freeswitch本机的通信端口为64836
FS 向1008产生一个回铃音时,会通过SDP告诉1008自己的接受语音的IP地址
No. Time Source Destination Protocol Length Info
525 26.399001 172.23.4.92 59.aa.aa.aa SIP/SDP 1228 Status: 183 Session Progress
---------------------------------------------------------------------------------------------------------------------------------------
Frame 525: 1228 bytes on wire (9824 bits), 1228 bytes captured (9824 bits) Ethernet II, Src: Vmware_83:02:4d (00:50:56:83:02:4d), Dst: IETF-VRRP-VRID_04 (00:00:5e:00:01:04)
Internet Protocol Version 4, Src: 172.23.4.92, Dst: 59.aa.aa.aa
User Datagram Protocol, Src Port: 5060 (5060), Dst Port: 24576 (24576)
Session Initiation Protocol (183)
Status-Line: SIP/2.0 183 Session Progress
Message Header 略
Message Body
Session Description Protocol
Session Description Protocol Version (v): 0
Owner/Creator, Session Id (o): FreeSWITCH 1508899003 1508899004 IN IP4 115.aa.aa.aa
Session Name (s): FreeSWITCH
Connection Information (c): 172.23.4.92
Time Description, active time (t): 0 0
Media Description, name and address (m): audio 23180 RTP/AVP 9 101
Media Attribute
(a): rtpmap:9 G722/8000
(a): rtpmap:101 telephone-event/8000
(a): fmtp:101 0-16
在这个消息中freeswitch通知1008的音频的本机的ip为172.23.4.92,是个私网地址。因为1008和freeswitch不在一个局域网中,所有1008发送给freeswitch全部失败。
3.4. 1018被叫的问题分析
freeswitch 进行路由找到1018的信息,向1018发送INVITE信息时,也会通过SDP信息带上自己的接收语音包的IP地址
No. Time Source Destination Protocol Length Info
508 25.731551 172.23.4.92 123.58.160.154 SIP/SDP 1361 Request: INVITE sip:[email protected]:36841;rinstance=0d9373ba78a06600
---------------------------------------------------------------------------------------------------------------------------------------
Frame 508: 1361 bytes on wire (10888 bits), 1361 bytes captured (10888 bits) Ethernet II, Src: Vmware_83:02:4d (00:50:56:83:02:4d), Dst: IETF-VRRP-VRID_04 (00:00:5e:00:01:04)
Internet Protocol Version 4, Src: 172.23.4.92, Dst: 123.58.160.154
User Datagram Protocol, Src Port: 5060 (5060), Dst Port: 36841 (36841)
Session Initiation Protocol (INVITE)
Request-Line: INVITE sip:[email protected]:36841;rinstance=0d9373ba78a06600 SIP/2.0
Message Header 略…
Message Body Session Description Protocol
Session Description Protocol Version (v): 0
Owner/Creator, Session Id (o): FreeSWITCH 1508895355 1508895356 IN IP4 115.aa.aa.aa
Session Name (s): FreeSWITCH
Connection Information (c): IN IP4 172.23.4.92
Time Description, active time (t): 0 0
Media Description, name and address (m): audio 26828 RTP/AVP 9 8 0 101
Media Attribute
(a): rtpmap:9 G722/8000
(a): rtpmap:8 PCMA/8000
(a): rtpmap:0 PCMU/8000
(a): rtpmap:101 telephone-event/8000
(a): fmtp:101 0-16
这里也时使用的私网地址: Connection Information (c): IN IP4 172.23.4.92
1018 接听电话,向FS回送200 OK消息,通过SDP告诉freeswitch自己的地址
No. Time Source Destination Protocol Length Info741 27.795404 123.58.160.154 172.23.4.92 SIP/SDP 815 Status: 200 OK
---------------------------------------------------------------------------------------------------------------------------------------
Frame 741: 815 bytes on wire (6520 bits), 815 bytes captured (6520 bits) Ethernet II, Src: ZteCorpo_60:22:21 (00:22:93:60:22:21), Dst: Vmware_83:02:4d (00:50:56:83:02:4d)
Internet Protocol Version 4, Src: 123.58.160.154, Dst: 172.23.4.92
User Datagram Protocol, Src Port: 36841 (36841), Dst Port: 5060 (5060)
Session Initiation Protocol (200) Status-Line: SIP/2.0 200 OK
Message Header ….
Message Body Session Description Protocol
Session Description Protocol Version (v): 0
Owner/Creator, Session Id (o): - 2353942294 3 IN IP4 10.240.80.146
Session Name (s): X-Lite release 4.9.8 stamp 84253
Connection Information (c): IN IP4 10.240.80.146
Time Description, active time (t): 0 0
Media Description, name and address (m): audio 59974 RTP/AVP 9 8 0 101
Media Attribute
(a): rtpmap:101 telephone-event/8000
(a): fmtp:101 0-15
(a): sendrecv
Connection Information (c): IN IP4 10.240.80.146:此时1018告诉freeswitch的也是私网地址
3.5. 结论
所以的问题的原因如下:
- a. freeswitch返回给1008和1018的SDP信息里的自己的IP地址是私网地址,那么1008和1018向这个私网地址发送语音udp包,当然无法送到freeswitch。所以需要freeswitch在回送的SDP的中的IP地址是自己的公网ip
- b. 解决a的问题,还需要解决freeswitch正确回送语音包的问题。1008和1018向freeswitch提供的SDP里的IP信息也都是私网地址,freeswitch也必须需要识别出1008和1018的对外的公网地址
以上两个问题都是NAT的问题,要解决问题,必须实现NAT穿越
4. NAT
4.1. 什么是NAT的问题
以下已经讲的很清楚,这时不在说明
4.2. NAT的种类
5. freeswich端解决NAT的问题
解决NAT的方法有很多,如客户端的解决方案ICE,STUM,TURN。这里我们略。我目前碰到的NAT问题,使用freeswitch端的NAT的方案即可。
5.1. 修改配置sip_profiles/internal.xml
修改ext-rtp-ip和ext-sip-ip为freeswitch公网地址
<param name="ext-rtp-ip" value="115.aa.aa.aa"/>
<param name="ext-sip-ip" value="115.aa.aa.aa"/>
5.2. 修改freeswitch支持NAT方式启动
默认安装后,freesiwtch是以不支持NAT的方式启动,这时一个大坑。使用ps查看
/usr/bin/freeswitch -u freeswitch -g freeswitch -ncwait -nonat
修改freeswitch支持NAT
// ## 修改freeswitch启动配置 vim /lib/systemd/system/freeswitch.service
// 注释掉这一行 #Environment="DAEMON_OPTS=-nonat"
// 重新加载配置 systemctl daemon-reload
// 重启freeswitch systemctl restart freeswitch
5.3. 开放公网端口
开启freeswitch对应公网的地址的rtp的UDP端口,可以被外网访问
5.4. 测试
如果配置成功,则1008和1018收到freeswitch的回送的SDP的c属性的IP地址为freeswitch的公网IP,并且fs_cli的控制台会输出以下类似的信息,保证freeswitch会将1008和1018传送过来的私网地址转化为对应的公网地址,freeswitch会向1008和1018的公网地址回送语音包,从而保证1008和1018进行正确的通话
Auto Changing audio port from 10.240.80.69:55562 to 59.aa.aa.aa:7698 … Auto Changing audio port from 10.242.5.144:58200 to 59.aa.aa.aa:7734 …
至此,问题解决
6. 参考文献
本文中的所有的图,都是作者用手机拍摄自图书”freeswitch权威指南”