Author: mmichelson
Date: Fri Nov 14 08:40:17 2014
New Revision: 427842

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

Merged revisions 427841 from http://svn.asterisk.org/svn/asterisk/branches/13

Modified:
    trunk/   (props changed)
    trunk/include/asterisk/res_pjsip.h
    trunk/res/res_pjsip.c
    trunk/res/res_pjsip_pubsub.c
    trunk/res/res_pjsip_session.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-13-merged' - no diff available.

Modified: trunk/include/asterisk/res_pjsip.h
URL: 
http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/res_pjsip.h?view=diff&rev=427842&r1=427841&r2=427842
==============================================================================
--- trunk/include/asterisk/res_pjsip.h (original)
+++ trunk/include/asterisk/res_pjsip.h Fri Nov 14 08:40:17 2014
@@ -1227,8 +1227,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: trunk/res/res_pjsip.c
URL: 
http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip.c?view=diff&rev=427842&r1=427841&r2=427842
==============================================================================
--- trunk/res/res_pjsip.c (original)
+++ trunk/res/res_pjsip.c Fri Nov 14 08:40:17 2014
@@ -2250,12 +2250,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,
@@ -2268,11 +2269,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: trunk/res/res_pjsip_pubsub.c
URL: 
http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_pubsub.c?view=diff&rev=427842&r1=427841&r2=427842
==============================================================================
--- trunk/res/res_pjsip_pubsub.c (original)
+++ trunk/res/res_pjsip_pubsub.c Fri Nov 14 08:40:17 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: trunk/res/res_pjsip_session.c
URL: 
http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_session.c?view=diff&rev=427842&r1=427841&r2=427842
==============================================================================
--- trunk/res/res_pjsip_session.c (original)
+++ trunk/res/res_pjsip_session.c Fri Nov 14 08:40:17 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) {


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to