今天,帮客户调试一个FreeSWITCH媒体问题,需要模拟丢包测试一下。
首先,FreeSWITCH在公网上,客户端在NAT环境中。我们先用客户端呼叫9196。呼通后可以听到自己的回音。
从下面的SDP中,我们很容易地获得客户端的IP地址和端口号分别是192.168.7.6和50432:
2015-08-13 17:10:24.978258 [DEBUG] sofia.c:5667 Remote SDP:
v=0
o=- 1439457023465991 1 IN IP4 192.168.7.6
s=Bria 3 release 3.5.5 stamp 71243
c=IN IP4 192.168.7.6
t=0 0
m=audio 50432 RTP/AVP 123 8 0 101
a=rtpmap:123 opus/48000/2
a=fmtp:123 useinbandfec=1
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
不过,由于客户端处于NAT后面,实际上FreeSWITCH向上述地址发送UDP包是发不通的。FreeSWITCH解决这类NAT问题的办法就是等待客户端给它发送RTP包。收到后便能“学习”到客户端的外网IP地址和端口号。我们很容易地从日志中找到它:
2015-08-13 17:10:26.038239 [INFO] switch_rtp.c:3713 Auto Changing port from 192.168.7.6:50432 to 112.238.196.224:50432
好了,知道了客户端的IP和端口以后,我们就可以用iptables模拟丢包了。
iptables -A OUTPUT -p udp --dst 112.238.196.224 --dport 50432 -m statistic --mode random --probability 0.08 -j DROP
上述命令是在FreeSWITCH所在的服务器上运行的。表示,所有发往IP 112.238.196.224和端口50432的包,8%的直接丢掉不发。
上面的例子是模拟FreeSWITCH发送时丢包。在实际使用中,有时也会模拟FreeSWITCH接收端丢包,可以用类似如下的命令来实现:
iptables -A INPUT -p udp —src 112.238.196.224 —sport 50432 -m statistic --mode random --probability 0.08 -j DROP
当然,iptables还有很多的参数和功能策略。读者不妨参照其文档自行学习研究一下。