[asterisk-commits] mmichelson: branch 12 r427840 - in /branches/12: include/asterisk/ res/

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


Author: mmichelson
Date: Fri Nov 14 08:21:55 2014
New Revision: 427840

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=427840
Log:
Fix a possible race condition where duplicate requests may be handled by separate threads.

If an endpoint retransmits a request, it's possible due to temporary load
that Asterisk may end up processing both requests at the same time in separate
threads. One thread will successfully handle the request, while the other thread
fails to handle the request since the first thread already registered the
transaction with the PJSIP core.

The fix here is to detect the duplicated transaction failure and to silently
absorb the request since another thread should be properly handling the request.

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


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

Modified: branches/12/include/asterisk/res_pjsip.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/include/asterisk/res_pjsip.h?view=diff&rev=427840&r1=427839&r2=427840
==============================================================================
--- branches/12/include/asterisk/res_pjsip.h (original)
+++ branches/12/include/asterisk/res_pjsip.h Fri Nov 14 08:21:55 2014
@@ -1228,8 +1228,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/12/res/res_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip.c?view=diff&rev=427840&r1=427839&r2=427840
==============================================================================
--- branches/12/res/res_pjsip.c (original)
+++ branches/12/res/res_pjsip.c Fri Nov 14 08:21:55 2014
@@ -1646,12 +1646,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,
@@ -1664,11 +1665,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/12/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip_pubsub.c?view=diff&rev=427840&r1=427839&r2=427840
==============================================================================
--- branches/12/res/res_pjsip_pubsub.c (original)
+++ branches/12/res/res_pjsip_pubsub.c Fri Nov 14 08:21:55 2014
@@ -122,6 +122,7 @@
 
 #define MOD_DATA_BODY_GENERATOR "sub_body_generator"
 #define MOD_DATA_PERSISTENCE "sub_persistence"
+#define MOD_DATA_DLG_STATUS "dlg_status"
 
 static const pj_str_t str_event_name = { "Event", 5 };
 
@@ -721,6 +722,7 @@
 	struct ast_sip_subscription *sub = ao2_alloc(sizeof(*sub), subscription_destructor);
 	pjsip_dialog *dlg;
 	struct subscription_persistence *persistence;
+	pj_status_t dlg_status;
 
 	if (!sub) {
 		return NULL;
@@ -739,7 +741,9 @@
 			pubsub_module.id, MOD_DATA_BODY_GENERATOR);
 	sub->role = role;
 	if (role == AST_SIP_NOTIFIER) {
-		dlg = ast_sip_create_dialog_uas(endpoint, rdata);
+		dlg = ast_sip_create_dialog_uas(endpoint, rdata, &dlg_status);
+		ast_sip_mod_data_set(rdata->tp_info.pool, rdata->endpt_info.mod_data,
+				pubsub_module.id, MOD_DATA_DLG_STATUS, (void *) dlg_status);
 	} else {
 		RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
 
@@ -1173,7 +1177,10 @@
 			}
 			pjsip_dlg_send_response(dlg, trans, tdata);
 		} else {
-			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+			long dlg_status = (long) ast_sip_mod_data_get(rdata->endpt_info.mod_data, pubsub_module.id, MOD_DATA_DLG_STATUS);
+			if (dlg_status != PJ_EEXISTS) {
+				pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+			}
 		}
 	} else {
 		sub->persistence = subscription_persistence_create(sub);

Modified: branches/12/res/res_pjsip_session.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip_session.c?view=diff&rev=427840&r1=427839&r2=427840
==============================================================================
--- branches/12/res/res_pjsip_session.c (original)
+++ branches/12/res/res_pjsip_session.c Fri Nov 14 08:21:55 2014
@@ -1406,6 +1406,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) {
@@ -1415,9 +1416,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