diff options
author | Mark Michelson <mmichelson@digium.com> | 2012-05-09 16:36:10 +0000 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2012-05-09 16:36:10 +0000 |
commit | 6125190ca125b10f7b829710be230816e9534f64 (patch) | |
tree | 8a0e15688454c8d30c6742d48e0d5b8d2bf192dd /channels/chan_sip.c | |
parent | d71d8ed99525f982cb3eaf988f8e8d78fd5bf527 (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.c | 5 |
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); |