[asterisk-commits] mmichelson: branch 1.8 r376901 - /branches/1.8/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Nov 30 10:12:11 CST 2012


Author: mmichelson
Date: Fri Nov 30 10:12:07 2012
New Revision: 376901

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=376901
Log:
Fix potential crashes during SIP attended transfers.

The principal behind this patch is simple. During a transfer,
we manipulate channels that are owned by a separate thread than
the one we currently are running in, so it makes sense that we
need to grab a reference to the channels so that they cannot
disappear out from under us.

In the wild, crashes were sometimes seen when the transferring
party would hang up the call before the transfer target answered
the call. The most common place to see the crash occur was when
attempting to send a connected line update to the transferer
channel.

(closes issue ASTERISK-20226)
Reported by Jared Smith
Patches:
	ASTERISK-20226.patch uploaded by Mark Michelson (License #5049)
Tested by: Jared Smith


Modified:
    branches/1.8/channels/chan_sip.c

Modified: branches/1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_sip.c?view=diff&rev=376901&r1=376900&r2=376901
==============================================================================
--- branches/1.8/channels/chan_sip.c (original)
+++ branches/1.8/channels/chan_sip.c Fri Nov 30 10:12:07 2012
@@ -23685,8 +23685,11 @@
 	}
 
 	/* We have a channel, find the bridge */
-	target.chan1 = targetcall_pvt->owner;				/* Transferer to Asterisk */
+	target.chan1 = ast_channel_ref(targetcall_pvt->owner);				/* Transferer to Asterisk */
 	target.chan2 = ast_bridged_channel(targetcall_pvt->owner);	/* Asterisk to target */
+	if (target.chan2) {
+		ast_channel_ref(target.chan2);
+	}
 
 	if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
 		/* Wrong state of new channel */
@@ -23825,6 +23828,10 @@
 	/* at this point if the transfer is successful only the transferer pvt should be locked. */
 	ast_party_connected_line_free(&connected_to_target);
 	ast_party_connected_line_free(&connected_to_transferee);
+	ast_channel_unref(target.chan1);
+	if (target.chan2) {
+		ast_channel_unref(target.chan2);
+	}
 	if (targetcall_pvt)
 		ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt");
 	return 1;




More information about the asterisk-commits mailing list