FreeSWITCH的limit功能问题汇总

概述
FreeSWITCH的limit功能很好用,但是fs1.6版本中通过hiredis模块实现的limit有不少bug存在。
环境
CentOS 7.9
FreeSWITCH 1.6.20
问题
limit通过mod_hiredis模块实现并发限制的bug。
1,max=-1时,limit逻辑是按照0来实现的
2,hiredis,redis的并发数据为负值时,并发到0时,limit返回失败,呼叫失败
3,hiredis,redis连接中断,limit返回失败,呼叫失败
4,hiredis主备切换时,并发数据有概率为负值
5,线路方对一通呼叫同时返回bye+486消息,挂机回调事件会对limit并发数据decr俩次,引出负值
修复代码
修改mod_hiredis.c文件的“SWITCH_LIMIT_INCR(hiredis_limit_incr)”函数接口如下。
//modify by zr 20250613, for redis reps and max value
count = atoll(response ? response : "");
if (count > 0)
{
limit_pvt = switch_core_alloc(session_pool, sizeof(hiredis_limit_pvt_t));
limit_pvt->next = switch_channel_get_private(channel, "hiredis_limit_pvt");
limit_pvt->realm = switch_core_strdup(session_pool, realm);
limit_pvt->resource = switch_core_strdup(session_pool, resource);
limit_pvt->limit_key = switch_core_strdup(session_pool, limit_key);
limit_pvt->inc = 1;
limit_pvt->interval = interval;
switch_channel_set_private(channel, "hiredis_limit_pvt", limit_pvt);
}
if (!interval && max >= 0 && count > max ) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s is already at max value (%d)\n", limit_key , max);
switch_safe_free(hashkey);
switch_safe_free(response);
hashkey = switch_mprintf("decr %s", limit_key);
if ( (status = hiredis_profile_execute_sync(profile, hashkey, &response, session)) != SWITCH_STATUS_SUCCESS ) {
if ( status == SWITCH_STATUS_SOCKERR && profile->ignore_connect_fail ) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "hiredis: profile[%s] connection error executing [%s] with limit already reached\n", realm, hashkey);
switch_goto_status(SWITCH_STATUS_SUCCESS, done); // increment has been succesful but decrement have failed
}
}
}
// if ( !count || count > max ) {
if ( max >= 0 && count > max ) {
switch_goto_status(SWITCH_STATUS_GENERR, done);
}
总结
修改后的hiredis重新编译安装后,问题解决。
空空如常
求真得真

浙公网安备 33010602011771号