# asterisk-0002 — app_confbridge: active_list/waiting_list have no channel-name index **Severity:** MEDIUM **CWE:** CWE-407 (Inefficient Algorithmic Complexity) **Target:** asterisk/asterisk **File:** `apps/app_confbridge.c`, `apps/confbridge/include/confbridge.h` **Lines:** confbridge.h:260-261, app_confbridge.c:1757, 1768, 3387, 3468, 3687 ## Description `confbridge_conference` stores participants as two plain linked lists: ```c /* confbridge.h:260-261 */ AST_LIST_HEAD_NOLOCK(, confbridge_user) active_list; AST_LIST_HEAD_NOLOCK(, confbridge_user) waiting_list; ``` Every operation that identifies a user by channel name (kick, mute, unmute, video-source selection, AMI/ARI events) traverses the entire list: ```c /* app_confbridge.c:1757-1776 */ AST_LIST_TRAVERSE(&conference->active_list, user, list) { if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) { found_user = 1; break; } } if (!found_user && conference->waitingusers) { AST_LIST_TRAVERSE(&conference->waiting_list, user, list) { if (strcasecmp(ast_channel_name(user->chan), ...) == 0) { ... } } } ``` There are at least 12 traversal sites in `app_confbridge.c`. In a conference with P participants each AMI/ARI kick/mute costs O(P). A conference of 500 participants (common for webinar/town-hall use cases) with frequent moderator actions creates quadratic work per conference. ## Complexity - **Before:** O(P) per user-by-name lookup across P participants - **After:** O(1) with an `ao2_container` keyed on channel name ## Fix Add an `ao2_container *users_by_name` field to `confbridge_conference`, keyed on `ast_channel_name(user->chan)`. Link/unlink on join/leave. Replace all `AST_LIST_TRAVERSE` + `strcasecmp` patterns with a single `ao2_find(conference->users_by_name, channel_name, OBJ_SEARCH_KEY)`. ## Patch `defects/asterisk/patch/asterisk-0002.patch` ## Test `defects/asterisk/unit/AsteriskTest.java` — benchmark `ASTERISK_CONFBRIDGE_USER_FIND`