1.8 KiB
asterisk-0001 — app_meetme: find_conf uses AST_LIST_TRAVERSE on global confs linked list
Severity: MEDIUM
CWE: CWE-407 (Inefficient Algorithmic Complexity)
Target: asterisk/asterisk
File: apps/app_meetme.c
Lines: 1493, 1609, 1669, 1773, 1818, 4117, 4311, 4862, 5032, 5092, 5157, 5232, 5370, 5515
Description
The global conference list confs is declared as a linked list:
static AST_LIST_HEAD_STATIC(confs, ast_conference); /* app_meetme.c:948 */
Every call to find_conf() and build_conf() traverses the entire list to
locate a conference by its string conference-number:
/* app_meetme.c:4311 */
AST_LIST_LOCK(&confs);
AST_LIST_TRAVERSE(&confs, cnf, list) {
if (!strcmp(confno, cnf->confno))
break;
}
find_conf() is called:
- Once per new channel joining a conference
- Repeatedly during DTMF menu processing (one call per key press)
- On every AMI
MeetmeList,MeetmeMute,MeetmeUnmuteaction
With C concurrent conferences the lookup cost is O(C) per operation. The
lock (AST_LIST_LOCK) serialises all lookups, making this a global
bottleneck under high call volume.
Complexity
- Before: O(C) locked traversal per conference lookup
- After: O(1) hash lookup using
ao2_containerkeyed onconfno
Fix
Replace AST_LIST_HEAD_STATIC(confs, ast_conference) with an
ao2_container (hashtable) keyed on confno. This matches the pattern
already used in app_confbridge.c for conference_bridges:
/* app_confbridge.c:924 */
return ao2_find(conference_bridges, conference_name, OBJ_KEY);
Provide a hash function on confno string and a compare callback.
Patch
defects/asterisk/patch/asterisk-0001.patch
Test
defects/asterisk/unit/AsteriskTest.java — benchmark ASTERISK_MEETME_CONF_FIND