事情的经过是这样的。
有人联系我们想帮忙解决个问题,并给出了问题的简单描述:
8根线不稳定半小时就得重启FreeSWITCH。
问题描述太过简略,因此我们建议用户交纳一定的费用,我们进一步沟通后再决定具体价格,为了便于理解,我们管这个费用叫挂号费。
但是客户不太接受这个方案,不过愿意出更高的价格只要我们能够保证解决。
其实客户的这种方案对双方风险都很大。我们最近挺忙,不想接这样的单子。
不过,经不住客户再三沟通,最后简单问了一下客户使用的什么网关评估了一下可能出现的问题。
其中有一个可能是迅时根本没挂断电话,可能是信号音检测问题,也可能是NAT穿越问题导致FreeSWITCH挂机后BYE消息没到达迅时因此电话未挂机,所以导致所有端口都被占用因此打不通电话。
但是为什么重启FreeSWITCH就能解决我们还不得而知。
这也是为什么我们要收挂号费,我们需要一些时间做进一步检测以便确认问题。多数情况下,如果解决方法极其简单,我们也就不再多收费用了。或者告诉用户我们解决不了,去其它大医院看看。当然,如果我们认为还得进一步治疗则评估下一步治疗的价格。我们一直是这么做的。
不过,这次不同,客户给了我们一些钱让我们保证解决问题。好吧,艺高人胆大,把单子接下了。
事实证明这是个坑。
事实跟我们想象的完全不同。
1)客户用Windows版的FreeSWITCH。我们更熟悉Linux,一般都默认是Linux,在Linux上处理问题一般比Windows上快很多;
2)客户的Windows只能用Teamviewer访问,而Linux如果SSH访问效率会高很多
3)客户使用迅时MX8全FXS口网关,而我们之前一直以为是FXO口网关
4)客户使用SIP中继对接到某运营商,但之前客户根本就没跟我们提到这个问题
5)客户实际上是为客户的客户服务,客户也是用Teamviewer连接到客户的客户的Windows上,而客户的客户描述问题很不清
但骑上虎了也不能轻易就下来,硬新头皮看看。客户一再声称摘机听忙音,但从我们检测后判断是客户拨号后才听忙音的。而且问题原因是SIP中继侧不通,跟迅时网关关系不大。
后来发现,外呼流程是这样的:
客户FSX话机通过迅时呼到FreeSWITCH,FreeSWITCH再通过SIP中继呼出去,而问题就出现在SIP中继方面,FreeSWITCH刚启动时是好的,但过一阵再外呼是就回480,只有重启FreeSWITCH才能恢复正常状态。
后来我们检查了一番,决定不重启FreeSWITCH,而是重新注册一下网关:
sofia profile external register 010-NNNNNNNN
其中010-NNNNNNNN是客户设置的网关的名字。本来是一串数字,保护隐私我们打了马赛克。
果然,注册后呼叫正常。
再查看网关配置,注册周期为默认值,尝试把注册周期改小一点:
告诉客户问题解决了,收工。
此处省力一万字。
客户周末都在上班,也够拼的。
客户说问题并没实际解决,而是出问题的周期缩短了。好像每次自动注册后打电话是好的,很短时间内就不好。
好吧,我们告诉客户,对方回480这么诡异的问题,应该去找对方。
从SIP概念上讲,4开头的响应码是客户端错误,应该在客户端修正然后重新发起呼叫可能就好了。
是的,注意上句中的可能。
我们已经在尝试修正了,比如改User Agent,开启Ping等。问题是这种错误要是有对端配合,可能很快就找到原因改好了,但是,如果对端不配合,你可能需要尝试一万种组合才可能解决问题。
果然,我们所有的尝试都失败了。要知道,这种尝试是非常花费时间的。你改了,必须等待它再次出现,再改,再等……死循环
所以事实往往是很悲催的——对端如果是大运营商的话,你能找到的所有人几乎都不懂技术;对端如果是小的“运营商”(姑且称之为是运营商吧)的话,往往也没有几个是懂技术的,他们往往只会告诉你一句话,人家别人用的都是好的……
说到别人,还真有。后来客户又告诉我们一个线索,人家迅时网关直接用这个SIP中继注册上去,打电话就没有问题!
也算是个线索吧,抓包,对比,直到我们的包改的跟迅时的一模一样我们也是不能解决问题。
而且我们发现迅时发的REGISTER消息Expire域为600,对方回的是60,但我们在FreeSWITCH里也写了600,对方回的就是1800。没头绪。
留给我们的时间已经不多了。
好吧,即然迅时好,那就让迅时做这个工作就好了。
改方案。
直接让迅时注册这个SIP中继。FSX口的话机打电话时,先送到FreeSWITCH,FreeSWITCH再送到迅时,再通过这个中继出去。有点绕,但是这也算是一种解决方案吧。
迅时跟FreeSWITCH对接可以简单的通过IP对接,即将呼叫送到FreeSWITCH的5080端口,不过,这样有点不安全不是。所以,我们需要FSX口发起的电话呼叫到达FreeSWITCH时,FreeSWITCH对迅时网关进行认证。
认证方式有两种:
1)在FreeSWITCH中设置ACL,允许ACL中指定的IP(即迅时网关的IP)呼叫5060端口。这种方式需要改ACL及Profile的一些配置,客户没采用这种方式。
虽然没有采用,我们简单说一下配置方案,供参考。
在ACL中添加迅时的IP。这样,迅时网关过来的呼叫就直接信任,不再发Challenge。但FreeSWITCH默认还是走public Dialplan,可以在internal.xml里设置将默认的 context = public 设成 context = default 以及任何其它值。
2)在FreeSWITCH中添加跟SIP中继网关上一样的用户名和密码,当迅时来的呼叫到达FreeSWITCH 5060端口时发起Challenge,此时,由于迅时注册到远端的SIP中继上,因此会用远端的SIP中继提供的用户名和密码回应FreeSWITCH,即用户010NNNNNNNN和密码PPPPPPPP。
因此,我们就在FreeSWITCH中添加了一个用户,用户名是010NNNNNNNN密码是PPPPPPPP。
这样,迅时网关就能呼叫FreeSWITCH的5060端口并正确的认证(仅在呼叫INVITE时认证,不注册)。
好了,在迅时网关上的路由是这么设的
FXS x ROUTE IP 192.168.1.100 # 任何来自FSX的呼叫都路由到FreeSWITCH
IP 1001 ROUTE FSX 1 # 来自FreeSWITCH的呼到,如果被叫号码是1001,则路由到第一个电话口
IP 1002 ROUTE FSX 2 # 以此类推
IP 1003 ROUTE FSX 3 # 以此类推
IP 1004 ROUTE FSX 4 # 以此类推
IP 1005 ROUTE FSX 5 # 以此类推
IP 1006 ROUTE FSX 6 # 以此类推
IP 1007 ROUTE FSX 7 # 以此类推
IP 1008 ROUTE FSX 8 # 以此类推
IP 010NNNNNNNN ROUTE IP 192.168.1.100:5080 #来自SIP中继的呼叫,如果呼入,则路由到FreeSWITCH,放IVR
IP x ROUTE IP 1.2.3.4 # 其它任何号码都路由到SIP中继网关,以1.2.3.4为例
测试拨打一切正常。
以前,迅时网关是直接注册到FreeSWITCH上的,因此,一个回呼命令类似如下的样子:
originate user/1001 &bridge(sofia/gateway/010-NNNNNNNN/18612345678)
其中,010-NNNNNNNN是SIP中继网关的名字。
但经我们改动后,迅时不再向FreeSWITCH注册,因此没有了本地用户,所以,呼叫命令改成:
originate sofia/gatewayxunshi/1001 &bridge(sofia/gateway/xunshi/18612345678)
其中xunshi时迅时对应的网关的名字。
小结:
- 我们坚持的挂号费是对的,对双方都是有利的
- 不要低估问题的复杂性,显然很多问题也可以分分钟解决,但不可否认,大部分问题都会有意外
- 有些问题不一定非得在FreeSWITCH里解决,本例就是一个例子