[asterisk-commits] mmichelson: trunk r397956 - in /trunk: ./ res/res_pjsip_session.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 29 17:25:18 CDT 2013


Author: mmichelson
Date: Thu Aug 29 17:25:16 2013
New Revision: 397956

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=397956
Log:
Fix a race condition where a canceled call was answered.

RFC 5407 section 3.1.2 details a scenario where a UAC sends
a CANCEL at the same time that a UAS sends a 200 OK for the
INVITE that the UAC is canceling. When this occurs, it is the
role of the UAC to immediately send a BYE to terminate
the call.

This scenario was reproducible by have a Digium phone with two lines
place a call to a second phone that forwarded the call to the second
line on the original phone. The Digium phone, upon realizing that it
was connecting to itself, would attempt to cancel the call. The timing
of this happened to trigger the aforementioned race condition about
80% of the time. Asterisk was not doing its job of sending a BYE
when receiving a 200 OK on a cancelled INVITE. The result was that
the ast_channel structure was destroyed but the underlying SIP
session, as well as the PJSIP inv_session and dialog, were still
alive. Attempting to perform an action such as a transfer, once in
this state, would result in Asterisk crashing.

The circumstances are now detected properly and the session is ended
as recommended in RFC 5407.

(closes issue AST-1209)
reported by John Bigelow
........

Merged revisions 397945 from http://svn.asterisk.org/svn/asterisk/branches/12

Modified:
    trunk/   (props changed)
    trunk/res/res_pjsip_session.c

Propchange: trunk/
------------------------------------------------------------------------------
--- branch-12-merged (original)
+++ branch-12-merged Thu Aug 29 17:25:16 2013
@@ -1,1 +1,1 @@
-/branches/12:1-397927,397938,397946
+/branches/12:1-397927,397938,397945-397946

Modified: trunk/res/res_pjsip_session.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_session.c?view=diff&rev=397956&r1=397955&r2=397956
==============================================================================
--- trunk/res/res_pjsip_session.c (original)
+++ trunk/res/res_pjsip_session.c Thu Aug 29 17:25:16 2013
@@ -1868,17 +1868,33 @@
 		break;
 	case PJSIP_EVENT_RX_MSG:
 		if (tsx->method.id == PJSIP_INVITE_METHOD) {
-			if (tsx->role == PJSIP_ROLE_UAC && tsx->state == PJSIP_TSX_STATE_COMPLETED) {
-				/* This means we got a non 2XX final response to our outgoing INVITE */
-				if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
-					reschedule_reinvite(session, tsx->mod_data[session_module.id], tsx->last_tx);
-					return;
-				} else if (inv->state == PJSIP_INV_STATE_CONFIRMED &&
-					   tsx->status_code != 488) {
-					/* Other reinvite failures (except 488) result in destroying the session. */
-					pjsip_tx_data *tdata;
-					if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
-						ast_sip_session_send_request(session, tdata);
+			if (tsx->role == PJSIP_ROLE_UAC) {
+				if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
+					/* This means we got a non 2XX final response to our outgoing INVITE */
+					if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
+						reschedule_reinvite(session, tsx->mod_data[session_module.id], tsx->last_tx);
+						return;
+					} else if (inv->state == PJSIP_INV_STATE_CONFIRMED &&
+						   tsx->status_code != 488) {
+						/* Other reinvite failures (except 488) result in destroying the session. */
+						pjsip_tx_data *tdata;
+						if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
+							ast_sip_session_send_request(session, tdata);
+						}
+					}
+				} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
+					if (inv->cancelling && tsx->status_code == PJSIP_SC_OK) {
+						/* This is a race condition detailed in RFC 5407 section 3.1.2.
+						 * We sent a CANCEL at the same time that the UAS sent us a 200 OK for
+						 * the original INVITE. As a result, we have now received a 200 OK for
+						 * a cancelled call. Our role is to immediately send a BYE to end the
+						 * dialog.
+						 */
+						pjsip_tx_data *tdata;
+
+						if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
+							ast_sip_session_send_request(session, tdata);
+						}
 					}
 				}
 			}




More information about the asterisk-commits mailing list