mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-22 20:56:39 +00:00
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
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user