diff options
author | Joshua Colp <jcolp@digium.com> | 2014-04-17 22:50:23 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2014-04-17 22:50:23 +0000 |
commit | 1a9ff2fffbb8102751b20971a08df1453df60f98 (patch) | |
tree | 03c9baafa0a8c25e82cb3fc63dcee0106552a9d9 /res/res_pjsip/pjsip_options.c | |
parent | c76608f24b1561ae9faff484381433df06631713 (diff) |
res_pjsip: Handle reloading when permanent contacts exist and qualify is configured.
This change fixes a problem where permanent contacts being qualified were not
being updated. This was caused by the permanent contacts getting a uuid and not a
known identifier, causing an inability to look them up when updating in the
qualify code. A bug also existed where the new configuration may not be available
immediately when updating qualifies.
(closes issue ASTERISK-23514)
Reported by: Richard Mudgett
Review: https://reviewboard.asterisk.org/r/3448/
........
Merged revisions 412551 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@412552 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip/pjsip_options.c')
-rw-r--r-- | res/res_pjsip/pjsip_options.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index 461e5534a..a8c603e1c 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -403,14 +403,15 @@ static void schedule_qualify(struct ast_sip_contact *contact) */ static void unschedule_qualify(struct ast_sip_contact *contact) { - RAII_VAR(struct sched_data *, data, ao2_find( - sched_qualifies, contact, OBJ_UNLINK), ao2_cleanup); + struct sched_data *data; + data = ao2_find(sched_qualifies, contact, OBJ_UNLINK | OBJ_SEARCH_KEY); if (!data) { return; } AST_SCHED_DEL_UNREF(sched, data->id, ao2_cleanup(data)); + ao2_ref(data, -1); } /*! @@ -778,17 +779,60 @@ static struct ast_cli_entry cli_options[] = { static int sched_qualifies_hash_fn(const void *obj, int flags) { - const struct sched_data *data = obj; + const struct sched_data *object; + const struct ast_sip_contact *key; - return ast_str_hash(ast_sorcery_object_get_id(data->contact)); + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_KEY: + key = obj; + break; + case OBJ_SEARCH_OBJECT: + object = obj; + key = object->contact; + break; + default: + /* Hash can only work on something with a full key. */ + ast_assert(0); + return 0; + } + return ast_str_hash(ast_sorcery_object_get_id(key)); } static int sched_qualifies_cmp_fn(void *obj, void *arg, int flags) { - struct sched_data *data = obj; - - return !strcmp(ast_sorcery_object_get_id(data->contact), - ast_sorcery_object_get_id(arg)); + const struct sched_data *object_left = obj; + const struct sched_data *object_right = arg; + struct ast_sip_contact *right_key = arg; + int cmp; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_OBJECT: + right_key = object_right->contact; + /* Fall through */ + case OBJ_SEARCH_KEY: + cmp = strcmp(ast_sorcery_object_get_id(object_left->contact), + ast_sorcery_object_get_id(right_key)); + break; + case OBJ_SEARCH_PARTIAL_KEY: + /* Not supported by container. */ + ast_assert(0); + return 0; + default: + /* + * What arg points to is specific to this traversal callback + * and has no special meaning to astobj2. + */ + cmp = 0; + break; + } + if (cmp) { + return 0; + } + /* + * At this point the traversal callback is identical to a sorted + * container. + */ + return CMP_MATCH; } int ast_sip_initialize_sorcery_qualify(void) @@ -884,7 +928,6 @@ int ast_res_pjsip_init_options_handling(int reload) if (!(sched_qualifies = ao2_t_container_alloc( QUALIFIED_BUCKETS, sched_qualifies_hash_fn, sched_qualifies_cmp_fn, "Create container for scheduled qualifies"))) { - return -1; } |