summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2014-11-20 14:49:48 +0000
committerJoshua Colp <jcolp@digium.com>2014-11-20 14:49:48 +0000
commitd25eda5fb232b4cd68a4c1252ba6e70ed5e89ee9 (patch)
tree048c1f211ab222bf14dc5f7923cc6a29ba1988bc
parent57c6f89bf082fafb64800ce49b4da74a9c2d8d9d (diff)
AST-2014-015: Fix race condition in chan_pjsip when sending responses after a CANCEL has been received.
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 ........ Merged revisions 428301 from http://svn.asterisk.org/svn/asterisk/branches/12 ........ Merged revisions 428302 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@428303 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--channels/chan_pjsip.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 96e62a171..77e610ac3 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -489,6 +489,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);
@@ -1001,7 +1006,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);
}
@@ -1053,6 +1059,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) {