[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