WRONG_CALL_STATE

 【转自http://www.10tiao.com/html/719/201802/2664614847/1.html

在使用FreeSWITCH的过程中,经常会看到日志中显示WRONG_CALL_STATE,如:

 

2018-02-12 13:00:30.734977 [WARNING]

switch_core_state_machine.c:687

sofia/internal/41@1.2.3.4 Abandoned

 

2018-02-12 13:00:30.734977 [NOTICE]

switch_core_state_machine.c:690

Hangup sofia/internal/41@1.2.3.4

[CS_NEW] [WRONG_CALL_STATE]

 

好多同学都问这个问题,不知道是什么原因。其实,要检查这个问题也很简单,只需要用sofia profile internal siptrace on打开SIP Trace,跟踪下信令就知道原因了。不过,这种事情比较麻烦的是,你不知道它什么时候会出现。

 

好在,FreeSWITCH是开源软件,直接打开源代码查看日志中描述文件的687~690行就好了,大致是这样的:

 

while ((state = switch_channel_get_state(session->channel)) != CS_DESTROY) {

uint32_t new_loops = 500;

 

...

 

if (endstate == CS_NEW) {

switch_yield(20000);

switch_ivr_parse_all_events(session);

if (!--new_loops) {

switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s %s Abandoned\n",

session->uuid_str, switch_core_session_get_name(session));

switch_channel_set_flag(session->channel, CF_NO_CDR);

switch_channel_hangup(session->channel, SWITCH_CAUSE_WRONG_CALL_STATE);

}

} else {

...

}

}

 

 

从代码上看,问题发生在FreeSWITCH的核心状态机,核心状态机是一个循环,里面有个计数器,如果状态机连续有500次处于CS_NEW状态,则打印错误日志WRONG_CALL_STATE,挂机。

 

switch_yield(20000)是等待20毫秒,因为循环500次的时间大约是20毫秒 x 500 = 20000毫秒 = 10秒。

 

从日志中我们倒回10秒查找日志,果然能找到电话初始化时候的日志:

 

2018-02-12 13:00:20.714977 [NOTICE]

switch_channel.c:1104 New Channel sofia/...

 

也就是说,从电话初始化,到释放,Channel的状态一直处于CS_NEW状态,当然至于为什么一直处于这个状态,还得进一步的看代码,那就不好找了。

 

所以,最终分析该分题比较好的方法还是要配合SIP消息进行分析。

 

此处省略5000字 ...

 

好吧,既然我知道这个问题的原因我就不卖关子了。

 

问题的原因在于SIP消息不完整,正常的SIP流程一般是:

 

 

--> 主叫发送INVITE

<-- FreeSWITCH回复100 Trying

<-- 401 需要Challenge 验证

--> ACK

--> 主叫发送带认证信息的INVITE

... 继续

 

 

而此处的问题在于,主叫在收到401后,没有回ACK,或者回了但没有继续发送INVITE消息,也就是,没有按规矩出牌,导致FreeSWITCH一直处于等待状态,10秒后FreeSWITCH超时挂机。

 

如果你的FreeSWITCH服务器部署在公网上,上面的问题多半是来自坏人的攻击,小半是由于NAT问题等导致客户端发送的ACK或INVITE到不了FreeSWITCH,小概率事件是你自己写了个SIP客户端半道崩溃了。

 

具体的SIP消息我这里也没有,大家不妨自己验证下。

 

有的同学说了,怎么验证呢?嗯,就是不好验证所以我才没有SIP消息。因为,大家手头的SIP客户端都是按规矩出牌的,一下子想不按规矩出牌还真不容易做到。

 

有没有工具能发送任意我想要的SIP呢?还真有,你直接用nc,或者sipsak,或sipp都可以发送任意的SIP消息。不过,今天我就写到这里了,有没有人接龙呢?

 


posted on 2019-04-26 14:27  w0z1y  阅读(1212)  评论(1编辑  收藏  举报