java-topology/docs/tickets/asterisk-0001-meetme-conf-find-linear-scan.md

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, MeetmeUnmute action

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_container keyed on confno

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