summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutomerge script <automerge@asterisk.org>2012-12-12 00:17:36 +0000
committerAutomerge script <automerge@asterisk.org>2012-12-12 00:17:36 +0000
commit7a7f9cba4324d576dfb59519915081793354ecd7 (patch)
treed1d1632a57ec3af79a3e6792554e91bce62e223f
parent686cdd0e79b01bfaf130389a1a948b2dc3d5efb0 (diff)
Merged revisions 377911 via svnmerge from
file:///srv/subversion/repos/asterisk/trunk ................ r377911 | mmichelson | 2012-12-11 18:02:31 -0600 (Tue, 11 Dec 2012) | 22 lines Fix a potential deadlock in chan_sip during transfers. The issue comes from the fact that transfers may perform a redirecting update on a channel. The issue is that lock inversion between the channel and its tech_pvt occurs since the channel lock is released during the transfer process. The fix is to move when the redirecting update occurs to a place where neither the tech_pvt or the channel is locked so that the two can be locked in the proper order. (closes issue ASTERISK-20708) reported by Mark Michelson patches: ASTERISK-20708-3.patch uploaded by Mark Michelson (License #5049) Tested by: Tim Ringenbach at Asteria Solutions Group ........ Merged revisions 377910 from http://svn.asterisk.org/svn/asterisk/branches/11 ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/team/mmichelson/threadpool@377912 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--channels/chan_sip.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index fa70dc807..793e14179 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -26331,6 +26331,24 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, uint
if (!ast_strlen_zero(referred_by)) {
pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", referred_by);
}
+
+ /* When a call is transferred to voicemail from a Digium phone, there may be
+ * a Diversion header present in the REFER with an appropriate reason parameter
+ * set. We need to update the redirecting information appropriately.
+ */
+ ast_channel_lock(p->owner);
+ sip_pvt_lock(p);
+ ast_party_redirecting_init(&redirecting);
+ memset(&update_redirecting, 0, sizeof(update_redirecting));
+ change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE);
+
+ /* Do not hold the pvt lock during a call that causes an indicate or an async_goto.
+ * Those functions lock channels which will invalidate locking order if the pvt lock
+ * is held.*/
+ sip_pvt_unlock(p);
+ ast_channel_unlock(p->owner);
+ ast_channel_update_redirecting(current.chan2, &redirecting, &update_redirecting);
+ ast_party_redirecting_free(&redirecting);
}
sip_pvt_lock(p);
@@ -26378,20 +26396,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, uint
}
ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */
- /* When a call is transferred to voicemail from a Digium phone, there may be
- * a Diversion header present in the REFER with an appropriate reason parameter
- * set. We need to update the redirecting information appropriately.
- */
- ast_party_redirecting_init(&redirecting);
- memset(&update_redirecting, 0, sizeof(update_redirecting));
- change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE);
-
- /* Do not hold the pvt lock during a call that causes an indicate or an async_goto.
- * Those functions lock channels which will invalidate locking order if the pvt lock
- * is held.*/
sip_pvt_unlock(p);
- ast_channel_update_redirecting(current.chan2, &redirecting, &update_redirecting);
- ast_party_redirecting_free(&redirecting);
/* For blind transfers, move the call to the new extensions. For attended transfers on multiple
* servers - generate an INVITE with Replaces. Either way, let the dial plan decided