
概述
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 reachedn", 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重新编译安装后,问题解决。
空空如常
求真得真