[asterisk-commits] mjordan: branch certified-1.8.11 r375568 - in /certified/branches/1.8.11: ./ ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Oct 31 15:22:31 CDT 2012
Author: mjordan
Date: Wed Oct 31 15:22:19 2012
New Revision: 375568
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375568
Log:
Multiple revisions 369436,369557,369579,369626,369652,372628 for 1.8.11-cert8
........
r369436 | twilson | 2012-06-27 15:58:51 -0500 (Wed, 27 Jun 2012) | 17 lines
AST-2012-010: Clean up after a reinvite that never gets a final response
The basic problem is that if a re-INVITE is sent by Asterisk and it receives a
provisional response, but no final response, then the dialog is never torn
down. In addition to leaking memory, this also leaks file descriptors and will
eventually lead to Asterisk no longer being able to process calls.
This patch just keeps track of whether there is an outstanding re-INVITE, and if
there is goes ahead and cleans up everything as though there was no outstanding
reinvite.
Review: https://reviewboard.asterisk.org/r/2009/
(closes issue ASTERISK-19992)
Reported by: Steve Davies
Tested by: Steve Davies, Terry Wilson
........
r369557 | twilson | 2012-07-03 09:27:02 -0500 (Tue, 03 Jul 2012) | 11 lines
Better handle re-INVITEs with provisional but no final repsonses
A previous attempt at fixing this issue had negative side effects related
to attended transfers which this patch should resolve. Many thanks to
Steve Davies for all of the good suggestions and testing.
(closes issue ASTERISK-19992)
Reported by: Steve Davies
Tested by: Steve Davies, Terry Wilson
Review: https://reviewboard.asterisk.org/r/2009/
........
r369579 | twilson | 2012-07-03 11:58:16 -0500 (Tue, 03 Jul 2012) | 8 lines
More improvements to re-INVITEs timing out after a provisional response
There is no need to call check_pendings() on a final response to an INVITE
when destroying the scheduler entry as it will be done later during normal
processing.
(issue ASTERISK-19992)
........
r369626 | mjordan | 2012-07-05 12:01:52 -0500 (Thu, 05 Jul 2012) | 16 lines
Do not send a BYE when a provisional response arrives during a re-INVITE
Commits r369557 and r369579 were done to improve handling of re-INVITEs
when the UA that was supposed to receive the re-INVITE fails to respond.
A limitation of those patches occurred when a UA sent a provisional
response to the re-INVITE. This triggered a sending of a BYE in
check_pending. This patch tweaks the handling of the re-INVITE such that
a BYE is not sent in response to those messages.
(issue ASTERISK-19992)
Reported by: Steve Davies
Tested by: Steve Davies
patches:
(reinvite_tweak.diff license #5012 by Steve Davies)
........
r369652 | kmoore | 2012-07-05 14:01:52 -0500 (Thu, 05 Jul 2012) | 22 lines
AST-2012-011: Resolve heap corruption issue with voicemail
The heard and deleted arrays in the voicemail state structure were not
handled properly following the memory leak fix in r354890 and a fix for
an invalid free in r356797. This could result in accessing and writing
into freed memory. The allocation for these arrays has been reworked
to avoid the possibility of invalid frees, access of freed memory, and
crashes that were occurring as a result of this.
Locking around accesses and modifications of the voicemail state
structure members dh_arraysize, heard, and deleted has been added to
prevent simultaneous modification and access when IMAP storage is in
use. If IMAP storage is not in use, this locking is not compiled in.
Review: https://reviewboard.asterisk.org/r/1994/
(closes issue ASTERISK-19923)
Reported by: Dan Delaney
Tested by: Dan Delaney, Julian Yap
Patches:
vm_alloc_fix.diff uploaded by kmoore (license 6273)
........
r372628 | rmudgett | 2012-09-07 17:06:29 -0500 (Fri, 07 Sep 2012) | 5 lines
Remove annoying unconditional debug message from INC/DEC functions.
(closes issue AST-1001)
Reported by: Guenther Kelleter
........
Merged revisions 369436,369557,369579,369626,369652,372628 from http://svn.asterisk.org/svn/asterisk/branches/1.8
Modified:
certified/branches/1.8.11/ (props changed)
certified/branches/1.8.11/apps/app_voicemail.c
certified/branches/1.8.11/channels/chan_sip.c
certified/branches/1.8.11/channels/sip/include/sip.h
certified/branches/1.8.11/funcs/func_math.c
Propchange: certified/branches/1.8.11/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.
Modified: certified/branches/1.8.11/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.11/apps/app_voicemail.c?view=diff&rev=375568&r1=375567&r2=375568
==============================================================================
--- certified/branches/1.8.11/apps/app_voicemail.c (original)
+++ certified/branches/1.8.11/apps/app_voicemail.c Wed Oct 31 15:22:19 2012
@@ -1803,24 +1803,27 @@
static int vm_allocate_dh(struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) {
int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg);
- if (!vms->dh_arraysize) {
- /* initial allocation */
+
+ /* remove old allocation */
+ if (vms->deleted) {
+ ast_free(vms->deleted);
+ vms->deleted = NULL;
+ }
+ if (vms->heard) {
+ ast_free(vms->heard);
+ vms->heard = NULL;
+ }
+ vms->dh_arraysize = 0;
+
+ if (arraysize > 0) {
if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) {
return -1;
}
if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) {
+ ast_free(vms->deleted);
+ vms->deleted = NULL;
return -1;
}
- vms->dh_arraysize = arraysize;
- } else if (vms->dh_arraysize < arraysize) {
- if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) {
- return -1;
- }
- if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) {
- return -1;
- }
- memset(vms->deleted, 0, arraysize * sizeof(int));
- memset(vms->heard, 0, arraysize * sizeof(int));
vms->dh_arraysize = arraysize;
}
@@ -6919,9 +6922,15 @@
name = "Unknown Caller";
/* If deleted, show "undeleted" */
-
- if (vms->deleted[vms->curmsg])
- keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
+#ifdef IMAP_STORAGE
+ ast_mutex_lock(&vms->lock);
+#endif
+ if (vms->deleted[vms->curmsg]) {
+ keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
+ }
+#ifdef IMAP_STORAGE
+ ast_mutex_unlock(&vms->lock);
+#endif
/* Except "Exit" */
keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
@@ -6974,8 +6983,15 @@
}
/* If deleted, show "undeleted" */
- if (vms->deleted[vms->curmsg])
+#ifdef IMAP_STORAGE
+ ast_mutex_lock(&vms->lock);
+#endif
+ if (vms->deleted[vms->curmsg]) {
keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
+ }
+#ifdef IMAP_STORAGE
+ ast_mutex_unlock(&vms->lock);
+#endif
/* Except "Exit" */
keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
@@ -8154,8 +8170,12 @@
if (!res) {
make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
+#ifdef IMAP_STORAGE
+ ast_mutex_lock(&vms->lock);
+#endif
vms->heard[vms->curmsg] = 1;
#ifdef IMAP_STORAGE
+ ast_mutex_unlock(&vms->lock);
/*IMAP storage stores any prepended message from a forward
* as a separate file from the rest of the message
*/
@@ -8371,6 +8391,7 @@
}
ast_unlock_path(vms->curdir);
#else /* defined(IMAP_STORAGE) */
+ ast_mutex_lock(&vms->lock);
if (vms->deleted) {
/* Since we now expunge after each delete, deleting in reverse order
* ensures that no reordering occurs between each step. */
@@ -8385,12 +8406,18 @@
#endif
done:
- if (vms->deleted && last_msg_idx) {
+ if (vms->deleted) {
ast_free(vms->deleted);
- }
- if (vms->heard && last_msg_idx) {
+ vms->deleted = NULL;
+ }
+ if (vms->heard) {
ast_free(vms->heard);
- }
+ vms->heard = NULL;
+ }
+ vms->dh_arraysize = 0;
+#ifdef IMAP_STORAGE
+ ast_mutex_unlock(&vms->lock);
+#endif
return 0;
}
@@ -9485,14 +9512,25 @@
res = ast_play_and_wait(chan, "vm-next");
}
if (!res) {
- if (!vms->deleted[vms->curmsg])
+ int curmsg_deleted;
+#ifdef IMAP_STORAGE
+ ast_mutex_lock(&vms->lock);
+#endif
+ curmsg_deleted = vms->deleted[vms->curmsg];
+#ifdef IMAP_STORAGE
+ ast_mutex_unlock(&vms->lock);
+#endif
+ if (!curmsg_deleted) {
res = ast_play_and_wait(chan, "vm-delete");
- else
+ } else {
res = ast_play_and_wait(chan, "vm-undelete");
- if (!res)
+ }
+ if (!res) {
res = ast_play_and_wait(chan, "vm-toforward");
- if (!res)
+ }
+ if (!res) {
res = ast_play_and_wait(chan, "vm-savemessage");
+ }
}
}
if (!res) {
@@ -10685,6 +10723,7 @@
}
vms.starting = 1;
+ vms.curmsg = 0;
break;
case '3': /* Advanced options */
ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu");
Modified: certified/branches/1.8.11/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.11/channels/chan_sip.c?view=diff&rev=375568&r1=375567&r2=375568
==============================================================================
--- certified/branches/1.8.11/channels/chan_sip.c (original)
+++ certified/branches/1.8.11/channels/chan_sip.c Wed Oct 31 15:22:19 2012
@@ -3933,7 +3933,7 @@
ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
append_history(p, "ReliableXmit", "timeout");
if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
- if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
+ if (p->ongoing_reinvite || method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
pvt_set_needdestroy(p, "autodestruct");
}
}
@@ -6304,6 +6304,21 @@
return 0;
}
+static int reinvite_timeout(const void *data)
+{
+ struct sip_pvt *dialog = (struct sip_pvt *) data;
+ struct ast_channel *owner = sip_pvt_lock_full(dialog);
+ dialog->reinviteid = -1;
+ check_pendings(dialog);
+ if (owner) {
+ ast_channel_unlock(owner);
+ ast_channel_unref(owner);
+ }
+ ao2_unlock(dialog);
+ dialog_unref(dialog, "unref for reinvite timeout");
+ return 0;
+}
+
/*! \brief sip_hangup: Hangup SIP call
* Part of PBX interface, called from ast_hangup */
static int sip_hangup(struct ast_channel *ast)
@@ -6503,8 +6518,16 @@
ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);
AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
- if (sip_cancel_destroy(p))
+ if (sip_cancel_destroy(p)) {
ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
+ }
+ /* If we have an ongoing reinvite, there is a chance that we have gotten a provisional
+ * response, but something weird has happened and we will never receive a final response.
+ * So, just in case, check for pending actions after a bit of time to trigger the pending
+ * bye that we are setting above */
+ if (p->ongoing_reinvite && p->reinviteid < 0) {
+ p->reinviteid = ast_sched_add(sched, 32 * p->timer_t1, reinvite_timeout, dialog_ref(p, "ref for reinvite_timeout"));
+ }
}
}
}
@@ -7826,6 +7849,7 @@
p->method = intended_method;
p->initid = -1;
p->waitid = -1;
+ p->reinviteid = -1;
p->autokillid = -1;
p->request_queue_sched_id = -1;
p->provisional_keepalive_sched_id = -1;
@@ -11993,7 +12017,7 @@
initialize_initreq(p, &req);
p->lastinvite = p->ocseq;
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */
-
+ p->ongoing_reinvite = 1;
return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
}
@@ -20149,8 +20173,11 @@
static void check_pendings(struct sip_pvt *p)
{
if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- /* if we can't BYE, then this is really a pending CANCEL */
- if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
+ if (p->reinviteid > -1) {
+ /* Outstanding p->reinviteid timeout, so wait... */
+ return;
+ } else if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
+ /* if we can't BYE, then this is really a pending CANCEL */
p->invitestate = INV_CANCELLED;
transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
/* If the cancel occurred on an initial invite, cancel the pending BYE */
@@ -20161,8 +20188,9 @@
INVITE, but do set an autodestruct just in case we never get it. */
} else {
/* We have a pending outbound invite, don't send something
- new in-transaction */
- if (p->pendinginvite)
+ * new in-transaction, unless it is a pending reinvite, then
+ * by the time we are called here, we should probably just hang up. */
+ if (p->pendinginvite && !p->ongoing_reinvite)
return;
if (p->owner) {
@@ -20402,9 +20430,17 @@
if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
p->invitestate = INV_COMPLETED;
+ if ((resp >= 200 && reinvite)) {
+ p->ongoing_reinvite = 0;
+ if (p->reinviteid > -1) {
+ AST_SCHED_DEL_UNREF(sched, p->reinviteid, dialog_unref(p, "unref dialog for reinvite timeout because of a final response"));
+ }
+ }
+
/* Final response, clear out pending invite */
- if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite)
+ if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) {
p->pendinginvite = 0;
+ }
/* If this is a response to our initial INVITE, we need to set what we can use
* for this peer.
Modified: certified/branches/1.8.11/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.11/channels/sip/include/sip.h?view=diff&rev=375568&r1=375567&r2=375568
==============================================================================
--- certified/branches/1.8.11/channels/sip/include/sip.h (original)
+++ certified/branches/1.8.11/channels/sip/include/sip.h Wed Oct 31 15:22:19 2012
@@ -1073,6 +1073,7 @@
struct sip_auth_container *peerauth;/*!< Realm authentication credentials */
int noncecount; /*!< Nonce-count */
unsigned int stalenonce:1; /*!< Marks the current nonce as responded too */
+ unsigned int ongoing_reinvite:1; /*!< There is a reinvite in progress that might need to be cleaned up */
char lastmsg[256]; /*!< Last Message sent/received */
int amaflags; /*!< AMA Flags */
uint32_t pendinginvite; /*!< Any pending INVITE or state NOTIFY (in subscribe pvt's) ? (seqno of this) */
@@ -1085,6 +1086,7 @@
int initid; /*!< Auto-congest ID if appropriate (scheduler) */
int waitid; /*!< Wait ID for scheduler after 491 or other delays */
+ int reinviteid; /*!< Reinvite in case of provisional, but no final response */
int autokillid; /*!< Auto-kill ID (scheduler) */
int t38id; /*!< T.38 Response ID */
struct sip_refer *refer; /*!< REFER: SIP transfer data structure */
Modified: certified/branches/1.8.11/funcs/func_math.c
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.11/funcs/func_math.c?view=diff&rev=375568&r1=375567&r2=375568
==============================================================================
--- certified/branches/1.8.11/funcs/func_math.c (original)
+++ certified/branches/1.8.11/funcs/func_math.c Wed Oct 31 15:22:19 2012
@@ -421,8 +421,6 @@
modify_orig = 1;
}
- ast_log(LOG_NOTICE, "The value is now: %d\n", int_value);
-
if (snprintf(returnvar, sizeof(returnvar), "%d", int_value) > 0) {
pbx_builtin_setvar_helper(chan, data, returnvar);
if (modify_orig) {
More information about the asterisk-commits
mailing list