]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_session: Use distributor serializer for incoming calls. 51/2951/2
authorRichard Mudgett <rmudgett@digium.com>
Fri, 27 May 2016 22:31:52 +0000 (17:31 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Tue, 7 Jun 2016 18:16:19 +0000 (13:16 -0500)
We must continue using the serializer that the original INVITE came in on
for the dialog.  There may be retransmissions already enqueued in the
original serializer that can result in reentrancy and message sequencing
problems.

Outgoing call legs create the pjsip/outsess/<endpoint> serializers for
their dialogs.

ASTERISK-26088
Reported by:  Richard Mudgett

Change-Id: I24d7948749c582b8045d5389ba3f6588508adbbc

include/asterisk/res_pjsip_session.h
res/res_pjsip_session.c

index 75d37ac3d7680c9e9bba767d945177fcdbe00f85..e4c54a173ef9f2a7259111480cc4b296613ba3c5 100644 (file)
@@ -406,9 +406,10 @@ struct ast_sip_channel_pvt *ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_
  * \param endpoint The endpoint that this session communicates with
  * \param contact The contact associated with this session
  * \param inv_session The PJSIP INVITE session data
+ * \param rdata INVITE request received (NULL if for outgoing allocation)
  */
 struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
-       struct ast_sip_contact *contact, pjsip_inv_session *inv);
+       struct ast_sip_contact *contact, pjsip_inv_session *inv, pjsip_rx_data *rdata);
 
 /*!
  * \brief Request and wait for the session serializer to be suspended.
index d66a819d71c92cf94b71b3d94298a3505bd087b8..a4108d566f9e3d8f9d3d99872e33c79ee85c013e 100644 (file)
@@ -1403,12 +1403,11 @@ struct ast_sip_channel_pvt *ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_
 }
 
 struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
-       struct ast_sip_contact *contact, pjsip_inv_session *inv_session)
+       struct ast_sip_contact *contact, pjsip_inv_session *inv_session, pjsip_rx_data *rdata)
 {
        RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
        struct ast_sip_session_supplement *iter;
        int dsp_features = 0;
-       char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
 
        session = ao2_alloc(sizeof(*session), session_destructor);
        if (!session) {
@@ -1429,11 +1428,24 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
        /* fill session->media with available types */
        ao2_callback(sdp_handlers, OBJ_NODATA, add_session_media, session);
 
-       /* Create name with seq number appended. */
-       ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/session/%s",
-               ast_sorcery_object_get_id(endpoint));
+       if (rdata) {
+               /*
+                * We must continue using the serializer that the original
+                * INVITE came in on for the dialog.  There may be
+                * retransmissions already enqueued in the original
+                * serializer that can result in reentrancy and message
+                * sequencing problems.
+                */
+               session->serializer = ast_sip_get_distributor_serializer(rdata);
+       } else {
+               char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
 
-       session->serializer = ast_sip_create_serializer_named(tps_name);
+               /* Create name with seq number appended. */
+               ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outsess/%s",
+                       ast_sorcery_object_get_id(endpoint));
+
+               session->serializer = ast_sip_create_serializer_named(tps_name);
+       }
        if (!session->serializer) {
                return NULL;
        }
@@ -1731,7 +1743,9 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
        timer.sess_expires = endpoint->extensions.timer.sess_expires;
        pjsip_timer_init_session(inv_session, &timer);
 
-       if (!(session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact, inv_session))) {
+       session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact,
+               inv_session, NULL);
+       if (!session) {
                pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
                return NULL;
        }
@@ -2142,7 +2156,7 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
                return;
        }
 
-       session = ast_sip_session_alloc(endpoint, NULL, inv_session);
+       session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
        if (!session) {
                if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
                        pjsip_inv_terminate(inv_session, 500, PJ_FALSE);