diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-12-29 23:08:13 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-12-29 23:08:13 +0000 |
commit | c1d8477cf54d9fd5e6f9902b2c960eb910e71239 (patch) | |
tree | 36add0a14b14a50e60f30758ab2c58180c947401 /channels | |
parent | f1cfb966ccdf499e06cbd388c212042bfe37d3e6 (diff) |
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: http://svn.digium.com/svn/asterisk/branches/1.6.2@236804 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2f4c2e429..e9bb0e3db 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1521,6 +1521,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 */ }; @@ -5491,6 +5492,11 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist) { 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); @@ -5567,6 +5573,7 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist) /* 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, "removing session timer ref")); @@ -22539,25 +22546,34 @@ 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; - stop_session_timer(p); - + if (p->stimer) { + p->stimer->st_schedid = -1; + stop_session_timer(p); + } + /* If we are not asking to be rescheduled, then we need to release our * reference to the dialog. */ dialog_unref(p, "removing session timer ref"); |