[asterisk-commits] mjordan: branch 1.8 r378303 - in /branches/1.8: apps/ channels/ funcs/ includ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jan 2 10:54:28 CST 2013
Author: mjordan
Date: Wed Jan 2 10:54:20 2013
New Revision: 378303
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378303
Log:
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 calls 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.
(issue ASTERISK-20175)
Reported by: Russell Bryant, Leif Madsen, Joshua Colp
Tested by: kmoore
patches:
event-cachability-3.diff uploaded by jcolp (license 5000)
Modified:
branches/1.8/apps/app_confbridge.c
branches/1.8/apps/app_meetme.c
branches/1.8/channels/chan_agent.c
branches/1.8/channels/chan_dahdi.c
branches/1.8/channels/chan_iax2.c
branches/1.8/channels/chan_local.c
branches/1.8/channels/chan_sip.c
branches/1.8/channels/chan_skinny.c
branches/1.8/funcs/func_devstate.c
branches/1.8/include/asterisk/channel.h
branches/1.8/include/asterisk/devicestate.h
branches/1.8/include/asterisk/event_defs.h
branches/1.8/main/channel.c
branches/1.8/main/devicestate.c
branches/1.8/main/event.c
branches/1.8/main/features.c
branches/1.8/res/res_calendar.c
branches/1.8/res/res_jabber.c
Modified: branches/1.8/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/apps/app_confbridge.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/apps/app_confbridge.c (original)
+++ branches/1.8/apps/app_confbridge.c Wed Jan 2 10:54:20 2013
@@ -486,7 +486,7 @@
/* Set the device state for this conference */
if (conference_bridge->users == 1) {
- 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);
}
/* If the caller is a marked user or is waiting for a marked user to enter pass 'em off, otherwise pass them off to do regular joining stuff */
@@ -568,7 +568,7 @@
}
} else {
/* Set device state to "not in use" */
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "confbridge:%s", conference_bridge->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference_bridge->name);
ao2_unlink(conference_bridges, conference_bridge);
}
Modified: branches/1.8/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/apps/app_meetme.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/apps/app_meetme.c (original)
+++ branches/1.8/apps/app_meetme.c Wed Jan 2 10:54:20 2013
@@ -2576,7 +2576,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);
@@ -3884,7 +3884,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);
}
/* Return the number of seconds the user was in the conf */
@@ -5303,8 +5303,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;
}
}
@@ -5802,8 +5802,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);
@@ -6312,8 +6312,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: branches/1.8/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_agent.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/channels/chan_agent.c (original)
+++ branches/1.8/channels/chan_agent.c Wed Jan 2 10:54:20 2013
@@ -618,7 +618,7 @@
if (p->chan) {
p->chan->_bridge = 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) {
@@ -994,7 +994,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) {
@@ -2138,7 +2138,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) {
@@ -2159,7 +2159,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 {
@@ -2219,7 +2219,7 @@
ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGOFF", "%s|%ld", chan->name, 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: branches/1.8/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_dahdi.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/channels/chan_dahdi.c (original)
+++ branches/1.8/channels/chan_dahdi.c Wed Jan 2 10:54:20 2013
@@ -3364,7 +3364,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. */
@@ -3380,7 +3380,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) */
}
@@ -9804,7 +9804,8 @@
if (dashptr) {
*dashptr = '\0';
}
- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+ tmp->flags |= 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: branches/1.8/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_iax2.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/channels/chan_iax2.c (original)
+++ branches/1.8/channels/chan_iax2.c Wed Jan 2 10:54:20 2013
@@ -5729,7 +5729,7 @@
}
/*! \brief Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
+static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid, unsigned int cachable)
{
struct ast_channel *tmp;
struct chan_iax2_pvt *i;
@@ -5797,6 +5797,10 @@
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
i->owner = tmp;
i->capability = capability;
+
+ if (!cachable) {
+ tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+ }
/* Set inherited variables */
if (i->vars) {
@@ -8084,7 +8088,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;
@@ -8638,7 +8642,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);
@@ -8693,7 +8697,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) {
@@ -8770,14 +8774,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\n", p->name);
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 */
@@ -10291,7 +10295,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;
@@ -10924,13 +10929,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;
@@ -11172,7 +11177,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;
@@ -11243,7 +11248,7 @@
ast_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;
@@ -11996,7 +12001,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]);
@@ -12164,7 +12169,7 @@
if (cai.found)
ast_string_field_set(iaxs[callno], host, pds.peer);
- c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
+ c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
ast_mutex_unlock(&iaxsl[callno]);
Modified: branches/1.8/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_local.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/channels/chan_local.c (original)
+++ branches/1.8/channels/chan_local.c Wed Jan 2 10:54:20 2013
@@ -1229,6 +1229,9 @@
tmp->tech_pvt = p;
tmp2->tech_pvt = p;
+ tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+ tmp2->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+
p->owner = tmp;
p->chan = tmp2;
Modified: branches/1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_sip.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/channels/chan_sip.c (original)
+++ branches/1.8/channels/chan_sip.c Wed Jan 2 10:54:20 2013
@@ -6418,7 +6418,7 @@
}
if (p) {
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name);
unref_peer(p, "update_call_counter: unref_peer from call counter");
}
return 0;
@@ -7609,6 +7609,9 @@
if (i->rtp)
ast_jb_configure(tmp, &global_jbconf);
+ if (!i->relatedpeer) {
+ tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+ }
/* Set channel variables for this call from configuration */
for (v = i->chanvars ; v ; v = v->next) {
char valuebuf[1024];
@@ -14221,7 +14224,7 @@
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
register_peer_exten(peer, FALSE); /* Remove regexten */
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
/* Do we need to release this peer from memory?
Only for realtime peers and autocreated peers
@@ -15003,8 +15006,9 @@
ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1));
/* Request device state update */
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->relatedpeer->name);
-
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE),
+ "SIP/%s", p->relatedpeer->name);
+
return;
}
@@ -15422,7 +15426,7 @@
} else {
update_peer_lastmsgssent(peer, -1, 0);
}
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
}
if (res < 0) {
switch (res) {
@@ -21414,7 +21418,7 @@
ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
peer->name, s, pingtime, peer->maxms);
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
if (sip_cfg.peer_rtupdate) {
ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
}
@@ -26870,7 +26874,7 @@
/* Don't send a devstate change if nothing changed. */
if (peer->lastms > -1) {
peer->lastms = -1;
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
}
/* Try again quickly */
Modified: branches/1.8/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_skinny.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/channels/chan_skinny.c (original)
+++ branches/1.8/channels/chan_skinny.c Wed Jan 2 10:54:20 2013
@@ -1925,7 +1925,7 @@
register_exten(l);
/* initialize MWI on line and device */
mwi_event_cb(0, l);
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
}
--instance;
}
@@ -1963,7 +1963,7 @@
l->instance = 0;
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
}
}
}
@@ -5321,7 +5321,7 @@
ast_verb(1, "RECEIVED UNKNOWN STIMULUS: %d(%d/%d)\n", event, instance, callreference);
break;
}
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
return 1;
}
@@ -5372,7 +5372,7 @@
transmit_ringer_mode(d, SKINNY_RING_OFF);
l->hookstate = SKINNY_OFFHOOK;
- ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
if (sub && sub->onhold) {
return 1;
@@ -5448,7 +5448,7 @@
return 0;
}
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
if (sub->onhold) {
return 0;
@@ -5834,7 +5834,7 @@
return 0;
}
- ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
switch(event) {
case SOFTKEY_NONE:
@@ -6049,7 +6049,7 @@
transmit_callstate(d, l->instance, sub->callid, l->hookstate);
}
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
if (skinnydebug)
ast_verb(1, "Skinny %s@%s went on hook\n", l->name, d->name);
if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) {
@@ -6073,7 +6073,7 @@
}
}
if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
}
}
break;
Modified: branches/1.8/funcs/func_devstate.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/funcs/func_devstate.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/funcs/func_devstate.c (original)
+++ branches/1.8/funcs/func_devstate.c Wed Jan 2 10:54:20 2013
@@ -132,7 +132,7 @@
ast_db_put(astdb_family, data, value);
- ast_devstate_changed(state_val, "Custom:%s", data);
+ ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", data);
return 0;
}
@@ -295,7 +295,7 @@
ast_db_put(astdb_family, dev, state);
- ast_devstate_changed(state_val, "Custom:%s", dev);
+ ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", dev);
return CLI_SUCCESS;
}
@@ -341,7 +341,7 @@
if (dev_name <= (const char *) 1)
continue;
ast_devstate_changed(ast_devstate_val(db_entry->data),
- "Custom:%s\n", dev_name);
+ AST_DEVSTATE_CACHABLE, "Custom:%s\n", dev_name);
}
ast_db_freetree(db_tree);
db_tree = NULL;
Modified: branches/1.8/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/channel.h?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/include/asterisk/channel.h (original)
+++ branches/1.8/include/asterisk/channel.h Wed Jan 2 10:54:20 2013
@@ -938,6 +938,12 @@
* some non-traditional dialplans (like AGI) to continue to function.
*/
AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20),
+ /*! Disable device state event caching. This allows allows channel
+ * drivers to selectively prevent device state events from being cached
+ * by certain channels such as anonymous calls which have no persistent
+ * represenatation that can be tracked.
+ */
+ AST_FLAG_DISABLE_DEVSTATE_CACHE = (1 << 21),
};
/*! \brief ast_bridge_config flags */
Modified: branches/1.8/include/asterisk/devicestate.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/devicestate.h?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/include/asterisk/devicestate.h (original)
+++ branches/1.8/include/asterisk/devicestate.h Wed Jan 2 10:54:20 2013
@@ -61,6 +61,14 @@
AST_DEVICE_TOTAL, /*/ Total num of device states, used for testing */
};
+/*! \brief Device State Cachability
+ * \note This is used to define the cachability of a device state when set.
+ */
+enum ast_devstate_cache {
+ AST_DEVSTATE_NOT_CACHABLE, /*!< This device state is not cachable */
+ AST_DEVSTATE_CACHABLE, /*!< This device state is cachable */
+};
+
/*! \brief Devicestate provider call back */
typedef enum ast_device_state (*ast_devstate_prov_cb_type)(const char *data);
@@ -129,6 +137,7 @@
* \brief Tells Asterisk the State for Device is changed
*
* \param state the new state of the device
+ * \param cachable whether this device state is cachable
* \param fmt device name like a dial string with format parameters
*
* The new state of the device will be sent off to any subscribers
@@ -138,13 +147,14 @@
* \retval 0 on success
* \retval -1 on failure
*/
-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));
+int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
+ __attribute__((format(printf, 3, 4)));
/*!
* \brief Tells Asterisk the State for Device is changed
*
* \param state the new state of the device
+ * \param cachable whether this device state is cachable
* \param device device name like a dial string with format parameters
*
* The new state of the device will be sent off to any subscribers
@@ -154,7 +164,7 @@
* \retval 0 on success
* \retval -1 on failure
*/
-int ast_devstate_changed_literal(enum ast_device_state state, const char *device);
+int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device);
/*!
* \brief Tells Asterisk the State for Device is changed.
Modified: branches/1.8/include/asterisk/event_defs.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/event_defs.h?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/include/asterisk/event_defs.h (original)
+++ branches/1.8/include/asterisk/event_defs.h Wed Jan 2 10:54:20 2013
@@ -283,8 +283,14 @@
AST_EVENT_IE_CHALLENGE = 0x0032,
AST_EVENT_IE_RESPONSE = 0x0033,
AST_EVENT_IE_EXPECTED_RESPONSE = 0x0034,
+ /*!
+ * \brief Event non-cachability flag
+ * Used by: All events
+ * Payload type: UINT
+ */
+ AST_EVENT_IE_CACHABLE = 0x0035,
/*! \brief Must be the last IE value +1 */
- AST_EVENT_IE_TOTAL = 0x0035,
+ AST_EVENT_IE_TOTAL = 0x0036,
};
/*!
Modified: branches/1.8/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/channel.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/main/channel.c (original)
+++ branches/1.8/main/channel.c Wed Jan 2 10:54:20 2013
@@ -299,6 +299,7 @@
ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN));
ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT));
ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS));
+ ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(chan, AST_FLAG_DISABLE_DEVSTATE_CACHE));
}
#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
@@ -2519,7 +2520,7 @@
* instance is dead, we don't know the state of all other possible
* instances.
*/
- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
}
ast_atomic_fetchadd_int(&chancount, -1);
}
@@ -7058,7 +7059,7 @@
/* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
* for this channel is using the callback method for device state. If we pass in an actual state here
* we override what they are saying the state is and things go amuck. */
- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
+ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
/* setstate used to conditionally report Newchannel; this is no more */
ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
Modified: branches/1.8/main/devicestate.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/devicestate.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/main/devicestate.c (original)
+++ branches/1.8/main/devicestate.c Wed Jan 2 10:54:20 2013
@@ -174,6 +174,7 @@
struct state_change {
AST_LIST_ENTRY(state_change) list;
+ enum ast_devstate_cache cachable;
char device[1];
};
@@ -191,6 +192,7 @@
AST_LIST_ENTRY(devstate_change) entry;
uint32_t state;
struct ast_eid eid;
+ enum ast_devstate_cache cachable;
char device[1];
};
@@ -424,7 +426,7 @@
return res;
}
-static void devstate_event(const char *device, enum ast_device_state state)
+static void devstate_event(const char *device, enum ast_device_state state, int cachable)
{
struct ast_event *event;
enum ast_event_type event_type;
@@ -440,18 +442,23 @@
ast_debug(3, "device '%s' state '%d'\n", device, state);
if (!(event = ast_event_new(event_type,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
- AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
- AST_EVENT_IE_END))) {
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
+ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
+ AST_EVENT_IE_CACHABLE, AST_EVENT_IE_PLTYPE_UINT, cachable,
+ AST_EVENT_IE_END))) {
return;
}
- ast_event_queue_and_cache(event);
+ if (cachable) {
+ ast_event_queue_and_cache(event);
+ } else {
+ ast_event_queue(event);
+ }
}
/*! Called by the state change thread to find out what the state is, and then
* to queue up the state change event */
-static void do_state_change(const char *device)
+static void do_state_change(const char *device, int cachable)
{
enum ast_device_state state;
@@ -459,10 +466,10 @@
ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, ast_devstate2str(state));
- devstate_event(device, state);
-}
-
-int ast_devstate_changed_literal(enum ast_device_state state, const char *device)
+ devstate_event(device, state, cachable);
+}
+
+int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
{
struct state_change *change;
@@ -483,14 +490,15 @@
*/
if (state != AST_DEVICE_UNKNOWN) {
- devstate_event(device, state);
+ devstate_event(device, state, cachable);
} else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
/* we could not allocate a change struct, or */
/* there is no background thread, so process the change now */
- do_state_change(device);
+ do_state_change(device, cachable);
} else {
/* queue the change */
strcpy(change->device, device);
+ change->cachable = cachable;
AST_LIST_LOCK(&state_changes);
AST_LIST_INSERT_TAIL(&state_changes, change, list);
ast_cond_signal(&change_pending);
@@ -502,10 +510,10 @@
int ast_device_state_changed_literal(const char *dev)
{
- return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev);
-}
-
-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
+ return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, dev);
+}
+
+int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
{
char buf[AST_MAX_EXTENSION];
va_list ap;
@@ -514,7 +522,7 @@
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- return ast_devstate_changed_literal(state, buf);
+ return ast_devstate_changed_literal(state, cachable, buf);
}
int ast_device_state_changed(const char *fmt, ...)
@@ -526,7 +534,7 @@
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, buf);
+ return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, buf);
}
/*! \brief Go through the dev state change queue and update changes in the dev state thread */
@@ -546,7 +554,7 @@
/* Process each state change */
while ((current = next)) {
next = AST_LIST_NEXT(current, list);
- do_state_change(current->device);
+ do_state_change(current->device, current->cachable);
ast_free(current);
}
}
@@ -590,7 +598,7 @@
collection->num_states++;
}
-static void process_collection(const char *device, struct change_collection *collection)
+static void process_collection(const char *device, enum ast_devstate_cache cachable, struct change_collection *collection)
{
int i;
struct ast_devstate_aggregate agg;
@@ -641,7 +649,11 @@
return;
}
- ast_event_queue_and_cache(event);
+ if (cachable) {
+ ast_event_queue_and_cache(event);
+ } else {
+ ast_event_queue(event);
+ }
}
static void handle_devstate_change(struct devstate_change *sc)
@@ -667,7 +679,7 @@
/* Populate the collection of device states from the cache */
ast_event_dump_cache(tmp_sub);
- process_collection(sc->device, &collection);
+ process_collection(sc->device, sc->cachable, &collection);
ast_event_sub_destroy(tmp_sub);
}
@@ -696,10 +708,12 @@
const char *device;
const struct ast_eid *eid;
uint32_t state;
+ enum ast_devstate_cache cachable = AST_DEVSTATE_CACHABLE;
device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
+ cachable = ast_event_get_ie_uint(event, AST_EVENT_IE_CACHABLE);
if (ast_strlen_zero(device) || !eid) {
ast_log(LOG_ERROR, "Invalid device state change event received\n");
@@ -712,6 +726,7 @@
strcpy(sc->device, device);
sc->eid = *eid;
sc->state = state;
+ sc->cachable = cachable;
ast_mutex_lock(&devstate_collector.lock);
AST_LIST_INSERT_TAIL(&devstate_collector.devstate_change_q, sc, entry);
Modified: branches/1.8/main/event.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/event.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/main/event.c (original)
+++ branches/1.8/main/event.c Wed Jan 2 10:54:20 2013
@@ -268,6 +268,7 @@
[AST_EVENT_IE_CHALLENGE] = { AST_EVENT_IE_PLTYPE_STR, "Challenge" },
[AST_EVENT_IE_RESPONSE] = { AST_EVENT_IE_PLTYPE_STR, "Response" },
[AST_EVENT_IE_EXPECTED_RESPONSE] = { AST_EVENT_IE_PLTYPE_STR, "ExpectedResponse" },
+ [AST_EVENT_IE_CACHABLE] = { AST_EVENT_IE_PLTYPE_UINT, "Cachable" },
};
const char *ast_event_get_type_name(const struct ast_event *event)
Modified: branches/1.8/main/features.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/features.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/main/features.c (original)
+++ branches/1.8/main/features.c Wed Jan 2 10:54:20 2013
@@ -1094,7 +1094,7 @@
ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
exten, context, ast_devstate2str(state));
- ast_devstate_changed(state, "park:%s@%s", exten, context);
+ ast_devstate_changed(state, AST_DEVSTATE_CACHABLE, "park:%s@%s", exten, context);
}
/*! \brief metermaids callback from devicestate.c */
Modified: branches/1.8/res/res_calendar.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/res/res_calendar.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/res/res_calendar.c (original)
+++ branches/1.8/res/res_calendar.c Wed Jan 2 10:54:20 2013
@@ -575,9 +575,9 @@
* but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
if (!calendar_is_busy(event->owner)) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
} else {
- ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
}
}
@@ -818,9 +818,9 @@
/* We can have overlapping events, so ignore the event->busy_state and check busy state
* based on all events in the calendar */
if (!calendar_is_busy(event->owner)) {
- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
} else {
- ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
+ ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
}
event = ast_calendar_unref_event(event);
Modified: branches/1.8/res/res_jabber.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/res/res_jabber.c?view=diff&rev=378303&r1=378302&r2=378303
==============================================================================
--- branches/1.8/res/res_jabber.c (original)
+++ branches/1.8/res/res_jabber.c Wed Jan 2 10:54:20 2013
@@ -349,7 +349,7 @@
static void aji_create_affiliations(struct aji_client *client, const char *node);
static iks* aji_pubsub_iq_create(struct aji_client *client, const char *type);
static void aji_publish_device_state(struct aji_client *client, const char * device,
- const char *device_state);
+ const char *device_state, unsigned int cachable);
[... 149 lines stripped ...]
More information about the asterisk-commits
mailing list