summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2012-05-09 16:36:10 +0000
committerMark Michelson <mmichelson@digium.com>2012-05-09 16:36:10 +0000
commit6125190ca125b10f7b829710be230816e9534f64 (patch)
tree8a0e15688454c8d30c6742d48e0d5b8d2bf192dd /channels/chan_sip.c
parentd71d8ed99525f982cb3eaf988f8e8d78fd5bf527 (diff)
Prevent sip_pvt refleak when an ast_channel outlasts its corresponding sip_pvt.
chan_sip was coded under the assumption that a SIP dialog with an owner channel will always be destroyed after the owner channel has been hung up. However, there are situations where the SIP dialog can time out and auto destruct before the corresponding channel has hung up. A typical example of this would be if the 'h' extension in the dialplan takes a long time to complete. In such cases, __sip_autodestruct() would complain about the dialog being auto destroyed with an owner channel still in place. The problem is that even once the owner channel was hung up, the sip_pvt would still be linked in its ao2_container because nothing would ever unlink it. The fix for this is that if __sip_autodestruct() is called for a sip_pvt that still has an owner channel in place, the destruction is rescheduled for 10 seconds in the future. This will continue until the owner channel is finally hung up. (closes issue ASTERISK-19425) reported by David Cunningham Patches: ASTERISK-19425.patch uploaded by Mark Michelson (License #5049) (closes issue ASTERISK-19455) reported by Dean Vesvuio Tested by Dean Vesvuio ........ Merged revisions 365896 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 365898 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@365913 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 17ef07e01..908721ae2 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -3895,16 +3895,17 @@ static int __sip_autodestruct(const void *data)
/* Reset schedule ID */
p->autokillid = -1;
-
/*
* Lock both the pvt and the channel safely so that we can queue up a frame.
*/
owner = sip_pvt_lock_full(p);
if (owner) {
- ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
+ ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s). Rescheduling destruction for 10000 ms\n", p->callid, sip_methods[p->method].text);
ast_queue_hangup_with_cause(owner, AST_CAUSE_PROTOCOL_ERROR);
ast_channel_unlock(owner);
ast_channel_unref(owner);
+ sip_pvt_unlock(p);
+ return 10000;
} else if (p->refer && !p->alreadygone) {
ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
stop_media_flows(p);