]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2014-015: Fix race condition in chan_pjsip when sending responses after a CANCEL...
authorJoshua Colp <jcolp@digium.com>
Thu, 20 Nov 2014 14:48:32 +0000 (14:48 +0000)
committerJoshua Colp <jcolp@digium.com>
Thu, 20 Nov 2014 14:48:32 +0000 (14:48 +0000)
Due to the serialized architecture of chan_pjsip there exists a race condition where a CANCEL may
be received and processed before responses (such as 180 Ringing, 183 Session Progress, and 200 OK)
are sent. Since the session is in an unexpected state PJSIP will assert when this is attempted.

This change makes it so that these responses are not sent on disconnected sessions.

ASTERISK-24471 #close
Reported by: yaron nahum

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@428301 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_pjsip.c

index 4c3f9c65a86848a6ed3676c4f21d9c8c6283d7b5..26eb421b968901b3343385fd6de1160aaebb56ce 100644 (file)
@@ -467,6 +467,11 @@ static int answer(void *data)
        pjsip_tx_data *packet = NULL;
        struct ast_sip_session *session = data;
 
+       if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
+               ao2_ref(session, -1);
+               return 0;
+       }
+
        pjsip_dlg_inc_lock(session->inv_session->dlg);
        if (session->inv_session->invite_tsx) {
                status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet);
@@ -966,7 +971,8 @@ static int indicate(void *data)
        struct ast_sip_session *session = ind_data->session;
        int response_code = ind_data->response_code;
 
-       if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
+       if ((session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
+               (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
                ast_sip_session_send_response(session, packet);
        }
 
@@ -1018,6 +1024,10 @@ static int update_connected_line_information(void *data)
        if ((ast_channel_state(session->channel) != AST_STATE_UP) && (session->inv_session->role == PJSIP_UAS_ROLE)) {
                int response_code = 0;
 
+               if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
+                       return 0;
+               }
+
                if (ast_channel_state(session->channel) == AST_STATE_RING) {
                        response_code = !session->endpoint->inband_progress ? 180 : 183;
                } else if (ast_channel_state(session->channel) == AST_STATE_RINGING) {