java-topology/defects/asterisk/patch/asterisk-0002.patch

65 lines
2.2 KiB
Diff

--- 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;
+}