[asterisk-commits] file: branch 12 r412551 - in /branches/12/res: ./ res_pjsip/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 17 17:49:38 CDT 2014


Author: file
Date: Thu Apr 17 17:49:32 2014
New Revision: 412551

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=412551
Log:
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/

Modified:
    branches/12/res/res_pjsip.c
    branches/12/res/res_pjsip/location.c
    branches/12/res/res_pjsip/pjsip_configuration.c
    branches/12/res/res_pjsip/pjsip_options.c
    branches/12/res/res_pjsip_registrar.c

Modified: branches/12/res/res_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip.c?view=diff&rev=412551&r1=412550&r2=412551
==============================================================================
--- branches/12/res/res_pjsip.c (original)
+++ branches/12/res/res_pjsip.c Thu Apr 17 17:49:32 2014
@@ -2258,6 +2258,18 @@
 	}
 }
 
+/*!
+ * \internal
+ * \brief Reload configuration within a PJSIP thread
+ */
+static int reload_configuration_task(void *obj)
+{
+	ast_res_pjsip_reload_configuration();
+	ast_res_pjsip_init_options_handling(1);
+	ast_sip_initialize_dns();
+	return 0;
+}
+
 static int load_module(void)
 {
 	/* The third parameter is just copied from
@@ -2409,11 +2421,11 @@
 
 static int reload_module(void)
 {
-	if (ast_res_pjsip_reload_configuration()) {
-		return AST_MODULE_LOAD_DECLINE;
-	}
-	ast_res_pjsip_init_options_handling(1);
-	ast_sip_initialize_dns();
+	if (ast_sip_push_task(NULL, reload_configuration_task, NULL)) {
+		ast_log(LOG_WARNING, "Failed to reload PJSIP\n");
+		return -1;
+	}
+
 	return 0;
 }
 

Modified: branches/12/res/res_pjsip/location.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip/location.c?view=diff&rev=412551&r1=412550&r2=412551
==============================================================================
--- branches/12/res/res_pjsip/location.c (original)
+++ branches/12/res/res_pjsip/location.c Thu Apr 17 17:49:32 2014
@@ -255,25 +255,66 @@
 	return 0;
 }
 
+static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags)
+{
+	const struct ast_sip_contact *object_left = obj_left;
+	const struct ast_sip_contact *object_right = obj_right;
+	const char *right_key = obj_right;
+	int cmp;
+
+	switch (flags & OBJ_SEARCH_MASK) {
+	case OBJ_SEARCH_OBJECT:
+		right_key = ast_sorcery_object_get_id(object_right);
+		/* Fall through */
+	case OBJ_SEARCH_KEY:
+		cmp = strcmp(ast_sorcery_object_get_id(object_left), right_key);
+		break;
+	case OBJ_SEARCH_PARTIAL_KEY:
+		/*
+		 * We could also use a partial key struct containing a length
+		 * so strlen() does not get called for every comparison instead.
+		 */
+		cmp = strncmp(ast_sorcery_object_get_id(object_left), right_key, strlen(right_key));
+		break;
+	default:
+		/* Sort can only work on something with a full or partial key. */
+		ast_assert(0);
+		cmp = 0;
+		break;
+	}
+	return cmp;
+}
+
 /*! \brief Custom handler for permanent URIs */
 static int permanent_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
 {
 	struct ast_sip_aor *aor = obj;
-	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
-
-	if (ast_sip_push_task_synchronous(NULL, permanent_contact_validate, (char*)var->value)) {
+	const char *aor_id = ast_sorcery_object_get_id(aor);
+	struct ast_sip_contact *contact;
+	char contact_id[strlen(aor_id) + strlen(var->value) + 2 + 1];
+
+	if (ast_sip_push_task_synchronous(NULL, permanent_contact_validate, (char *) var->value)) {
 		ast_log(LOG_ERROR, "Permanent URI on aor '%s' with contact '%s' failed to parse\n",
-			ast_sorcery_object_get_id(aor), var->value);
-		return -1;
-	}
-
-	if ((!aor->permanent_contacts && !(aor->permanent_contacts = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL))) ||
-		!(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", NULL))) {
-		return -1;
-	}
-
+			aor_id, var->value);
+		return -1;
+	}
+
+	if (!aor->permanent_contacts) {
+		aor->permanent_contacts = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
+			AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, permanent_uri_sort_fn, NULL);
+		if (!aor->permanent_contacts) {
+			return -1;
+		}
+	}
+
+	snprintf(contact_id, sizeof(contact_id), "%s@@%s", aor_id, var->value);
+	contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", contact_id);
+	if (!contact) {
+		return -1;
+	}
 	ast_string_field_set(contact, uri, var->value);
 	ao2_link(aor->permanent_contacts, contact);
+	ao2_ref(contact, -1);
 
 	return 0;
 }

Modified: branches/12/res/res_pjsip/pjsip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip/pjsip_configuration.c?view=diff&rev=412551&r1=412550&r2=412551
==============================================================================
--- branches/12/res/res_pjsip/pjsip_configuration.c (original)
+++ branches/12/res/res_pjsip/pjsip_configuration.c Thu Apr 17 17:49:32 2014
@@ -1817,24 +1817,11 @@
 	ast_sorcery_unref(sip_sorcery);
 }
 
-/*!
- * \internal
- * \brief Reload configuration within a PJSIP thread
- */
-static int reload_configuration_task(void *obj)
+int ast_res_pjsip_reload_configuration(void)
 {
 	if (sip_sorcery) {
 		ast_sorcery_reload(sip_sorcery);
 	}
-	return 0;
-}
-
-int ast_res_pjsip_reload_configuration(void)
-{
-	if (ast_sip_push_task(NULL, reload_configuration_task, NULL)) {
-		ast_log(LOG_WARNING, "Failed to reload PJSIP configuration\n");
-	}
-
 	return 0;
 }
 

Modified: branches/12/res/res_pjsip/pjsip_options.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip/pjsip_options.c?view=diff&rev=412551&r1=412550&r2=412551
==============================================================================
--- branches/12/res/res_pjsip/pjsip_options.c (original)
+++ branches/12/res/res_pjsip/pjsip_options.c Thu Apr 17 17:49:32 2014
@@ -403,14 +403,15 @@
  */
 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 int sched_qualifies_hash_fn(const void *obj, int flags)
 {
-	const struct sched_data *data = obj;
-
-	return ast_str_hash(ast_sorcery_object_get_id(data->contact));
+	const struct sched_data *object;
+	const struct ast_sip_contact *key;
+
+	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 @@
 	if (!(sched_qualifies = ao2_t_container_alloc(
 		QUALIFIED_BUCKETS, sched_qualifies_hash_fn, sched_qualifies_cmp_fn,
 		"Create container for scheduled qualifies"))) {
-
 		return -1;
 	}
 

Modified: branches/12/res/res_pjsip_registrar.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip_registrar.c?view=diff&rev=412551&r1=412550&r2=412551
==============================================================================
--- branches/12/res/res_pjsip_registrar.c (original)
+++ branches/12/res/res_pjsip_registrar.c Thu Apr 17 17:49:32 2014
@@ -159,7 +159,7 @@
 	return ast_tvzero(contact->expiration_time) ? CMP_MATCH : 0;
 }
 
-/*! \brief Internal function used to delete all contacts from an AOR */
+/*! \brief Internal function used to delete a contact from an AOR */
 static int registrar_delete_contact(void *obj, void *arg, int flags)
 {
 	struct ast_sip_contact *contact = obj;




More information about the asterisk-commits mailing list