[svn-commits] russell: branch 1.4 r203115 - /branches/1.4/channels/chan_sip.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jun 25 11:02:19 CDT 2009


Author: russell
Date: Thu Jun 25 11:02:16 2009
New Revision: 203115

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=203115
Log:
Resolve a crash related to a T.38 reinvite race condition.

This change resolves a crash observed locally during some T.38 testing.
A call was set up using a call file, and when the T.38 reinvite came in,
the channel state was still AST_STATE_DOWN.  The reason is explained by
a comment in the code that previously lived in the handling of
AST_STATE_RINGING.  This change modifies the logic to handle the same
race condition for any channel state that is not UP.

(closes ABE-1895)

Modified:
    branches/1.4/channels/chan_sip.c

Modified: branches/1.4/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/branches/1.4/channels/chan_sip.c?view=diff&rev=203115&r1=203114&r2=203115
==============================================================================
--- branches/1.4/channels/chan_sip.c (original)
+++ branches/1.4/channels/chan_sip.c Thu Jun 25 11:02:16 2009
@@ -14865,7 +14865,23 @@
 
 
 	if (c) {	/* We have a call  -either a new call or an old one (RE-INVITE) */
-		switch(c->_state) {
+		enum ast_channel_state c_state = c->_state;
+
+		if (c_state != AST_STATE_UP && reinvite &&
+			(p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
+			/* If these conditions are true, and the channel is still in the 'ringing'
+			 * state, then this likely means that we have a situation where the initial
+			 * INVITE transaction has completed *but* the channel's state has not yet been
+			 * changed to UP. The reason this could happen is if the reinvite is received
+			 * on the SIP socket prior to an application calling ast_read on this channel
+			 * to read the answer frame we earlier queued on it. In this case, the reinvite
+			 * is completely legitimate so we need to handle this the same as if the channel 
+			 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
+			 */
+			c_state = AST_STATE_UP;
+		}
+
+		switch(c_state) {
 		case AST_STATE_DOWN:
 			if (option_debug > 1)
 				ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
@@ -14937,21 +14953,9 @@
 			p->invitestate = INV_PROCEEDING;
 			break;
 		case AST_STATE_RINGING:
-			if (reinvite && (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
-			/* If these conditions are true, and the channel is still in the 'ringing'
-			 * state, then this likely means that we have a situation where the initial
-			 * INVITE transaction has completed *but* the channel's state has not yet been
-			 * changed to UP. The reason this could happen is if the reinvite is received
-			 * on the SIP socket prior to an application calling ast_read on this channel
-			 * to read the answer frame we earlier queued on it. In this case, the reinvite
-			 * is completely legitimate so we need to handle this the same as if the channel 
-			 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
-			 */
-			} else {
-				transmit_response(p, "180 Ringing", req);
-				p->invitestate = INV_PROCEEDING;
-				break;
-			}
+			transmit_response(p, "180 Ringing", req);
+			p->invitestate = INV_PROCEEDING;
+			break;
 		case AST_STATE_UP:
 			if (option_debug > 1)
 				ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);




More information about the svn-commits mailing list