[asterisk-commits] mmichelson: branch 13 r427841 - in /branches/13: include/asterisk/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Nov 14 08:24:06 CST 2014


Author: mmichelson
Date: Fri Nov 14 08:24:02 2014
New Revision: 427841

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=427841
Log:
Fix race condition where duplicated requests may be handled by multiple threads.

This is the Asterisk 13 version of the patch. The main difference is in the pubsub
code since it was completely refactored between Asterisk 12 and 13.

Review: https://reviewboard.asterisk.org/r/4174


Modified:
    branches/13/include/asterisk/res_pjsip.h
    branches/13/res/res_pjsip.c
    branches/13/res/res_pjsip_pubsub.c
    branches/13/res/res_pjsip_session.c

Modified: branches/13/include/asterisk/res_pjsip.h
URL: http://svnview.digium.com/svn/asterisk/branches/13/include/asterisk/res_pjsip.h?view=diff&rev=427841&r1=427840&r2=427841
==============================================================================
--- branches/13/include/asterisk/res_pjsip.h (original)
+++ branches/13/include/asterisk/res_pjsip.h Fri Nov 14 08:24:02 2014
@@ -1223,8 +1223,9 @@
  *
  * \param endpoint A pointer to the endpoint
  * \param rdata The request that is starting the dialog
- */
-pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
+ * \param[out] status On failure, the reason for failure in creating the dialog
+ */
+pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status);
 
 /*!
  * \brief General purpose method for creating an rdata structure using specific information

Modified: branches/13/res/res_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip.c?view=diff&rev=427841&r1=427840&r2=427841
==============================================================================
--- branches/13/res/res_pjsip.c (original)
+++ branches/13/res/res_pjsip.c Fri Nov 14 08:24:02 2014
@@ -2191,12 +2191,13 @@
 	return dlg;
 }
 
-pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
+pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
 {
 	pjsip_dialog *dlg;
 	pj_str_t contact;
 	pjsip_transport_type_e type = rdata->tp_info.transport->key.type;
-	pj_status_t status;
+
+	ast_assert(status != NULL);
 
 	contact.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
 	contact.slen = pj_ansi_snprintf(contact.ptr, PJSIP_MAX_URL_SIZE,
@@ -2209,11 +2210,11 @@
 			(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
 			(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
 
-	status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg);
-	if (status != PJ_SUCCESS) {
+	*status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg);
+	if (*status != PJ_SUCCESS) {
 		char err[PJ_ERR_MSG_SIZE];
 
-		pj_strerror(status, err, sizeof(err));
+		pj_strerror(*status, err, sizeof(err));
 		ast_log(LOG_ERROR, "Could not create dialog with endpoint %s. %s\n",
 				ast_sorcery_object_get_id(endpoint), err);
 		return NULL;

Modified: branches/13/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_pubsub.c?view=diff&rev=427841&r1=427840&r2=427841
==============================================================================
--- branches/13/res/res_pjsip_pubsub.c (original)
+++ branches/13/res/res_pjsip_pubsub.c Fri Nov 14 08:24:02 2014
@@ -1230,6 +1230,7 @@
  * \param resource The requested resource in the SUBSCRIBE request
  * \param generator The body generator to use in leaf subscriptions
  * \param tree The resource tree on which the subscription tree is based
+ * \param dlg_status[out] The result of attempting to create a dialog.
  *
  * \retval NULL Could not create the subscription tree
  * \retval non-NULL The root of the created subscription tree
@@ -1237,7 +1238,8 @@
 
 static struct sip_subscription_tree *create_subscription_tree(const struct ast_sip_subscription_handler *handler,
 		struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
-		struct ast_sip_pubsub_body_generator *generator, struct resource_tree *tree)
+		struct ast_sip_pubsub_body_generator *generator, struct resource_tree *tree,
+		pj_status_t *dlg_status)
 {
 	struct sip_subscription_tree *sub_tree;
 	pjsip_dialog *dlg;
@@ -1245,13 +1247,16 @@
 
 	sub_tree = allocate_subscription_tree(endpoint);
 	if (!sub_tree) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
 		return NULL;
 	}
 	sub_tree->role = AST_SIP_NOTIFIER;
 
-	dlg = ast_sip_create_dialog_uas(endpoint, rdata);
+	dlg = ast_sip_create_dialog_uas(endpoint, rdata, dlg_status);
 	if (!dlg) {
-		ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
+		if (*dlg_status != PJ_EEXISTS) {
+			ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
+		}
 		ao2_ref(sub_tree, -1);
 		return NULL;
 	}
@@ -1362,7 +1367,9 @@
 	resp = build_resource_tree(endpoint, handler, resource, &tree,
 		ast_sip_pubsub_has_eventlist_support(&rdata));
 	if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
-		sub_tree = create_subscription_tree(handler, endpoint, &rdata, resource, generator, &tree);
+		pj_status_t dlg_status;
+
+		sub_tree = create_subscription_tree(handler, endpoint, &rdata, resource, generator, &tree, &dlg_status);
 		if (!sub_tree) {
 			ast_sorcery_delete(ast_sip_get_sorcery(), persistence);
 			ast_log(LOG_WARNING, "Failed to re-create subscription for %s\n", persistence->endpoint);
@@ -2506,6 +2513,7 @@
 	size_t resource_size;
 	int resp;
 	struct resource_tree tree;
+	pj_status_t dlg_status;
 
 	endpoint = ast_pjsip_rdata_get_endpoint(rdata);
 	ast_assert(endpoint != NULL);
@@ -2570,9 +2578,11 @@
 		return PJ_TRUE;
 	}
 
-	sub_tree = create_subscription_tree(handler, endpoint, rdata, resource, generator, &tree);
+	sub_tree = create_subscription_tree(handler, endpoint, rdata, resource, generator, &tree, &dlg_status);
 	if (!sub_tree) {
-		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		if (dlg_status != PJ_EEXISTS) {
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		}
 	} else {
 		sub_tree->persistence = subscription_persistence_create(sub_tree);
 		subscription_persistence_update(sub_tree, rdata);

Modified: branches/13/res/res_pjsip_session.c
URL: http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_session.c?view=diff&rev=427841&r1=427840&r2=427841
==============================================================================
--- branches/13/res/res_pjsip_session.c (original)
+++ branches/13/res/res_pjsip_session.c Fri Nov 14 08:24:02 2014
@@ -1416,6 +1416,7 @@
 	pjsip_dialog *dlg;
 	pjsip_inv_session *inv_session;
 	unsigned int options = endpoint->extensions.flags;
+	pj_status_t dlg_status;
 
 	if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, ast_sip_get_pjsip_endpoint(), &tdata) != PJ_SUCCESS) {
 		if (tdata) {
@@ -1425,9 +1426,11 @@
 		}
 		return NULL;
 	}
-	dlg = ast_sip_create_dialog_uas(endpoint, rdata);
+	dlg = ast_sip_create_dialog_uas(endpoint, rdata, &dlg_status);
 	if (!dlg) {
-		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		if (dlg_status != PJ_EEXISTS) {
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		}
 		return NULL;
 	}
 	if (pjsip_inv_create_uas(dlg, rdata, NULL, options, &inv_session) != PJ_SUCCESS) {




More information about the asterisk-commits mailing list