66 lines
2.2 KiB
Diff
66 lines
2.2 KiB
Diff
# UNDF: UNDF-2026-000000008
|
|
--- a/apps/confbridge/include/confbridge.h
|
|
+++ b/apps/confbridge/include/confbridge.h
|
|
@@ -258,6 +258,10 @@ struct confbridge_conference {
|
|
AST_LIST_HEAD_NOLOCK(, confbridge_user) active_list;
|
|
AST_LIST_HEAD_NOLOCK(, confbridge_user) waiting_list;
|
|
+ /*
|
|
+ * CWE-407 fix: O(1) user lookup by channel name.
|
|
+ * Maintained in sync with active_list + waiting_list.
|
|
+ */
|
|
+ struct ao2_container *users_by_name;
|
|
|
|
--- a/apps/app_confbridge.c
|
|
+++ b/apps/app_confbridge.c
|
|
@@ -conf_bridge_alloc,0 @@
|
|
+ conference->users_by_name = ao2_container_alloc_hash(
|
|
+ AO2_ALLOC_OPT_LOCK_NOLOCK, 0, 127,
|
|
+ user_name_hash_fn, NULL, user_name_cmp_fn);
|
|
|
|
/* On user join — replace list insert + O(n) search with O(1) link */
|
|
- AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
|
|
+ AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
|
|
+ ao2_link(conference->users_by_name, user);
|
|
|
|
/* On user leave */
|
|
- AST_LIST_REMOVE(&conference->active_list, user, list);
|
|
+ AST_LIST_REMOVE(&conference->active_list, user, list);
|
|
+ ao2_unlink(conference->users_by_name, user);
|
|
|
|
/* Replace every AST_LIST_TRAVERSE + strcasecmp pattern: */
|
|
- 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),
|
|
- old_snapshot->base->name) == 0) {
|
|
- found_user = 1;
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
+ user = ao2_find(conference->users_by_name,
|
|
+ old_snapshot->base->name, OBJ_SEARCH_KEY);
|
|
+ found_user = (user != NULL);
|
|
|
|
+static int user_name_hash_fn(const void *obj, const int flags)
|
|
+{
|
|
+ const struct confbridge_user *u = obj;
|
|
+ return flags & OBJ_SEARCH_KEY
|
|
+ ? ast_str_case_hash(obj)
|
|
+ : ast_str_case_hash(ast_channel_name(u->chan));
|
|
+}
|
|
+
|
|
+static int user_name_cmp_fn(void *obj, void *arg, int flags)
|
|
+{
|
|
+ const struct confbridge_user *u = obj;
|
|
+ const char *name = (flags & OBJ_SEARCH_KEY)
|
|
+ ? (const char *)arg
|
|
+ : ast_channel_name(((struct confbridge_user *)arg)->chan);
|
|
+ return strcasecmp(ast_channel_name(u->chan), name) ? 0 : CMP_MATCH | CMP_STOP;
|
|
+}
|