[asterisk-commits] bebuild: tag 11.2.0-rc2 r378785 - in /tags/11.2.0-rc2: ./ apps/ apps/confbrid...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 9 14:43:11 CST 2013


Author: bebuild
Date: Wed Jan  9 14:43:00 2013
New Revision: 378785

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378785
Log:
Merge changes for 11.2.0-rc2

* 378687, 378690, 378036 for ASTERISK-20801
* 378287, 378409 for ASTERISK-20658
* 378582 for ASTERISK-20681
* 378321, 378411 for ASTERISK-20175

Removed:
    tags/11.2.0-rc2/asterisk-11.2.0-rc1-summary.html
    tags/11.2.0-rc2/asterisk-11.2.0-rc1-summary.txt
Modified:
    tags/11.2.0-rc2/   (props changed)
    tags/11.2.0-rc2/.version
    tags/11.2.0-rc2/CHANGES
    tags/11.2.0-rc2/ChangeLog
    tags/11.2.0-rc2/UPGRADE.txt
    tags/11.2.0-rc2/apps/app_confbridge.c
    tags/11.2.0-rc2/apps/app_meetme.c
    tags/11.2.0-rc2/apps/app_queue.c
    tags/11.2.0-rc2/apps/confbridge/conf_state_empty.c
    tags/11.2.0-rc2/channels/chan_agent.c
    tags/11.2.0-rc2/channels/chan_dahdi.c
    tags/11.2.0-rc2/channels/chan_iax2.c
    tags/11.2.0-rc2/channels/chan_local.c
    tags/11.2.0-rc2/channels/chan_sip.c
    tags/11.2.0-rc2/channels/chan_skinny.c
    tags/11.2.0-rc2/channels/sip/include/sip.h
    tags/11.2.0-rc2/configs/queues.conf.sample
    tags/11.2.0-rc2/funcs/func_devstate.c
    tags/11.2.0-rc2/include/asterisk/channel.h
    tags/11.2.0-rc2/include/asterisk/devicestate.h
    tags/11.2.0-rc2/include/asterisk/event_defs.h
    tags/11.2.0-rc2/main/ccss.c
    tags/11.2.0-rc2/main/channel.c
    tags/11.2.0-rc2/main/channel_internal_api.c
    tags/11.2.0-rc2/main/devicestate.c
    tags/11.2.0-rc2/main/event.c
    tags/11.2.0-rc2/main/features.c
    tags/11.2.0-rc2/main/http.c
    tags/11.2.0-rc2/res/pjproject/aconfigure
    tags/11.2.0-rc2/res/pjproject/aconfigure.ac
    tags/11.2.0-rc2/res/pjproject/build/common.mak
    tags/11.2.0-rc2/res/res_calendar.c
    tags/11.2.0-rc2/res/res_jabber.c
    tags/11.2.0-rc2/res/res_xmpp.c

Propchange: tags/11.2.0-rc2/
------------------------------------------------------------------------------
--- branch-1.8-merged (added)
+++ branch-1.8-merged Wed Jan  9 14:43:00 2013
@@ -1,0 +1,1 @@
+/branches/1.8:1-378147,378164,378356,378375,378427,378455-378456,378486,378514,378554,378591

Propchange: tags/11.2.0-rc2/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.

Propchange: tags/11.2.0-rc2/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Wed Jan  9 14:43:00 2013
@@ -1,0 +1,1 @@
+/branches/11:378038,378287,378321,378409-378411,378582,378687,378690

Modified: tags/11.2.0-rc2/.version
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/.version?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/.version (original)
+++ tags/11.2.0-rc2/.version Wed Jan  9 14:43:00 2013
@@ -1,1 +1,1 @@
-11.2.0-rc1
+11.2.0-rc2

Modified: tags/11.2.0-rc2/CHANGES
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/CHANGES?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/CHANGES (original)
+++ tags/11.2.0-rc2/CHANGES Wed Jan  9 14:43:00 2013
@@ -901,8 +901,6 @@
  * Added member option ignorebusy this when set and ringinuse is not
    will allow per member control of multiple calls as ringinuse does for
    the Queue.
- * Added global option check_state_unknown to enforce checking of device state
-   when the device state is unknown app_queue will see unknown as available.
 
 Applications
 ------------

Modified: tags/11.2.0-rc2/ChangeLog
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/ChangeLog?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/ChangeLog (original)
+++ tags/11.2.0-rc2/ChangeLog Wed Jan  9 14:43:00 2013
@@ -1,3 +1,78 @@
+2013-01-09  Asterisk Development Team <asteriskteam at digium.com>
+
+	* Asterisk 11.2.0-rc2 Released.
+
+	* Fix pjproject compilation in certain circumstances.
+
+	  On a fresh checkout of Asterisk 11, running make before ./configure
+	  could cause the pjproject subdirectory to get in an odd state that
+	  would prevent compilation. This patch by Tilghman prevents that from
+	  occurring.
+
+	  (closes issue ASTERISK-20681)
+	  Patch-by: Tilghman Lesher
+
+	* AST-2012-014: Resolve crashes due to large stack allocations when
+	  using TCP
+
+	  Asterisk had several places where messages received over various
+	  network transports may be copied in a single stack allocation. In
+	  the case of TCP, since multiple packets in a stream may be
+	  concatenated together, this can lead to large allocations that
+	  overflow the stack.
+
+	  This patch modifies those portions of Asterisk using TCP to either
+	  favor heap allocations or use an upper bound to ensure that the
+	  stack will not overflow:
+	  * For SIP, the allocation now has an upper limit
+	  * For HTTP, the allocation is now a heap allocation instead of a
+	    stack allocation
+	  * For XMPP, the allocation has been eliminated since it was
+	    unnecessary.
+
+	  This patch contains the fix for both res_jabber and res_xmpp.
+
+	* AST-2012-015: Prevent exhaustion of system resources through
+	  exploitation of event cache 
+
+	  Asterisk maintains an internal cache for devices in the event
+	  subsystem. The device state cache holds the state of each device
+	  known to Asterisk, such that consumers of device state information
+	  can query for the last known state for a particular device, even if
+	  it is not part of an active call. The concept of a device in
+	  Asterisk can include entities that do not have a physical
+	  representation. One way that this occurred was when anonymous calls
+	  are allowed in Asterisk. A device was automatically created and
+	  stored in the cache for each anonymous call that occurred; this was
+	  possible in the SIP and IAX2 channel drivers and through channel
+	  drivers that utilized the res_jabber/res_xmpp resource modules (Gtalk,
+	  Jingle, and Motif). These devices are never removed from the system,
+	  allowing anonymous call to potentially exhaust a system's resources.
+
+	  This patch changes the event cache subsystem and device state
+	  management to no longer cache devices that are not associated with a
+	  physical entity.
+
+	* Revert bad ringinuse=no patch.
+
+	  With the option ringinuse=no set, the patch committed previous for
+	  ASTERISK-16115 causes non-SIP queue members to never be called
+	  because the device state is checked after a channel is created to
+	  determine if the member is busy. These queue members always get the
+	  "Member %s is busy, cannot dial" message.
+
+	  Most channel drivers other than chan_sip use the default device
+	  state handling. The default device state is considered in use or
+	  unknown if the channel exists or not, respectively.
+
+	* Fix multiple calls to a queue member that is only in queue.
+
+	  When ringinuse=no queue members can receive more than one call if
+	  these calls happen at nearly the same time. This patch fixes it so a
+	  queu member does not receive more than one call from a queue. note
+	  that this fix does not prevent multiple calls to a member if hte
+	  member is in more than one queue (see ASTERISK-16115).
+
 2012-12-10  Asterisk Development Team <asteriskteam at digium.com>
 
 	* Asterisk 11.2.0-rc1 Released.

Modified: tags/11.2.0-rc2/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/UPGRADE.txt?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/UPGRADE.txt (original)
+++ tags/11.2.0-rc2/UPGRADE.txt Wed Jan  9 14:43:00 2013
@@ -25,6 +25,9 @@
 * Asterisk has always had code to ignore dash '-' characters that are not
   part of a character set in the dialplan extensions.  The code now
   consistently ignores these characters when matching dialplan extensions.
+
+* Removed the queues.conf check_state_unknown option.  It is no longer
+  necessary.
 
 From 11.0 to 11.1:
 

Modified: tags/11.2.0-rc2/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/apps/app_confbridge.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/apps/app_confbridge.c (original)
+++ tags/11.2.0-rc2/apps/app_confbridge.c Wed Jan  9 14:43:00 2013
@@ -953,7 +953,7 @@
 
 void conf_handle_first_join(struct conference_bridge *conference_bridge)
 {
-	ast_devstate_changed(AST_DEVICE_INUSE, "confbridge:%s", conference_bridge->name);
+	ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference_bridge->name);
 }
 
 void conf_handle_second_active(struct conference_bridge *conference_bridge)

Modified: tags/11.2.0-rc2/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/apps/app_meetme.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/apps/app_meetme.c (original)
+++ tags/11.2.0-rc2/apps/app_meetme.c Wed Jan  9 14:43:00 2013
@@ -2696,7 +2696,7 @@
 
 	/* This device changed state now - if this is the first user */
 	if (conf->users == 1)
-		ast_devstate_changed(AST_DEVICE_INUSE, "meetme:%s", conf->confno);
+		ast_devstate_changed(AST_DEVICE_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
 
 	ast_mutex_unlock(&conf->playlock);
 
@@ -4087,7 +4087,7 @@
 
 		/* Change any states */
 		if (!conf->users) {
-			ast_devstate_changed(AST_DEVICE_NOT_INUSE, "meetme:%s", conf->confno);
+			ast_devstate_changed(AST_DEVICE_NOT_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
 		}
 
  		/* This flag is meant to kill a conference with only one participant remaining.  */
@@ -5582,8 +5582,8 @@
 				|| trunk_ref == exclude)
 				continue;
 			trunk_ref->state = state;
-			ast_devstate_changed(sla_state_to_devstate(state), 
-				"SLA:%s_%s", station->name, trunk->name);
+			ast_devstate_changed(sla_state_to_devstate(state), AST_DEVSTATE_CACHABLE,
+					     "SLA:%s_%s", station->name, trunk->name);
 			break;
 		}
 	}
@@ -6081,8 +6081,8 @@
 {
 	ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
 	event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
-	ast_devstate_changed(AST_DEVICE_ONHOLD, "SLA:%s_%s", 
-		event->station->name, event->trunk_ref->trunk->name);
+	ast_devstate_changed(AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, "SLA:%s_%s",
+			     event->station->name, event->trunk_ref->trunk->name);
 	sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD, 
 		INACTIVE_TRUNK_REFS, event->trunk_ref);
 
@@ -6591,8 +6591,8 @@
 			sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
 		else {
 			trunk_ref->state = SLA_TRUNK_STATE_UP;
-			ast_devstate_changed(AST_DEVICE_INUSE, 
-				"SLA:%s_%s", station->name, trunk_ref->trunk->name);
+			ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE,
+					     "SLA:%s_%s", station->name, trunk_ref->trunk->name);
 		}
 	} else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
 		struct sla_ringing_trunk *ringing_trunk;

Modified: tags/11.2.0-rc2/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/apps/app_queue.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/apps/app_queue.c (original)
+++ tags/11.2.0-rc2/apps/app_queue.c Wed Jan  9 14:43:00 2013
@@ -1042,9 +1042,6 @@
 /*! \brief queues.conf [general] option */
 static int log_membername_as_agent = 0;
 
-/*! \brief queues.conf [general] option */
-static int check_state_unknown = 0;
-
 /*! \brief name of the ringinuse field in the realtime database */
 static char *realtime_ringinuse_field;
 
@@ -1160,6 +1157,7 @@
 	struct call_queue *lastqueue;	     /*!< Last queue we received a call */
 	unsigned int dead:1;                 /*!< Used to detect members deleted in realtime */
 	unsigned int delme:1;                /*!< Flag to delete entry on reload */
+	unsigned int call_pending:1;         /*!< TRUE if the Q is attempting to place a call to the member. */
 	char rt_uniqueid[80];                /*!< Unique id of realtime member entry */
 	unsigned int ringinuse:1;            /*!< Flag to ring queue members even if their status is 'inuse' */
 };
@@ -1787,9 +1785,9 @@
 		if (found_member) {
 			found = 1;
 			if (avail) {
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			} else {
-				ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			}
 		}
 
@@ -2079,7 +2077,7 @@
 	 * AST_DEVICE_INUSE indicates no members are available.
 	 * AST_DEVICE_NOT_INUSE indicates a member is available.
 	 */
-	ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+	ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 }
 
 static void clear_queue(struct call_queue *q)
@@ -2959,7 +2957,7 @@
 		ast_copy_string(qe->context, q->context, sizeof(qe->context));
 		q->count++;
 		if (q->count == 1) {
-			ast_devstate_changed(AST_DEVICE_RINGING, "Queue:%s", q->name);
+			ast_devstate_changed(AST_DEVICE_RINGING, AST_DEVSTATE_CACHABLE, "Queue:%s", q->name);
 		}
 
 		res = 0;
@@ -3267,7 +3265,7 @@
 			char posstr[20];
 			q->count--;
 			if (!q->count) {
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s", q->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s", q->name);
 			}
 
 			/* Take us out of the queue */
@@ -3488,6 +3486,112 @@
 	return vars;
 }
 
+/*!
+ * \internal
+ * \brief Check if the member status is available.
+ *
+ * \param status Member status to check if available.
+ *
+ * \retval non-zero if the member status is available.
+ */
+static int member_status_available(int status)
+{
+	return status == AST_DEVICE_NOT_INUSE || status == AST_DEVICE_UNKNOWN;
+}
+
+/*!
+ * \internal
+ * \brief Clear the member call pending flag.
+ *
+ * \param mem Queue member.
+ *
+ * \return Nothing
+ */
+static void member_call_pending_clear(struct member *mem)
+{
+	ao2_lock(mem);
+	mem->call_pending = 0;
+	ao2_unlock(mem);
+}
+
+/*!
+ * \internal
+ * \brief Set the member call pending flag.
+ *
+ * \param mem Queue member.
+ *
+ * \retval non-zero if call pending flag was already set.
+ */
+static int member_call_pending_set(struct member *mem)
+{
+	int old_pending;
+
+	ao2_lock(mem);
+	old_pending = mem->call_pending;
+	mem->call_pending = 1;
+	ao2_unlock(mem);
+
+	return old_pending;
+}
+
+/*!
+ * \internal
+ * \brief Determine if can ring a queue entry.
+ *
+ * \param qe Queue entry to check.
+ * \param call Member call attempt.
+ *
+ * \retval non-zero if an entry can be called.
+ */
+static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
+{
+	if (call->member->paused) {
+		ast_debug(1, "%s paused, can't receive call\n", call->interface);
+		return 0;
+	}
+
+	if (!call->member->ringinuse && !member_status_available(call->member->status)) {
+		ast_debug(1, "%s not available, can't receive call\n", call->interface);
+		return 0;
+	}
+
+	if ((call->lastqueue && call->lastqueue->wrapuptime && (time(NULL) - call->lastcall < call->lastqueue->wrapuptime))
+		|| (!call->lastqueue && qe->parent->wrapuptime && (time(NULL) - call->lastcall < qe->parent->wrapuptime))) {
+		ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
+			(call->lastqueue ? call->lastqueue->name : qe->parent->name),
+			call->interface);
+		return 0;
+	}
+
+	if (use_weight && compare_weight(qe->parent, call->member)) {
+		ast_debug(1, "Priority queue delaying call to %s:%s\n",
+			qe->parent->name, call->interface);
+		return 0;
+	}
+
+	if (!call->member->ringinuse) {
+		if (member_call_pending_set(call->member)) {
+			ast_debug(1, "%s has another call pending, can't receive call\n",
+				call->interface);
+			return 0;
+		}
+
+		/*
+		 * The queue member is available.  Get current status to be sure
+		 * because the device state and extension state callbacks may
+		 * not have updated the status yet.
+		 */
+		if (!member_status_available(get_queue_member_status(call->member))) {
+			ast_debug(1, "%s actually not available, can't receive call\n",
+				call->interface);
+			member_call_pending_clear(call->member);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
 /*! 
  * \brief Part 2 of ring_one
  *
@@ -3509,60 +3613,17 @@
 	char tech[256];
 	char *location;
 	const char *macrocontext, *macroexten;
-	enum ast_device_state newstate;
 
 	/* on entry here, we know that tmp->chan == NULL */
-	if (tmp->member->paused) {
-		ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
+	if (!can_ring_entry(qe, tmp)) {
 		if (ast_channel_cdr(qe->chan)) {
 			ast_cdr_busy(ast_channel_cdr(qe->chan));
 		}
 		tmp->stillgoing = 0;
-		(*busies)++;
+		++*busies;
 		return 0;
 	}
-
-	if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
-		(!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
-		ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
-				(tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
-		if (ast_channel_cdr(qe->chan)) {
-			ast_cdr_busy(ast_channel_cdr(qe->chan));
-		}
-		tmp->stillgoing = 0;
-		(*busies)++;
-		return 0;
-	}
-
-	if (!tmp->member->ringinuse) {
-		if (check_state_unknown && (tmp->member->status == AST_DEVICE_UNKNOWN)) {
-			newstate = ast_device_state(tmp->member->interface);
-			if (newstate != tmp->member->status) {
-				ast_log(LOG_WARNING, "Found a channel matching iterface %s while status was %s changed to %s\n",
-					tmp->member->interface, ast_devstate2str(tmp->member->status), ast_devstate2str(newstate));
-				ast_devstate_changed_literal(newstate, tmp->member->interface);
-			}
-		}
-		if ((tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
-			ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
-			if (ast_channel_cdr(qe->chan)) {
-				ast_cdr_busy(ast_channel_cdr(qe->chan));
-			}
-			tmp->stillgoing = 0;
-			(*busies)++;
-			return 0;
-		}
-	}
-
-	if (use_weight && compare_weight(qe->parent,tmp->member)) {
-		ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
-		if (ast_channel_cdr(qe->chan)) {
-			ast_cdr_busy(ast_channel_cdr(qe->chan));
-		}
-		tmp->stillgoing = 0;
-		(*busies)++;
-		return 0;
-	}
+	ast_assert(tmp->member->ringinuse || tmp->member->call_pending);
 
 	ast_copy_string(tech, tmp->interface, sizeof(tech));
 	if ((location = strchr(tech, '/'))) {
@@ -3574,18 +3635,18 @@
 	/* Request the peer */
 	tmp->chan = ast_request(tech, ast_channel_nativeformats(qe->chan), qe->chan, location, &status);
 	if (!tmp->chan) {			/* If we can't, just go on to the next call */
-		if (ast_channel_cdr(qe->chan)) {
-			ast_cdr_busy(ast_channel_cdr(qe->chan));
-		}
-		tmp->stillgoing = 0;
-
 		ao2_lock(qe->parent);
-		update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
 		qe->parent->rrpos++;
 		qe->linpos++;
 		ao2_unlock(qe->parent);
 
-		(*busies)++;
+		member_call_pending_clear(tmp->member);
+
+		if (ast_channel_cdr(qe->chan)) {
+			ast_cdr_busy(ast_channel_cdr(qe->chan));
+		}
+		tmp->stillgoing = 0;
+		++*busies;
 		return 0;
 	}
 
@@ -3656,25 +3717,17 @@
 	ast_channel_unlock(tmp->chan);
 	ast_channel_unlock(qe->chan);
 
-	ao2_lock(tmp->member);
-	update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
-	if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
-		ast_verb(1, "Member %s is busy, cannot dial", tmp->member->interface);
-		res = -1;
-	}
-	else {
-		/* Place the call, but don't wait on the answer */
-		res = ast_call(tmp->chan, location, 0);
-	}
-	ao2_unlock(tmp->member);
-	if (res) {
+	/* Place the call, but don't wait on the answer */
+	if ((res = ast_call(tmp->chan, location, 0))) {
 		/* Again, keep going even if there's an error */
 		ast_verb(3, "Couldn't call %s\n", tmp->interface);
 		do_hang(tmp);
-		(*busies)++;
-		update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
+		member_call_pending_clear(tmp->member);
+		++*busies;
 		return 0;
-	} else if (qe->parent->eventwhencalled) {
+	}
+
+	if (qe->parent->eventwhencalled) {
 		char vars[2048];
 
 		ast_channel_lock_both(tmp->chan, qe->chan);
@@ -3730,7 +3783,7 @@
 		ast_verb(3, "Called %s\n", tmp->interface);
 	}
 
-	update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
+	member_call_pending_clear(tmp->member);
 	return 1;
 }
 
@@ -6026,7 +6079,7 @@
 			}
 
 			if (!num_available_members(q)) {
-				ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			}
 
 			res = RES_OKAY;
@@ -6103,7 +6156,7 @@
 				new_member->status, new_member->paused);
 
 			if (is_member_available(new_member)) {
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			}
 
 			ao2_ref(new_member, -1);
@@ -6169,9 +6222,9 @@
 				}
 
 				if (is_member_available(mem)) {
-					ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+					ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 				} else if (!num_available_members(q)) {
-					ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+					ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 				}
 
 				ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));
@@ -7724,10 +7777,6 @@
 	if ((general_val = ast_variable_retrieve(cfg, "general", "log_membername_as_agent"))) {
 		log_membername_as_agent = ast_true(general_val);
 	}
-	check_state_unknown = 0;
-	if ((general_val = ast_variable_retrieve(cfg, "general", "check_state_unknown"))) {
-		check_state_unknown = ast_true(general_val);
-	}
 }
 
 /*! \brief reload information pertaining to a single member
@@ -8505,7 +8554,7 @@
 			while ((mem = ao2_iterator_next(&mem_iter))) {
 				if ((mem->status != AST_DEVICE_UNAVAILABLE) && (mem->status != AST_DEVICE_INVALID)) {
 					++qmemcount;
-					if (((mem->status == AST_DEVICE_NOT_INUSE) || (mem->status == AST_DEVICE_UNKNOWN)) && !(mem->paused)) {
+					if (member_status_available(mem->status) && !mem->paused) {
 						++qmemavail;
 					}
 				}

Modified: tags/11.2.0-rc2/apps/confbridge/conf_state_empty.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/apps/confbridge/conf_state_empty.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/apps/confbridge/conf_state_empty.c (original)
+++ tags/11.2.0-rc2/apps/confbridge/conf_state_empty.c Wed Jan  9 14:43:00 2013
@@ -81,6 +81,6 @@
 static void transition_to_empty(struct conference_bridge_user *cbu)
 {
 	/* Set device state to "not in use" */
-	ast_devstate_changed(AST_DEVICE_NOT_INUSE, "confbridge:%s", cbu->conference_bridge->name);
+	ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", cbu->conference_bridge->name);
 	conf_ended(cbu->conference_bridge);
 }

Modified: tags/11.2.0-rc2/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/channels/chan_agent.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/channels/chan_agent.c (original)
+++ tags/11.2.0-rc2/channels/chan_agent.c Wed Jan  9 14:43:00 2013
@@ -618,7 +618,7 @@
 		if (p->chan) {
 			ast_channel_internal_bridged_channel_set(p->chan, NULL);
 			p->chan = NULL;
-			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 			p->acknowledged = 0;
 		}
 	} else {
@@ -875,7 +875,7 @@
 	} else {
 		/* Agent hung-up */
 		p->chan = NULL;
-		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 	}
 
 	if (!res) {
@@ -995,7 +995,7 @@
 	if (!p->loginstart) {
 		p->logincallerid[0] = '\0';
 	} else {
-		ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+		ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 	}
 
 	if (p->abouttograb) {
@@ -2166,7 +2166,7 @@
 						}
 						ast_mutex_unlock(&p->lock);
 						AST_LIST_UNLOCK(&agents);
-						ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+						ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 						while (res >= 0) {
 							ast_mutex_lock(&p->lock);
 							if (p->deferlogoff && p->chan) {
@@ -2187,7 +2187,7 @@
 								if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0) {
 									ast_debug(1, "Wrapup time for %s expired!\n", p->agent);
 									p->lastdisc = ast_tv(0, 0);
-									ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+									ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 									if (p->ackcall) {
 										check_beep(p, 0);
 									} else {
@@ -2258,7 +2258,7 @@
 						ast_queue_log("NONE", ast_channel_uniqueid(chan), agent, "AGENTLOGOFF", "%s|%ld", ast_channel_name(chan), logintime);
 						ast_verb(2, "Agent '%s' logged out\n", p->agent);
 						/* If there is no owner, go ahead and kill it now */
-						ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+						ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 						if (p->dead && !p->owner) {
 							ast_mutex_destroy(&p->lock);
 							ast_cond_destroy(&p->app_complete_cond);

Modified: tags/11.2.0-rc2/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/channels/chan_dahdi.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/channels/chan_dahdi.c (original)
+++ tags/11.2.0-rc2/channels/chan_dahdi.c Wed Jan  9 14:43:00 2013
@@ -3438,7 +3438,7 @@
 	}
 	if (pri->congestion_devstate != new_state) {
 		pri->congestion_devstate = new_state;
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/congestion", pri->span);
 	}
 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
 	/* Update the span threshold device state and report any change. */
@@ -3454,7 +3454,7 @@
 	}
 	if (pri->threshold_devstate != new_state) {
 		pri->threshold_devstate = new_state;
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/threshold", pri->span);
 	}
 #endif	/* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
 }
@@ -10010,7 +10010,8 @@
 	if (dashptr) {
 		*dashptr = '\0';
 	}
-	ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+	ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+	ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, device_name);
 
 	for (v = i->vars ; v ; v = v->next)
 		pbx_builtin_setvar_helper(tmp, v->name, v->value);

Modified: tags/11.2.0-rc2/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/channels/chan_iax2.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/channels/chan_iax2.c (original)
+++ tags/11.2.0-rc2/channels/chan_iax2.c Wed Jan  9 14:43:00 2013
@@ -5798,7 +5798,7 @@
 }
 
 /*! \brief  Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid)
+static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid, unsigned int cachable)
 {
 	struct ast_channel *tmp;
 	struct chan_iax2_pvt *i;
@@ -5879,6 +5879,10 @@
 		ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
 	i->owner = tmp;
 	i->capability = capability;
+
+	if (!cachable) {
+		ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+	}
 
 	/* Set inherited variables */
 	if (i->vars) {
@@ -8161,7 +8165,7 @@
 		/* if challenge has been sent, but no challenge response if given, reject. */
 		goto return_unref;
 	}
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 
 	/* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
 	res = 0;
@@ -8715,7 +8719,7 @@
 	if (!ast_test_flag64(peer, IAX_TEMPONLY))
 		ast_db_del("IAX/Registry", peer->name);
 	register_peer_exten(peer, 0);
-	ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+	ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 	if (iax2_regfunk)
 		iax2_regfunk(peer->name, 0);
 
@@ -8770,7 +8774,7 @@
 		}
 	}
 
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 
 	p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
 	if (p->expire == -1) {
@@ -8847,14 +8851,14 @@
 					    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 			manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", p->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 			register_peer_exten(p, 1);
-			ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+			ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 		} else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
 			ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
 					    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
 			manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
 			register_peer_exten(p, 0);
 			ast_db_del("IAX/Registry", p->name);
-			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
+			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 		}
 		/* Update the host */
 		/* Verify that the host is really there */
@@ -10420,7 +10424,8 @@
 		    (f.frametype == AST_FRAME_IAX)) {
 			if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
 				ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
-				if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
+				if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
+						  ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
 					ast_variables_destroy(ies.vars);
 					ast_mutex_unlock(&iaxsl[fr->callno]);
 					return 1;
@@ -11062,13 +11067,13 @@
 						if (iaxs[fr->callno]->pingtime <= peer->maxms) {
 							ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
 							manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
-							ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
+							ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 						}
 					} else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
 						if (iaxs[fr->callno]->pingtime > peer->maxms) {
 							ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
 							manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
-							ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+							ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 						}
 					}
 					peer->lastms = iaxs[fr->callno]->pingtime;
@@ -11312,7 +11317,7 @@
 											using_prefs);
 
 							ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
-							if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
+							if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
 								iax2_destroy(fr->callno);
 							else if (ies.vars) {
 								struct ast_datastore *variablestore;
@@ -11383,7 +11388,7 @@
 							iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
 						ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 						send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
-						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
+						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
 							iax2_destroy(fr->callno);
 						else if (ies.vars) {
 							struct ast_datastore *variablestore;
@@ -12150,7 +12155,7 @@
 	if (peer->lastms > -1) {
 		ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
 		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
-		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 	}
 	if ((callno = peer->callno) > 0) {
 		ast_mutex_lock(&iaxsl[callno]);
@@ -12324,7 +12329,8 @@
 		ast_string_field_set(iaxs[callno], host, pds.peer);
 	}
 
-	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL);
+	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL, cai.found);
+
 	ast_mutex_unlock(&iaxsl[callno]);
 
 	if (c) {

Modified: tags/11.2.0-rc2/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/channels/chan_local.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/channels/chan_local.c (original)
+++ tags/11.2.0-rc2/channels/chan_local.c Wed Jan  9 14:43:00 2013
@@ -1266,6 +1266,9 @@
 	ast_channel_tech_pvt_set(tmp, p);
 	ast_channel_tech_pvt_set(tmp2, p);
 
+	ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+	ast_set_flag(ast_channel_flags(tmp2), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+
 	p->owner = tmp;
 	p->chan = tmp2;
 	p->u_owner = ast_module_user_add(p->owner);

Modified: tags/11.2.0-rc2/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/tags/11.2.0-rc2/channels/chan_sip.c?view=diff&rev=378785&r1=378784&r2=378785
==============================================================================
--- tags/11.2.0-rc2/channels/chan_sip.c (original)
+++ tags/11.2.0-rc2/channels/chan_sip.c Wed Jan  9 14:43:00 2013
@@ -2667,19 +2667,20 @@
 			int authenticated, time_t start, struct sip_threadinfo *me)
 {
 	int res, content_length, after_poll = 1, need_poll = 1;
+	size_t datalen = ast_str_strlen(req->data);
 	char buf[1024] = "";
 	int timeout = -1;
-
-	/* Read in headers one line at a time */
-	while (ast_str_strlen(req->data) < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
-		if (!tcptls_session->client && !authenticated) {
-			if ((timeout = sip_check_authtimeout(start)) < 0) {
-				ast_debug(2, "SIP SSL server failed to determine authentication timeout\n");
+ 
+ 	/* Read in headers one line at a time */
+	while (datalen < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
+ 		if (!tcptls_session->client && !authenticated) {
+ 			if ((timeout = sip_check_authtimeout(start)) < 0) {
+				ast_debug(2, "SIP TLS server failed to determine authentication timeout\n");
 				return -1;
 			}
 
 			if (timeout == 0) {
-				ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+				ast_debug(2, "SIP TLS server timed out\n");
 				return -1;
 			}
 		} else {
@@ -2694,11 +2695,11 @@
 			after_poll = 1;
 			res = ast_wait_for_input(tcptls_session->fd, timeout);
 			if (res < 0) {
-				ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+				ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
 				return -1;
 			} else if (res == 0) {
 				/* timeout */
-				ast_debug(2, "SIP TCP server timed out\n");
+				ast_debug(2, "SIP TLS server timed out\n");
 				return -1;
 			}
 		}
@@ -2719,6 +2720,13 @@
 			return -1;
 		}
 		ast_str_append(&req->data, 0, "%s", buf);
+
+		datalen = ast_str_strlen(req->data);
+		if (datalen > SIP_MAX_PACKET_SIZE) {
+			ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+				ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+			return -1;
+		}
 	}
 	copy_request(reqcpy, req);
 	parse_request(reqcpy);
@@ -2732,7 +2740,7 @@
 				}
 
 				if (timeout == 0) {
-					ast_debug(2, "SIP SSL server timed out\n");
+					ast_debug(2, "SIP TLS server timed out\n");
 					return -1;
 				}
 			} else {
@@ -2744,11 +2752,11 @@
 				after_poll = 1;
 				res = ast_wait_for_input(tcptls_session->fd, timeout);
 				if (res < 0) {
-					ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+					ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
 					return -1;
 				} else if (res == 0) {
 					/* timeout */
-					ast_debug(2, "SIP TCP server timed out\n");
+					ast_debug(2, "SIP TLS server timed out\n");
 					return -1;
 				}
 			}
@@ -2771,6 +2779,13 @@
 			}
 			content_length -= strlen(buf);
 			ast_str_append(&req->data, 0, "%s", buf);
+		
+			datalen = ast_str_strlen(req->data);
+			if (datalen > SIP_MAX_PACKET_SIZE) {
+				ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+					ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+				return -1;
+			}
 		}
 	}
 	/*! \todo XXX If there's no Content-Length or if the content-length and what
@@ -2944,6 +2959,8 @@
 	enum message_integrity message_integrity = MESSAGE_FRAGMENT;
 
 	while (message_integrity == MESSAGE_FRAGMENT) {
+		size_t datalen;
+
 		if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
 			char readbuf[4097];
 			int timeout;
@@ -2982,6 +2999,13 @@
 		} else {

[... 1113 lines stripped ...]



More information about the asterisk-commits mailing list