summaryrefslogtreecommitdiff
path: root/res/res_pjsip/pjsip_options.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2014-04-17 22:50:23 +0000
committerJoshua Colp <jcolp@digium.com>2014-04-17 22:50:23 +0000
commit1a9ff2fffbb8102751b20971a08df1453df60f98 (patch)
tree03c9baafa0a8c25e82cb3fc63dcee0106552a9d9 /res/res_pjsip/pjsip_options.c
parentc76608f24b1561ae9faff484381433df06631713 (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.c61
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;
}