From: Tilghman Lesher Date: Tue, 29 Dec 2009 23:11:00 +0000 (+0000) Subject: Merged revisions 236802 via svnmerge from X-Git-Tag: 1.6.0.21-rc1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d11363f54fc817fe46f96fd3141f2dd4ea18f0d3;p=thirdparty%2Fasterisk.git Merged revisions 236802 via svnmerge from https://origsvn.digium.com/svn/asterisk/trunk ........ r236802 | tilghman | 2009-12-29 17:05:45 -0600 (Tue, 29 Dec 2009) | 7 lines Shut down the SIP session timers more gracefully, in order to prevent a possible crash. (closes issue #16452) Reported by: corruptor Patches: 20091221__issue16452.diff.txt uploaded by tilghman (license 14) Tested by: corruptor ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.0@236805 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 6b843e2348..bbd662ff9e 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1128,6 +1128,7 @@ struct sip_st_dlg { int st_cached_max_se; /*!< Session-Timers cached Session-Expires */ enum st_mode st_cached_mode; /*!< Session-Timers cached M.O. */ enum st_refresher st_cached_ref; /*!< Session-Timers cached refresher */ + unsigned char quit_flag:1; /*!< Stop trying to lock; just quit */ }; @@ -2412,10 +2413,10 @@ static int dialog_cleanup_and_destroy(struct sip_pvt *p) /* Destroy Session-Timers if allocated */ if (p->stimer) { + p->stimer->quit_flag = 1; if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) { - AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, dialog_unref(p)); + AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, if (_count < 10) dialog_unref(p)); } - ast_free(p->stimer); } /* this is the last dialog ref */ dialog_unref(p); @@ -4643,6 +4644,11 @@ static int __sip_destroy(struct sip_pvt *p, int lockowner) struct sip_pkt *cp; struct sip_request *req; + if (p->stimer) { + ast_free(p->stimer); + p->stimer = NULL; + } + if (sip_debug_test_pvt(p)) ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); @@ -20352,22 +20358,32 @@ static int proc_session_timer(const void *vp) } else { p->stimer->st_expirys++; if (p->stimer->st_expirys >= 2) { + if (p->stimer->quit_flag) { + goto return_unref; + } ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); + sip_pvt_lock(p); while (p->owner && ast_channel_trylock(p->owner)) { sip_pvt_unlock(p); usleep(1); + if (p->stimer && p->stimer->quit_flag) { + goto return_unref; + } sip_pvt_lock(p); } ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); ast_channel_unlock(p->owner); + sip_pvt_unlock(p); } } return_unref: if (!res) { /* An error occurred. Stop session timer processing */ - p->stimer->st_schedid = -1; /* this is the sched, so this is safe */ - stop_session_timer(p); /* will not unref, only mark st_active FALSE */ + if (p->stimer) { + p->stimer->st_schedid = -1; /* this is the sched, so this is safe */ + stop_session_timer(p); /* will not unref, only mark st_active FALSE */ + } /* If we are not asking to be rescheduled, then we need to release our * reference to the dialog. */