aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-31 21:31:44 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-31 21:31:44 +0000
commit5d92dd53e619a67f6a7cb35d3c84eab4322c83e0 (patch)
tree3697c15ae359392c284bb0bdacdb76a09a2e2c48
parent9101f1b8e797b3cc45ee890a5f309289c970a3f3 (diff)
Merged revisions 38611 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r38611 | kpfleming | 2006-07-31 16:14:11 -0500 (Mon, 31 Jul 2006) | 4 lines don't reissue hangup requests for SIP channels that have expired their RTP timeouts (one time is enough) don't rescan the SIP private structure list too fast, it can cause channels to not be able to hang up (issue #7495, and probably others) use ast_softhangup_nolock() since we already hold the channel's lock ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@38612 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_sip.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 4c049cbf6..a293c243b 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -14300,41 +14300,61 @@ static void *do_monitor(void *data)
ast_mutex_lock(&iflock);
restartsearch:
t = time(NULL);
- for (sip = iflist; sip; sip = sip->next) {
+ /* don't scan the interface list if it hasn't been a reasonable period
+ of time since the last time we did it (when MWI is being sent, we can
+ get back to this point every millisecond or less)
+ */
+ for (sip = iflist; !fastrestart && sip; sip = sip->next) {
ast_mutex_lock(&sip->lock);
/* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
- if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) {
- if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) {
+ if (sip->rtp && sip->owner &&
+ (sip->owner->_state == AST_STATE_UP) &&
+ !sip->redirip.sin_addr.s_addr) {
+ if (sip->lastrtptx &&
+ sip->rtpkeepalive &&
+ (t > sip->lastrtptx + sip->rtpkeepalive)) {
/* Need to send an empty RTP packet */
sip->lastrtptx = time(NULL);
ast_rtp_sendcng(sip->rtp, 0);
}
- if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) {
+ if (sip->lastrtprx &&
+ (sip->rtptimeout || sip->rtpholdtimeout) &&
+ (t > sip->lastrtprx + sip->rtptimeout)) {
/* Might be a timeout now -- see if we're on hold */
struct sockaddr_in sin;
ast_rtp_get_peer(sip->rtp, &sin);
if (sin.sin_addr.s_addr ||
- (sip->rtpholdtimeout &&
- (t > sip->lastrtprx + sip->rtpholdtimeout))) {
+ (sip->rtpholdtimeout &&
+ (t > sip->lastrtprx + sip->rtpholdtimeout))) {
/* Needs a hangup */
if (sip->rtptimeout) {
- while(sip->owner && ast_channel_trylock(sip->owner)) {
+ while (sip->owner && ast_channel_trylock(sip->owner)) {
ast_mutex_unlock(&sip->lock);
usleep(1);
ast_mutex_lock(&sip->lock);
}
if (sip->owner) {
- ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx));
+ ast_log(LOG_NOTICE,
+ "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
+ sip->owner->name,
+ (long) (t - sip->lastrtprx));
/* Issue a softhangup */
- ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV);
+ ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
ast_channel_unlock(sip->owner);
+ /* forget the timeouts for this call, since a hangup
+ has already been requested and we don't want to
+ repeatedly request hangups
+ */
+ sip->rtptimeout = 0;
+ sip->rtpholdtimeout = 0;
}
}
}
}
}
/* If we have sessions that needs to be destroyed, do it now */
- if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && !sip->owner) {
+ if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
+ !sip->owner) {
ast_mutex_unlock(&sip->lock);
__sip_destroy(sip, 1);
goto restartsearch;