From: Asterisk Autobuilder Date: Wed, 9 Jan 2013 20:43:00 +0000 (+0000) Subject: Merge changes for 11.2.0-rc2 X-Git-Tag: 11.2.0-rc2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be91d94f70b8084f9c73d5747c6289c44293f1b8;p=thirdparty%2Fasterisk.git 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 git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/11.2.0-rc2@378785 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/.version b/.version index 94ba9ae2bd..b7ce1a2353 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -11.2.0-rc1 +11.2.0-rc2 diff --git a/CHANGES b/CHANGES index b28e3bf6c3..e317f47dbf 100644 --- a/CHANGES +++ b/CHANGES @@ -901,8 +901,6 @@ Queue changes * 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 ------------ diff --git a/ChangeLog b/ChangeLog index 8c03a7aa25..42366ce19f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,78 @@ +2013-01-09 Asterisk Development Team + + * 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 * Asterisk 11.2.0-rc1 Released. diff --git a/UPGRADE.txt b/UPGRADE.txt index 4f9691344d..ae1ba2feeb 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -26,6 +26,9 @@ From 11.1 to 11.2: 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: Queues: diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index b0f61e9902..12ae7872cd 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -953,7 +953,7 @@ int conf_add_post_join_action(struct conference_bridge_user *cbu, int (*func)(st 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) diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 5b300d1111..05ef9f4b25 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -2696,7 +2696,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc /* 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 @@ bailoutandtrynormal: /* 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 @@ static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk || 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 @@ static void sla_handle_hold_event(struct sla_event *event) { 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 @@ static int sla_station_exec(struct ast_channel *chan, const char *data) 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; diff --git a/apps/app_queue.c b/apps/app_queue.c index 62b54b6eed..9f262a7a61 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1042,9 +1042,6 @@ static int negative_penalty_invalid = 0; /*! \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 member { 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 @@ static int handle_statechange(void *datap) 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 @@ static void init_queue(struct call_queue *q) * 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 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result * 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 @@ static void leave_queue(struct queue_ent *qe) 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 @@ static char *vars2manager(struct ast_channel *chan, char *vars, size_t len) 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 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies 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 (ast_channel_cdr(qe->chan)) { - ast_cdr_busy(ast_channel_cdr(qe->chan)); - } - tmp->stillgoing = 0; - (*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 (!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; } + 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 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies /* 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 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies 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 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies 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 @@ static int remove_from_queue(const char *queuename, const char *interface) } 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 @@ static int add_to_queue(const char *queuename, const char *interface, const char 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 @@ static int set_member_paused(const char *queuename, const char *interface, const } 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 @@ static void queue_set_global_params(struct ast_config *cfg) 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 @@ static int manager_queues_summary(struct mansession *s, const struct message *m) 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; } } diff --git a/apps/confbridge/conf_state_empty.c b/apps/confbridge/conf_state_empty.c index 22997ad2c6..afc736d4a2 100644 --- a/apps/confbridge/conf_state_empty.c +++ b/apps/confbridge/conf_state_empty.c @@ -81,6 +81,6 @@ static void join_marked(struct conference_bridge_user *cbu) 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); } diff --git a/asterisk-11.2.0-rc1-summary.html b/asterisk-11.2.0-rc1-summary.html deleted file mode 100644 index 4b7e9d9ae3..0000000000 --- a/asterisk-11.2.0-rc1-summary.html +++ /dev/null @@ -1,403 +0,0 @@ - - -Release Summary - asterisk-11.2.0-rc1 - -

Release Summary

-

asterisk-11.2.0-rc1

-

Date: 2012-12-09

-

<asteriskteam@digium.com>

-
-

Table of Contents

-
    -
  1. Summary
  2. -
  3. Contributors
  4. -
  5. Closed Issues
  6. -
  7. Other Changes
  8. -
  9. Diffstat
  10. -
-
-

Summary

-
[Back to Top]

This release includes only bug fixes. The changes included were made only to address problems that have been identified in this release series. Users should be able to safely upgrade to this version if this release series is already in use. Users considering upgrading from a previous release series are strongly encouraged to review the UPGRADE.txt document as well as the CHANGES document for information about upgrading to this release series.

-

The data in this summary reflects changes that have been made since the previous release, asterisk-11.1.0.

-
-

Contributors

-
[Back to Top]

This table lists the people who have submitted code, those that have tested patches, as well as those that reported issues on the issue tracker that were resolved in this release. For coders, the number is how many of their patches (of any size) were committed into this release. For testers, the number is the number of times their name was listed as assisting with testing a patch. Finally, for reporters, the number is the number of issues that they reported that were closed by commits that went into this release.

- - - - - - - - - - - -

Coders

Testers

Reporters

-22 rmudgett
-4 jcolp
-4 jrose
-4 mjordan
-4 mmichelson
-3 dlee
-2 elguero
-2 russell
-2 tilghman
-1 alecdavis
-1 Andre Luis
-1 beagles
-1 file
-1 James Le Cuirot
-1 Jeremiah Gowdy
-1 jkroon
-1 kmoore
-1 pkiefer
-1 Rusty Newton
-1 seanbright
-1 wdoekes
-
-3 rmudgett
-1 alecdavis
-1 elguero
-1 Jared Smith
-1 mjordan
-1 Rusty Newton
-1 Steven T. Wheeler
-
-4 mjordan
-1 alecdavis
-1 andrel
-1 chewi
-1 coopvr
-1 deti
-1 dlee
-1 eabad
-1 elguero
-1 ibc
-1 jgowdy
-1 jkroon
-1 joshoa
-1 jrose
-1 jsmith
-1 mcargile
-1 p_lindheimer
-1 rmudgett
-1 sruffell
-1 supertle
-1 swheeler
-1 tomo1657
-1 tootai
-1 vldmr
-1 wimpy
-
-
-

Closed Issues

-
[Back to Top]

This is a list of all issues from the issue tracker that were closed by changes that went into this release.

-

Category: Applications/app_confbridge


-ASTERISK-20655: Cannot reset pin with CONFBRIDGE(user,pin)
-Revision: 377228
-Reporter: wimpy
-Coders: rmudgett
-
-

Category: Applications/app_meetme


-ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel hangs up.
-Revision: 376310
-Reporter: mcargile
-Coders: jrose
-
-

Category: Applications/app_queue


-ASTERISK-19918: MoH (Music on Hold) is stopped after call in a queue is terminated
-Revision: 376217
-Reporter: eabad
-Coders: beagles
-
-

Category: Applications/app_voicemail


-ASTERISK-20280: In app_voicemail we attempt to play the sound "vm-urgent-removed", which should be "vm-marked-nonurgent"
-Revision: 376264
-Reporter: tomo1657
-Testers: Rusty Newton
-Coders: Rusty Newton
-
-

Category: Channels/General


-ASTERISK-20414: Timeout antipattern using ast_waitfor_nandfds
-Revision: 376014
-Reporter: dlee
-Coders: mmichelson
-
-

Category: Channels/chan_bridge


-ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two channel bridge
-Revision: 375966
-Reporter: jgowdy
-Testers: rmudgett
-Coders: Jeremiah Gowdy, rmudgett
-
-

Category: Channels/chan_dahdi/SS7


-ASTERISK-20204: Asterisk not rejecting call setup on CIC that is down
-Revision: 376060
-Reporter: supertle
-Coders: rmudgett
-
-

Category: Channels/chan_local


-ASTERISK-20769: Memory leak of local_pvt in chan_local.
-Revision: 376870
-Reporter: rmudgett
-Testers: rmudgett
-Coders: rmudgett
-
-

Category: Channels/chan_motif


-ASTERISK-20671: Add Who Hung Up support to the Motif channel driver
-Revision: 377462
-Reporter: mjordan
-Coders: jcolp
-
-ASTERISK-20751: chan_motif leaves UDP ports open
-Revision: 377021
-Reporter: joshoa
-Coders: jcolp
-
-

Category: Channels/chan_sip/General


-ASTERISK-20226: Segfault in chan_sip while performing connected line update
-Revision: 376917
-Reporter: jsmith
-Testers: Jared Smith
-Coders: mmichelson
-
-ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel hangs up.
-Revision: 376310
-Reporter: mcargile
-Coders: jrose
-
-ASTERISK-20570: Asterisk, when acting as the UAS in Session Timer negotiation, fails to add required header in 200 response ("Require: timer")
-Revision: 376550
-Reporter: mjordan
-Coders: mmichelson
-
-ASTERISK-20643: SIP ICE support - remove hardcoded limitation on SDP size, make ICE support disabled by default in SIP, maybe provide a better warning message
-Revision: 376130
-Reporter: coopvr
-Coders: jcolp
-
-ASTERISK-20724: Fix natdetected flag being set when VIA doesn't include port in address
-Revision: 376836
-Reporter: elguero
-Coders: elguero
-
-

Category: Channels/chan_sip/SRTP


-ASTERISK-20499: Crash in libsrtp srtp_unprotect_rtcp when SIP channel is bridged with non-optimizing Local channel
-Revision: 377262
-Reporter: tootai
-Coders: jrose
-
-

Category: Channels/chan_sip/TCP-TLS


-ASTERISK-20763: Memory Leak in chan_sip with TLS enabled clients
-Revision: 377259
-Reporter: deti
-Coders: jcolp
-
-

Category: Channels/chan_sip/WebSocket


-ASTERISK-20745: In MESSAGE received over WebSocket, the body last char is cut
-Revision: 376822
-Reporter: ibc
-Coders: pkiefer
-
-

Category: Codecs/codec_dahdi


-ASTERISK-19921: codec_dahdi: Wrong number of encoder/decoder channels.
-Revision: 377383
-Reporter: sruffell
-Coders: kmoore
-
-

Category: Contrib/General


-ASTERISK-20756: Asterisk sippeers.sql columns place error cause peer to be without codecs when setting disallow=all under MySQL
-Revision: 377433
-Reporter: andrel
-Coders: Andre Luis
-
-

Category: Core/Channels


-ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two channel bridge
-Revision: 375966
-Reporter: jgowdy
-Testers: rmudgett
-Coders: Jeremiah Gowdy, rmudgett
-
-

Category: Core/ManagerInterface


-ASTERISK-20677: Action Challenge not working with allowmultiplelogin=no
-Revision: 376727
-Reporter: vldmr
-Coders: jrose
-
-

Category: Core/PBX


-ASTERISK-19205: Most Unique pattern matching broken when trailing "-" is part of extension
-Revision: 376690
-Reporter: p_lindheimer
-Testers: rmudgett
-Coders: rmudgett
-
-ASTERISK-20639: Dynamic hints are not properly initialized when the extension contains an underscore.
-Revision: 376144
-Reporter: swheeler
-Testers: Steven T. Wheeler, elguero
-Coders: elguero
-
-

Category: General


-ASTERISK-19463: Asterisk deadlocks during startup with mutex errors
-Revision: 376441
-Reporter: mjordan
-Testers: mjordan
-Coders: mjordan
-
-ASTERISK-20226: Segfault in chan_sip while performing connected line update
-Revision: 376917
-Reporter: jsmith
-Testers: Jared Smith
-Coders: mmichelson
-
-

Category: PBX/General


-ASTERISK-20628: [patch] - main/pbx.c - ShowDialPlan generates with error if no Exten: was presented and there are no exten => lines present
-Revision: 376168
-Reporter: jkroon
-Coders: jkroon
-
-

Category: PBX/pbx_spool


-ASTERISK-20593: [patch] Future-dated call files are ignored when astspooldir is relative
-Revision: 376234
-Reporter: chewi
-Coders: James Le Cuirot
-
-

Category: Resources/res_monitor


-ASTERISK-20641: Erroneous error messages from Monitor when using options 'i' and 'o'
-Revision: 376391
-Reporter: jrose
-Coders: jrose
-
-

Category: Tests/testsuite


-ASTERISK-19463: Asterisk deadlocks during startup with mutex errors
-Revision: 376441
-Reporter: mjordan
-Testers: mjordan
-Coders: mjordan
-
-

Category: Utilities/General


-ASTERISK-20505: Migrate hashtest/hashtest2 to be unit tests
-Revision: 376339
-Reporter: mjordan
-Coders: dlee
-
-
-

Commits Not Associated with an Issue

-
[Back to Top]

This is a list of all changes that went into this release that did not directly close an issue from the issue tracker. The commits may have been marked as being related to an issue. If that is the case, the issue numbers are listed here, as well.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RevisionAuthorSummaryIssues Referenced
376048rmudgettAdd MALLOC_DEBUG enhancements.
376089mmichelsonFix a "set but not used" warning on newer gccs.
376343dleeFixed extconf.c breakage introduced in r376306.
376415mjordanAdd a test event that reports changes in ConfBridge state
376471wdoekesFix most leftover non-opaque ast_str uses.
376561dleeAdded missing newlines to websocket ast_logs.
376588mjordanRe-initialize logmsgs mutex upon logger initialization to prevent lock errorsASTERISK-19463
376629rmudgettMade AST_LIST_REMOVE() simpler and use better names.
376659rmudgettRemove unnecessary channel module references.
376760rmudgettEnhance MALLOC_DEBUG CLI commands.
376790rmudgettAdd MALLOC_DEBUG atexit unreleased malloc memory summary.
376866rmudgettFix compile error.ASTERISK-20724
376921seanbrightMinor spelling fix to the VOLUME documentation.
376952rmudgettchan_misdn: Fix sending RELEASE_COMPLETE in response to SETUP.
376983fileTweak extension used for incoming calls received on Motif.
377039rmudgettFix CCSS CLI commands and logger level not unregistered.ASTERISK-20649
377071rmudgettCleanup CDR resources on exit.ASTERISK-20649
377075rmudgettCleanup CLI resources on exit and CLI command registration errors.ASTERISK-20649
377106rmudgettCleanup config cache on exit.ASTERISK-20649
377137rmudgettCleanup core main on exit.ASTERISK-20649
377167rmudgettCleanup ast_run_atexits() atexits list.ASTERISK-20649
377195russellAdd libuuid to install_prereq for Fedora.
377213rmudgettconfbridge: Update online XML documentation.
377244rmudgettFix registering core show codecs/codec CLI commands twice.
377319mjordanFix memory leak in 'manager show event' when command entered incorrectly
377340russellAdd CLI tab completion to 'acl show'.
377355rmudgettconfbridge: Fix some resource leaks on conference teardown.
377401rmudgettMALLOC_DEBUG: Only wait if we want atexit allocation dumps.
377505tilghmanRemove some dead code and additionally handle a case that wasn't handled.
377511tilghmanImprove documentation by making all of the colors used readable,
-
-

Diffstat Results

-
[Back to Top]

This is a summary of the changes to the source code that went into this release that was generated using the diffstat utility.

-
-UPGRADE.txt                          |    6
-addons/cdr_mysql.c                   |   11
-addons/res_config_mysql.c            |    3
-apps/app_celgenuserevent.c           |    9
-apps/app_confbridge.c                |  148 ++--
-apps/app_dial.c                      |   14
-apps/app_jack.c                      |    4
-apps/app_meetme.c                    |   15
-apps/app_queue.c                     |   26
-apps/app_record.c                    |   27
-apps/app_voicemail.c                 |    2
-apps/app_waitforring.c               |   25
-apps/confbridge/conf_config_parser.c |  126 ++-
-apps/confbridge/conf_state.c         |    5
-channels/chan_agent.c                |   14
-channels/chan_dahdi.c                |   42 -
-channels/chan_iax2.c                 |   14
-channels/chan_local.c                |   21
-channels/chan_motif.c                |   27
-channels/chan_sip.c                  |  208 +++--
-channels/misdn/isdn_lib.c            |   17
-channels/sig_analog.c                |   22
-channels/sig_pri.c                   |   12
-channels/sig_ss7.c                   |   51 -
-channels/sip/include/sip.h           |    1
-codecs/codec_dahdi.c                 |    2
-configs/motif.conf.sample            |    5
-configs/sip.conf.sample              |    5
-contrib/realtime/mysql/sippeers.sql  |    2
-contrib/scripts/install_prereq       |    2
-funcs/func_volume.c                  |    2
-include/asterisk/_private.h          |    1
-include/asterisk/astmm.h             |    3
-include/asterisk/channel.h           |    8
-include/asterisk/features.h          |   12
-include/asterisk/hashtab.h           |    3
-include/asterisk/linkedlists.h       |   58 -
-include/asterisk/lock.h              |   16
-include/asterisk/time.h              |   14
-include/asterisk/utils.h             |   29
-main/asterisk.c                      |  352 ++++++----
-main/astmm.c                         | 1223 ++++++++++++++++++++++++++++++-----
-main/ccss.c                          |    2
-main/cdr.c                           |   46 -
-main/channel.c                       |  150 +++-
-main/channel_internal_api.c          |   21
-main/cli.c                           |   41 +
-main/config.c                        |   14
-main/features.c                      |   27
-main/format.c                        |    6
-main/indications.c                   |    2
-main/lock.c                          |    2
-main/logger.c                        |   11
-main/manager.c                       |    7
-main/named_acl.c                     |   25
-main/pbx.c                           |  532 +++++++++++----
-main/rtp_engine.c                    |   16
-main/security_events.c               |    2
-main/stdtime/localtime.c             |   14
-main/utils.c                         |   69 +
-main/xmldoc.c                        |    8
-pbx/pbx_dundi.c                      |   31
-pbx/pbx_spool.c                      |    2
-res/res_fax.c                        |  128 ++-
-res/res_http_websocket.c             |   12
-res/res_monitor.c                    |   32
-res/res_rtp_asterisk.c               |    2
-res/res_srtp.c                       |    4
-tests/test_astobj2_thrash.c          |  353 ++++++++++
-tests/test_hashtab_thrash.c          |  321 +++++++++
-utils/Makefile                       |    7
-utils/extconf.c                      |    1
-utils/hashtest.c                     |  410 -----------
-utils/hashtest2.c                    |  418 -----------
-utils/utils.xml                      |    8
-75 files changed, 3469 insertions(+), 1842 deletions(-)
-

-
- - diff --git a/asterisk-11.2.0-rc1-summary.txt b/asterisk-11.2.0-rc1-summary.txt deleted file mode 100644 index f51f5dd035..0000000000 --- a/asterisk-11.2.0-rc1-summary.txt +++ /dev/null @@ -1,526 +0,0 @@ - Release Summary - - asterisk-11.2.0-rc1 - - Date: 2012-12-09 - - - - ---------------------------------------------------------------------- - - Table of Contents - - 1. Summary - 2. Contributors - 3. Closed Issues - 4. Other Changes - 5. Diffstat - - ---------------------------------------------------------------------- - - Summary - - [Back to Top] - - This release includes only bug fixes. The changes included were made only - to address problems that have been identified in this release series. - Users should be able to safely upgrade to this version if this release - series is already in use. Users considering upgrading from a previous - release series are strongly encouraged to review the UPGRADE.txt document - as well as the CHANGES document for information about upgrading to this - release series. - - The data in this summary reflects changes that have been made since the - previous release, asterisk-11.1.0. - - ---------------------------------------------------------------------- - - Contributors - - [Back to Top] - - This table lists the people who have submitted code, those that have - tested patches, as well as those that reported issues on the issue tracker - that were resolved in this release. For coders, the number is how many of - their patches (of any size) were committed into this release. For testers, - the number is the number of times their name was listed as assisting with - testing a patch. Finally, for reporters, the number is the number of - issues that they reported that were closed by commits that went into this - release. - - Coders Testers Reporters - 22 rmudgett 3 rmudgett 4 mjordan - 4 jcolp 1 alecdavis 1 alecdavis - 4 jrose 1 elguero 1 andrel - 4 mjordan 1 Jared Smith 1 chewi - 4 mmichelson 1 mjordan 1 coopvr - 3 dlee 1 Rusty Newton 1 deti - 2 elguero 1 Steven T. Wheeler 1 dlee - 2 russell 1 eabad - 2 tilghman 1 elguero - 1 alecdavis 1 ibc - 1 Andre Luis 1 jgowdy - 1 beagles 1 jkroon - 1 file 1 joshoa - 1 James Le Cuirot 1 jrose - 1 Jeremiah Gowdy 1 jsmith - 1 jkroon 1 mcargile - 1 kmoore 1 p_lindheimer - 1 pkiefer 1 rmudgett - 1 Rusty Newton 1 sruffell - 1 seanbright 1 supertle - 1 wdoekes 1 swheeler - 1 tomo1657 - 1 tootai - 1 vldmr - 1 wimpy - - ---------------------------------------------------------------------- - - Closed Issues - - [Back to Top] - - This is a list of all issues from the issue tracker that were closed by - changes that went into this release. - - Category: Applications/app_confbridge - - ASTERISK-20655: Cannot reset pin with CONFBRIDGE(user,pin) - Revision: 377228 - Reporter: wimpy - Coders: rmudgett - - Category: Applications/app_meetme - - ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel - hangs up. - Revision: 376310 - Reporter: mcargile - Coders: jrose - - Category: Applications/app_queue - - ASTERISK-19918: MoH (Music on Hold) is stopped after call in a queue is - terminated - Revision: 376217 - Reporter: eabad - Coders: beagles - - Category: Applications/app_voicemail - - ASTERISK-20280: In app_voicemail we attempt to play the sound - "vm-urgent-removed", which should be "vm-marked-nonurgent" - Revision: 376264 - Reporter: tomo1657 - Testers: Rusty Newton - Coders: Rusty Newton - - Category: Channels/General - - ASTERISK-20414: Timeout antipattern using ast_waitfor_nandfds - Revision: 376014 - Reporter: dlee - Coders: mmichelson - - Category: Channels/chan_bridge - - ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two - channel bridge - Revision: 375966 - Reporter: jgowdy - Testers: rmudgett - Coders: Jeremiah Gowdy, rmudgett - - Category: Channels/chan_dahdi/SS7 - - ASTERISK-20204: Asterisk not rejecting call setup on CIC that is down - Revision: 376060 - Reporter: supertle - Coders: rmudgett - - Category: Channels/chan_local - - ASTERISK-20769: Memory leak of local_pvt in chan_local. - Revision: 376870 - Reporter: rmudgett - Testers: rmudgett - Coders: rmudgett - - Category: Channels/chan_motif - - ASTERISK-20671: Add Who Hung Up support to the Motif channel driver - Revision: 377462 - Reporter: mjordan - Coders: jcolp - - ASTERISK-20751: chan_motif leaves UDP ports open - Revision: 377021 - Reporter: joshoa - Coders: jcolp - - Category: Channels/chan_sip/General - - ASTERISK-20226: Segfault in chan_sip while performing connected line - update - Revision: 376917 - Reporter: jsmith - Testers: Jared Smith - Coders: mmichelson - - ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel - hangs up. - Revision: 376310 - Reporter: mcargile - Coders: jrose - - ASTERISK-20570: Asterisk, when acting as the UAS in Session Timer - negotiation, fails to add required header in 200 response ("Require: - timer") - Revision: 376550 - Reporter: mjordan - Coders: mmichelson - - ASTERISK-20643: SIP ICE support - remove hardcoded limitation on SDP size, - make ICE support disabled by default in SIP, maybe provide a better - warning message - Revision: 376130 - Reporter: coopvr - Coders: jcolp - - ASTERISK-20724: Fix natdetected flag being set when VIA doesn't include - port in address - Revision: 376836 - Reporter: elguero - Coders: elguero - - Category: Channels/chan_sip/SRTP - - ASTERISK-20499: Crash in libsrtp srtp_unprotect_rtcp when SIP channel is - bridged with non-optimizing Local channel - Revision: 377262 - Reporter: tootai - Coders: jrose - - Category: Channels/chan_sip/TCP-TLS - - ASTERISK-20763: Memory Leak in chan_sip with TLS enabled clients - Revision: 377259 - Reporter: deti - Coders: jcolp - - Category: Channels/chan_sip/WebSocket - - ASTERISK-20745: In MESSAGE received over WebSocket, the body last char is - cut - Revision: 376822 - Reporter: ibc - Coders: pkiefer - - Category: Codecs/codec_dahdi - - ASTERISK-19921: codec_dahdi: Wrong number of encoder/decoder channels. - Revision: 377383 - Reporter: sruffell - Coders: kmoore - - Category: Contrib/General - - ASTERISK-20756: Asterisk sippeers.sql columns place error cause peer to be - without codecs when setting disallow=all under MySQL - Revision: 377433 - Reporter: andrel - Coders: Andre Luis - - Category: Core/Channels - - ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two - channel bridge - Revision: 375966 - Reporter: jgowdy - Testers: rmudgett - Coders: Jeremiah Gowdy, rmudgett - - Category: Core/ManagerInterface - - ASTERISK-20677: Action Challenge not working with allowmultiplelogin=no - Revision: 376727 - Reporter: vldmr - Coders: jrose - - Category: Core/PBX - - ASTERISK-19205: Most Unique pattern matching broken when trailing "-" is - part of extension - Revision: 376690 - Reporter: p_lindheimer - Testers: rmudgett - Coders: rmudgett - - ASTERISK-20639: Dynamic hints are not properly initialized when the - extension contains an underscore. - Revision: 376144 - Reporter: swheeler - Testers: Steven T. Wheeler, elguero - Coders: elguero - - Category: General - - ASTERISK-19463: Asterisk deadlocks during startup with mutex errors - Revision: 376441 - Reporter: mjordan - Testers: mjordan - Coders: mjordan - - ASTERISK-20226: Segfault in chan_sip while performing connected line - update - Revision: 376917 - Reporter: jsmith - Testers: Jared Smith - Coders: mmichelson - - Category: PBX/General - - ASTERISK-20628: [patch] - main/pbx.c - ShowDialPlan generates with error - if no Exten: was presented and there are no exten => lines present - Revision: 376168 - Reporter: jkroon - Coders: jkroon - - Category: PBX/pbx_spool - - ASTERISK-20593: [patch] Future-dated call files are ignored when - astspooldir is relative - Revision: 376234 - Reporter: chewi - Coders: James Le Cuirot - - Category: Resources/res_monitor - - ASTERISK-20641: Erroneous error messages from Monitor when using options - 'i' and 'o' - Revision: 376391 - Reporter: jrose - Coders: jrose - - Category: Tests/testsuite - - ASTERISK-19463: Asterisk deadlocks during startup with mutex errors - Revision: 376441 - Reporter: mjordan - Testers: mjordan - Coders: mjordan - - Category: Utilities/General - - ASTERISK-20505: Migrate hashtest/hashtest2 to be unit tests - Revision: 376339 - Reporter: mjordan - Coders: dlee - - ---------------------------------------------------------------------- - - Commits Not Associated with an Issue - - [Back to Top] - - This is a list of all changes that went into this release that did not - directly close an issue from the issue tracker. The commits may have been - marked as being related to an issue. If that is the case, the issue - numbers are listed here, as well. - - +------------------------------------------------------------------------+ - | Revision | Author | Summary | Issues Referenced | - |----------+------------+----------------------------+-------------------| - | 376048 | rmudgett | Add MALLOC_DEBUG | | - | | | enhancements. | | - |----------+------------+----------------------------+-------------------| - | 376089 | mmichelson | Fix a "set but not used" | | - | | | warning on newer gccs. | | - |----------+------------+----------------------------+-------------------| - | 376343 | dlee | Fixed extconf.c breakage | | - | | | introduced in r376306. | | - |----------+------------+----------------------------+-------------------| - | | | Add a test event that | | - | 376415 | mjordan | reports changes in | | - | | | ConfBridge state | | - |----------+------------+----------------------------+-------------------| - | 376471 | wdoekes | Fix most leftover | | - | | | non-opaque ast_str uses. | | - |----------+------------+----------------------------+-------------------| - | 376561 | dlee | Added missing newlines to | | - | | | websocket ast_logs. | | - |----------+------------+----------------------------+-------------------| - | | | Re-initialize logmsgs | | - | 376588 | mjordan | mutex upon logger | ASTERISK-19463 | - | | | initialization to prevent | | - | | | lock errors | | - |----------+------------+----------------------------+-------------------| - | | | Made AST_LIST_REMOVE() | | - | 376629 | rmudgett | simpler and use better | | - | | | names. | | - |----------+------------+----------------------------+-------------------| - | 376659 | rmudgett | Remove unnecessary channel | | - | | | module references. | | - |----------+------------+----------------------------+-------------------| - | 376760 | rmudgett | Enhance MALLOC_DEBUG CLI | | - | | | commands. | | - |----------+------------+----------------------------+-------------------| - | | | Add MALLOC_DEBUG atexit | | - | 376790 | rmudgett | unreleased malloc memory | | - | | | summary. | | - |----------+------------+----------------------------+-------------------| - | 376866 | rmudgett | Fix compile error. | ASTERISK-20724 | - |----------+------------+----------------------------+-------------------| - | 376921 | seanbright | Minor spelling fix to the | | - | | | VOLUME documentation. | | - |----------+------------+----------------------------+-------------------| - | | | chan_misdn: Fix sending | | - | 376952 | rmudgett | RELEASE_COMPLETE in | | - | | | response to SETUP. | | - |----------+------------+----------------------------+-------------------| - | | | Tweak extension used for | | - | 376983 | file | incoming calls received on | | - | | | Motif. | | - |----------+------------+----------------------------+-------------------| - | | | Fix CCSS CLI commands and | | - | 377039 | rmudgett | logger level not | ASTERISK-20649 | - | | | unregistered. | | - |----------+------------+----------------------------+-------------------| - | 377071 | rmudgett | Cleanup CDR resources on | ASTERISK-20649 | - | | | exit. | | - |----------+------------+----------------------------+-------------------| - | | | Cleanup CLI resources on | | - | 377075 | rmudgett | exit and CLI command | ASTERISK-20649 | - | | | registration errors. | | - |----------+------------+----------------------------+-------------------| - | 377106 | rmudgett | Cleanup config cache on | ASTERISK-20649 | - | | | exit. | | - |----------+------------+----------------------------+-------------------| - | 377137 | rmudgett | Cleanup core main on exit. | ASTERISK-20649 | - |----------+------------+----------------------------+-------------------| - | 377167 | rmudgett | Cleanup ast_run_atexits() | ASTERISK-20649 | - | | | atexits list. | | - |----------+------------+----------------------------+-------------------| - | 377195 | russell | Add libuuid to | | - | | | install_prereq for Fedora. | | - |----------+------------+----------------------------+-------------------| - | 377213 | rmudgett | confbridge: Update online | | - | | | XML documentation. | | - |----------+------------+----------------------------+-------------------| - | | | Fix registering core show | | - | 377244 | rmudgett | codecs/codec CLI commands | | - | | | twice. | | - |----------+------------+----------------------------+-------------------| - | | | Fix memory leak in | | - | 377319 | mjordan | 'manager show event' when | | - | | | command entered | | - | | | incorrectly | | - |----------+------------+----------------------------+-------------------| - | 377340 | russell | Add CLI tab completion to | | - | | | 'acl show'. | | - |----------+------------+----------------------------+-------------------| - | | | confbridge: Fix some | | - | 377355 | rmudgett | resource leaks on | | - | | | conference teardown. | | - |----------+------------+----------------------------+-------------------| - | | | MALLOC_DEBUG: Only wait if | | - | 377401 | rmudgett | we want atexit allocation | | - | | | dumps. | | - |----------+------------+----------------------------+-------------------| - | | | Remove some dead code and | | - | 377505 | tilghman | additionally handle a case | | - | | | that wasn't handled. | | - |----------+------------+----------------------------+-------------------| - | | | Improve documentation by | | - | 377511 | tilghman | making all of the colors | | - | | | used readable, | | - +------------------------------------------------------------------------+ - - ---------------------------------------------------------------------- - - Diffstat Results - - [Back to Top] - - This is a summary of the changes to the source code that went into this - release that was generated using the diffstat utility. - - UPGRADE.txt | 6 - addons/cdr_mysql.c | 11 - addons/res_config_mysql.c | 3 - apps/app_celgenuserevent.c | 9 - apps/app_confbridge.c | 148 ++-- - apps/app_dial.c | 14 - apps/app_jack.c | 4 - apps/app_meetme.c | 15 - apps/app_queue.c | 26 - apps/app_record.c | 27 - apps/app_voicemail.c | 2 - apps/app_waitforring.c | 25 - apps/confbridge/conf_config_parser.c | 126 ++- - apps/confbridge/conf_state.c | 5 - channels/chan_agent.c | 14 - channels/chan_dahdi.c | 42 - - channels/chan_iax2.c | 14 - channels/chan_local.c | 21 - channels/chan_motif.c | 27 - channels/chan_sip.c | 208 +++-- - channels/misdn/isdn_lib.c | 17 - channels/sig_analog.c | 22 - channels/sig_pri.c | 12 - channels/sig_ss7.c | 51 - - channels/sip/include/sip.h | 1 - codecs/codec_dahdi.c | 2 - configs/motif.conf.sample | 5 - configs/sip.conf.sample | 5 - contrib/realtime/mysql/sippeers.sql | 2 - contrib/scripts/install_prereq | 2 - funcs/func_volume.c | 2 - include/asterisk/_private.h | 1 - include/asterisk/astmm.h | 3 - include/asterisk/channel.h | 8 - include/asterisk/features.h | 12 - include/asterisk/hashtab.h | 3 - include/asterisk/linkedlists.h | 58 - - include/asterisk/lock.h | 16 - include/asterisk/time.h | 14 - include/asterisk/utils.h | 29 - main/asterisk.c | 352 ++++++---- - main/astmm.c | 1223 ++++++++++++++++++++++++++++++----- - main/ccss.c | 2 - main/cdr.c | 46 - - main/channel.c | 150 +++- - main/channel_internal_api.c | 21 - main/cli.c | 41 + - main/config.c | 14 - main/features.c | 27 - main/format.c | 6 - main/indications.c | 2 - main/lock.c | 2 - main/logger.c | 11 - main/manager.c | 7 - main/named_acl.c | 25 - main/pbx.c | 532 +++++++++++---- - main/rtp_engine.c | 16 - main/security_events.c | 2 - main/stdtime/localtime.c | 14 - main/utils.c | 69 + - main/xmldoc.c | 8 - pbx/pbx_dundi.c | 31 - pbx/pbx_spool.c | 2 - res/res_fax.c | 128 ++- - res/res_http_websocket.c | 12 - res/res_monitor.c | 32 - res/res_rtp_asterisk.c | 2 - res/res_srtp.c | 4 - tests/test_astobj2_thrash.c | 353 ++++++++++ - tests/test_hashtab_thrash.c | 321 +++++++++ - utils/Makefile | 7 - utils/extconf.c | 1 - utils/hashtest.c | 410 ----------- - utils/hashtest2.c | 418 ----------- - utils/utils.xml | 8 - 75 files changed, 3469 insertions(+), 1842 deletions(-) - - ---------------------------------------------------------------------- diff --git a/channels/chan_agent.c b/channels/chan_agent.c index 81cf8d5678..fbd3ec0603 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -618,7 +618,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast) 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 @@ static int agent_call(struct ast_channel *ast, const char *dest, int timeout) } 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 @@ static int agent_hangup(struct ast_channel *ast) 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 @@ static int login_exec(struct ast_channel *chan, const char *data) } 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 @@ static int login_exec(struct ast_channel *chan, const char *data) 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 @@ static int login_exec(struct ast_channel *chan, const char *data) 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); diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 390f8b2a22..c60379795e 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -3438,7 +3438,7 @@ static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri) } 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 @@ static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri) } 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 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb 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); diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 80041336f4..38274de7d6 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -5798,7 +5798,7 @@ static int iax2_getpeertrunk(struct sockaddr_in sin) } /*! \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; @@ -5880,6 +5880,10 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab 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) { for (v = i->vars ; v ; v = v->next) @@ -8161,7 +8165,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * /* 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 @@ static void __expire_registry(const void *data) 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 @@ static void reg_source_db(struct iax2_peer *p) } } - 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 @@ static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, i 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 @@ static int socket_process_helper(struct iax2_thread *thread) (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 @@ static int socket_process_helper(struct iax2_thread *thread) 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 @@ static int socket_process_helper(struct iax2_thread *thread) 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 @@ immediatedial: 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 @@ static void __iax2_poke_noanswer(const void *data) 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 @@ static struct ast_channel *iax2_request(const char *type, struct ast_format_cap 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) { diff --git a/channels/chan_local.c b/channels/chan_local.c index da86e14733..ec19cd71b9 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -1266,6 +1266,9 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char 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); diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 37b4c7ba17..5207c51e27 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -2667,19 +2667,20 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str 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 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str 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 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str 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 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str } 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 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str 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 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str } 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 @@ static int sip_tcp_read(struct sip_request *req, struct ast_tcptls_session_insta 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; @@ -2983,6 +3000,13 @@ static int sip_tcp_read(struct sip_request *req, struct ast_tcptls_session_insta ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf)); ast_str_reset(tcptls_session->overflow_buf); } + + datalen = ast_str_strlen(req->data); + if (datalen > SIP_MAX_PACKET_SIZE) { + ast_log(LOG_WARNING, "Rejecting TCP packet from '%s' because way too large: %zu\n", + ast_sockaddr_stringify(&tcptls_session->remote_address), datalen); + return -1; + } message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf); } @@ -3054,7 +3078,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s } me->threadid = pthread_self(); - ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); + ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); /* set up pollfd to watch for reads on both the socket and the alert_pipe */ fds[0].fd = tcptls_session->fd; @@ -3088,7 +3112,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s } if (timeout == 0) { - ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); + ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); goto cleanup; } } else { @@ -3098,11 +3122,11 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s if (ast_str_strlen(tcptls_session->overflow_buf) == 0) { res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */ if (res < 0) { - ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res); + ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res); goto cleanup; } else if (res == 0) { /* timeout */ - ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); + ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP"); goto cleanup; } } @@ -3184,7 +3208,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s } } - ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); + ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP"); cleanup: if (tcptls_session && !tcptls_session->client && !authenticated) { @@ -6771,7 +6795,7 @@ static int update_call_counter(struct sip_pvt *fup, int event) } 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); sip_unref_peer(p, "update_call_counter: sip_unref_peer from call counter"); } return 0; @@ -8032,6 +8056,9 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit ast_jb_configure(tmp, &global_jbconf); } + if (!i->relatedpeer) { + ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE); + } /* Set channel variables for this call from configuration */ for (v = i->chanvars ; v ; v = v->next) { char valuebuf[1024]; @@ -15540,7 +15567,7 @@ static int expire_register(const void *data) 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 @@ -16325,8 +16352,9 @@ static void sip_peer_hold(struct sip_pvt *p, int hold) 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, (ast_test_flag(ast_channel_flags(p->owner), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), + "SIP/%s", p->relatedpeer->name); + return; } @@ -16849,7 +16877,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock } 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) { @@ -23219,7 +23247,7 @@ static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_req 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); } @@ -29113,7 +29141,7 @@ static int sip_poke_noanswer(const void *data) /* 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 */ diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 2997ac834e..0332235b82 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -2133,7 +2133,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s) AST_LIST_TRAVERSE(&l->sublines, subline, list) { ast_extension_state_add(subline->context, subline->exten, skinny_extensionstate_cb, subline->container); } - ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name); + ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name); --instance; } break; @@ -2168,7 +2168,7 @@ static int skinny_unregister(struct skinny_req *req, struct skinnysession *s) 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", l->name); + ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name); } } } @@ -5935,7 +5935,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession event, d->name, instance, callreference); break; } - ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s", l->name); + ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name); return 1; } @@ -5975,7 +5975,7 @@ static int handle_offhook_message(struct skinny_req *req, struct skinnysession * transmit_ringer_mode(d, SKINNY_RING_OFF); d->hookstate = SKINNY_OFFHOOK; - ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name); + ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name); if (sub && sub->substate == SUBSTATE_HOLD) { return 1; @@ -6042,7 +6042,7 @@ static int handle_onhook_message(struct skinny_req *req, struct skinnysession *s return 0; } - ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name); + ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name); dumpsub(sub, 0); @@ -6378,7 +6378,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse return 0; } - ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name); + ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name); switch(event) { case SOFTKEY_NONE: @@ -6532,8 +6532,8 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse return 0; } - ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name); - + ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name); + if (sub) { dumpsub(sub, 1); } else { /* No sub, maybe an SLA call */ diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h index 7f907c6e5e..17841096ca 100644 --- a/channels/sip/include/sip.h +++ b/channels/sip/include/sip.h @@ -101,6 +101,7 @@ #define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */ #define SIP_MAX_LINES 256 /*!< Max amount of lines in SIP attachment (like SDP) */ +#define SIP_MAX_PACKET_SIZE 20480 /*!< Max SIP packet size */ #define SIP_MIN_PACKET 4096 /*!< Initialize size of memory to allocate for packets */ #define MAX_HISTORY_ENTRIES 50 /*!< Max entires in the history list for a sip_pvt */ diff --git a/configs/queues.conf.sample b/configs/queues.conf.sample index c9e5e21a47..f7c05181c0 100644 --- a/configs/queues.conf.sample +++ b/configs/queues.conf.sample @@ -71,13 +71,6 @@ monitor-type = MixMonitor ; ;log_membername_as_agent = no ; -; app_queue allows calls to members in a "Unknown" state to be treated as available -; setting check_state_unknown = yes will cause app_queue to query the channel driver -; to better determine the state this only applies to queues with ringinuse set -; appropriately. -; -;check_state_unknown = no -; ;[markq] ; ; A sample call queue diff --git a/funcs/func_devstate.c b/funcs/func_devstate.c index e1f34387a1..6472610c8a 100644 --- a/funcs/func_devstate.c +++ b/funcs/func_devstate.c @@ -132,7 +132,7 @@ static int devstate_write(struct ast_channel *chan, const char *cmd, char *data, 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 @@ static char *handle_cli_devstate_change(struct ast_cli_entry *e, int cmd, struct 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 @@ static int load_module(void) 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; diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 40dbf4381c..e2661870cf 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -888,6 +888,12 @@ enum { * 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 */ diff --git a/include/asterisk/devicestate.h b/include/asterisk/devicestate.h index 66ca2bd1a3..86740bc2fd 100644 --- a/include/asterisk/devicestate.h +++ b/include/asterisk/devicestate.h @@ -61,6 +61,14 @@ enum ast_device_state { 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 @@ enum ast_device_state ast_device_state(const char *device); * \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 @@ enum ast_device_state ast_device_state(const char *device); * \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 @@ int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...) * \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. diff --git a/include/asterisk/event_defs.h b/include/asterisk/event_defs.h index d3514f59c7..10c76d0da0 100644 --- a/include/asterisk/event_defs.h +++ b/include/asterisk/event_defs.h @@ -298,8 +298,14 @@ enum ast_event_ie_type { AST_EVENT_IE_PRESENCE_SUBTYPE = 0x003b, AST_EVENT_IE_PRESENCE_MESSAGE = 0x003c, + /*! + * \brief Event non-cachability flag + * Used by: All events + * Payload type: UINT + */ + AST_EVENT_IE_CACHABLE = 0x003d, /*! \brief Must be the last IE value +1 */ - AST_EVENT_IE_TOTAL = 0x003d, + AST_EVENT_IE_TOTAL = 0x003e, }; /*! diff --git a/main/ccss.c b/main/ccss.c index 47891b8ef2..b1585312ef 100644 --- a/main/ccss.c +++ b/main/ccss.c @@ -638,7 +638,7 @@ static void ccss_notify_device_state_change(const char *device, enum cc_state st "Notification of CCSS state change to '%s', device state '%s' for device '%s'\n", cc_state_to_string(state), ast_devstate2str(devstate), device); - ast_devstate_changed(devstate, "ccss:%s", device); + ast_devstate_changed(devstate, AST_DEVSTATE_CACHABLE, "ccss:%s", device); } #define CC_OFFER_TIMER_DEFAULT 20 /* Seconds */ diff --git a/main/channel.c b/main/channel.c index ec338e7b9d..da8452003b 100644 --- a/main/channel.c +++ b/main/channel.c @@ -2431,7 +2431,7 @@ static void ast_channel_destructor(void *obj) * 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, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name); } ast_channel_nativeformats_set(chan, ast_format_cap_destroy(ast_channel_nativeformats(chan))); @@ -7348,7 +7348,7 @@ int ast_setstate(struct ast_channel *chan, enum ast_channel_state state) /* 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, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name); /* setstate used to conditionally report Newchannel; this is no more */ /*** DOCUMENTATION diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index c7ed84c349..3f892ddef5 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -263,6 +263,7 @@ static void channel_data_add_flags(struct ast_data *tree, ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_RUN)); ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_DONT)); ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS)); + ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE)); } int ast_channel_data_add_structure(struct ast_data *tree, diff --git a/main/devicestate.c b/main/devicestate.c index 3256a7b4f9..4ed51f9e39 100644 --- a/main/devicestate.c +++ b/main/devicestate.c @@ -174,6 +174,7 @@ static AST_RWLIST_HEAD_STATIC(devstate_provs, devstate_prov); struct state_change { AST_LIST_ENTRY(state_change) list; + enum ast_devstate_cache cachable; char device[1]; }; @@ -191,6 +192,7 @@ struct devstate_change { 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 @@ static int getproviderstate(const char *provider, const char *address) 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 @@ static void devstate_event(const char *device, enum ast_device_state state) 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 @@ static void do_state_change(const char *device) ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, ast_devstate2str(state)); - devstate_event(device, state); + devstate_event(device, state, cachable); } -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) { struct state_change *change; @@ -483,14 +490,15 @@ int ast_devstate_changed_literal(enum ast_device_state state, const char *device */ 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_devstate_changed_literal(enum ast_device_state state, const char *device int ast_device_state_changed_literal(const char *dev) { - return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev); + return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, dev); } -int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...) +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 @@ int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...) 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 @@ int ast_device_state_changed(const char *fmt, ...) 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 @@ static void *do_devstate_changes(void *data) /* 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 @@ static void devstate_cache_cb(const struct ast_event *event, void *data) 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 @@ static void process_collection(const char *device, struct change_collection *col 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 @@ static void handle_devstate_change(struct devstate_change *sc) /* 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 @@ static void devstate_change_collector_cb(const struct ast_event *event, void *da 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 @@ static void devstate_change_collector_cb(const struct ast_event *event, void *da 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); diff --git a/main/event.c b/main/event.c index 4c231fe91f..c0295a7f25 100644 --- a/main/event.c +++ b/main/event.c @@ -279,7 +279,7 @@ static const struct ie_map { [AST_EVENT_IE_RECEIVED_HASH] = { AST_EVENT_IE_PLTYPE_STR, "ReceivedHash" }, [AST_EVENT_IE_USING_PASSWORD] = { AST_EVENT_IE_PLTYPE_UINT, "UsingPassword" }, [AST_EVENT_IE_ATTEMPTED_TRANSPORT] = { AST_EVENT_IE_PLTYPE_STR, "AttemptedTransport" }, - + [AST_EVENT_IE_CACHABLE] = { AST_EVENT_IE_PLTYPE_UINT, "Cachable" }, }; const char *ast_event_get_type_name(const struct ast_event *event) diff --git a/main/features.c b/main/features.c index 3b165d71ab..9dab53ce56 100644 --- a/main/features.c +++ b/main/features.c @@ -1248,7 +1248,7 @@ static void notify_metermaids(const char *exten, char *context, enum ast_device_ 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 */ diff --git a/main/http.c b/main/http.c index 55ade21d79..0553e6b465 100644 --- a/main/http.c +++ b/main/http.c @@ -603,6 +603,7 @@ struct ast_variable *ast_http_get_post_vars( int content_length = 0; struct ast_variable *v, *post_vars=NULL, *prev = NULL; char *buf, *var, *val; + int res; for (v = headers; v; v = v->next) { if (!strcasecmp(v->name, "Content-Type")) { @@ -615,20 +616,28 @@ struct ast_variable *ast_http_get_post_vars( for (v = headers; v; v = v->next) { if (!strcasecmp(v->name, "Content-Length")) { - content_length = atoi(v->value) + 1; + content_length = atoi(v->value); break; } } - if (!content_length) { + if (content_length <= 0) { return NULL; } - buf = ast_alloca(content_length); - if (!fgets(buf, content_length, ser->f)) { + buf = ast_malloc(content_length + 1); + if (!buf) { return NULL; } + res = fread(buf, 1, content_length, ser->f); + if (res < content_length) { + /* Error, distinguishable by ferror() or feof(), but neither + * is good. */ + goto done; + } + buf[content_length] = '\0'; + while ((val = strsep(&buf, "&"))) { var = strsep(&val, "="); if (val) { @@ -646,6 +655,9 @@ struct ast_variable *ast_http_get_post_vars( prev = v; } } + +done: + ast_free(buf); return post_vars; } diff --git a/res/pjproject/aconfigure b/res/pjproject/aconfigure index 73683e805b..64cc6f014d 100755 --- a/res/pjproject/aconfigure +++ b/res/pjproject/aconfigure @@ -2401,7 +2401,7 @@ test -n "$target_alias" && program_prefix=${target_alias}- ac_config_headers="$ac_config_headers pjlib/include/pj/compat/os_auto.h pjlib/include/pj/compat/m_auto.h pjmedia/include/pjmedia/config_auto.h pjmedia/include/pjmedia-codec/config_auto.h pjsip/include/pjsip/sip_autoconf.h" -ac_config_files="$ac_config_files build.mak build/os-auto.mak build/cc-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak third_party/build/portaudio/os-auto.mak" +ac_config_files="$ac_config_files build.mak build/os-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak third_party/build/portaudio/os-auto.mak" @@ -7799,7 +7799,6 @@ do "pjsip/include/pjsip/sip_autoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS pjsip/include/pjsip/sip_autoconf.h" ;; "build.mak") CONFIG_FILES="$CONFIG_FILES build.mak" ;; "build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES build/os-auto.mak" ;; - "build/cc-auto.mak") CONFIG_FILES="$CONFIG_FILES build/cc-auto.mak" ;; "pjlib/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjlib/build/os-auto.mak" ;; "pjlib-util/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjlib-util/build/os-auto.mak" ;; "pjmedia/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjmedia/build/os-auto.mak" ;; diff --git a/res/pjproject/aconfigure.ac b/res/pjproject/aconfigure.ac index 1de41faafa..a19b84eeba 100644 --- a/res/pjproject/aconfigure.ac +++ b/res/pjproject/aconfigure.ac @@ -13,7 +13,6 @@ AC_CONFIG_HEADER([pjlib/include/pj/compat/os_auto.h ]) AC_CONFIG_FILES([build.mak build/os-auto.mak - build/cc-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak diff --git a/res/pjproject/build/common.mak b/res/pjproject/build/common.mak index ad6df03e94..d6000078ea 100644 --- a/res/pjproject/build/common.mak +++ b/res/pjproject/build/common.mak @@ -16,15 +16,6 @@ include $(PJDIR)/build/cc-$(CC_NAME).mak # -include cc-$(CC_NAME).mak -# -# Include auto configured compiler specification. -# This will override the compiler settings above. -# Currently this is made OPTIONAL, to prevent people -# from getting errors because they don't re-run ./configure -# after downloading new PJSIP. -# --include $(PJDIR)/build/cc-auto.mak - # # Include global machine specific definitions # diff --git a/res/res_calendar.c b/res/res_calendar.c index 8c349946bb..13c95d9a9d 100644 --- a/res/res_calendar.c +++ b/res/res_calendar.c @@ -611,9 +611,9 @@ static struct ast_calendar_event *destroy_event(struct ast_calendar_event *event * 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); } } @@ -871,9 +871,9 @@ static int calendar_devstate_change(const void *data) /* 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); diff --git a/res/res_jabber.c b/res/res_jabber.c index 8eed3fb189..8692de1884 100644 --- a/res/res_jabber.c +++ b/res/res_jabber.c @@ -352,7 +352,7 @@ static char *aji_cli_create_leafnode(struct ast_cli_entry *e, int cmd, 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); static int aji_handle_pubsub_error(void *data, ikspak *pak); static int aji_handle_pubsub_event(void *data, ikspak *pak); static void aji_pubsub_subscribe(struct aji_client *client, const char *node); @@ -366,7 +366,7 @@ static void aji_publish_mwi(struct aji_client *client, const char *mailbox, static void aji_devstate_cb(const struct ast_event *ast_event, void *data); static void aji_mwi_cb(const struct ast_event *ast_event, void *data); static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node, - const char *event_type); + const char *event_type, unsigned int cachable); /* No transports in this version */ /* static int aji_create_transport(char *label, struct aji_client *client); @@ -776,7 +776,7 @@ static struct ast_custom_function jabberstatus_function = { */ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen) { - char *aux = NULL, *parse = NULL; + char *parse = NULL; int timeout; int jidlen, resourcelen; struct timeval start; @@ -893,7 +893,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch continue; } found = 1; - aux = ast_strdupa(tmp->message); + ast_copy_string(buf, tmp->message, buflen); AST_LIST_REMOVE_CURRENT(list); aji_message_destroy(tmp); break; @@ -918,7 +918,6 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid); return -1; } - ast_copy_string(buf, aux, buflen); return 0; } @@ -3267,6 +3266,7 @@ static void aji_devstate_cb(const struct ast_event *ast_event, void *data) { const char *device; const char *device_state; + unsigned int cachable; struct aji_client *client; if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(ast_event, AST_EVENT_IE_EID))) { @@ -3278,7 +3278,8 @@ static void aji_devstate_cb(const struct ast_event *ast_event, void *data) client = ASTOBJ_REF((struct aji_client *) data); device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE); device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE)); - aji_publish_device_state(client, device, device_state); + cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE); + aji_publish_device_state(client, device, device_state, cachable); ASTOBJ_UNREF(client, ast_aji_client_destroy); } @@ -3318,11 +3319,13 @@ static void aji_init_event_distribution(struct aji_client *client) */ static int aji_handle_pubsub_event(void *data, ikspak *pak) { - char *item_id, *device_state, *context; + char *item_id, *device_state, *context, *cachable_str; int oldmsgs, newmsgs; iks *item, *item_content; struct ast_eid pubsub_eid; struct ast_event *event; + unsigned int cachable = AST_DEVSTATE_CACHABLE; + item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item"); if (!item) { ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n"); @@ -3337,11 +3340,14 @@ static int aji_handle_pubsub_event(void *data, ikspak *pak) } if (!strcasecmp(iks_name(item_content), "state")) { device_state = iks_find_cdata(item, "state"); + if ((cachable_str = iks_find_cdata(item, "cachable"))) { + sscanf(cachable_str, "%30d", &cachable); + } if (!(event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE, - AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE, - AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID, - AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid), - AST_EVENT_IE_END))) { + AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE, + AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID, + AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid), + AST_EVENT_IE_END))) { return IKS_FILTER_EAT; } } else if (!strcasecmp(iks_name(item_content), "mailbox")) { @@ -3361,7 +3367,13 @@ static int aji_handle_pubsub_event(void *data, ikspak *pak) iks_name(item_content)); return IKS_FILTER_EAT; } - ast_event_queue_and_cache(event); + + if (cachable == AST_DEVSTATE_CACHABLE) { + ast_event_queue_and_cache(event); + } else { + ast_event_queue(event); + } + return IKS_FILTER_EAT; } @@ -3436,7 +3448,7 @@ static void aji_pubsub_subscribe(struct aji_client *client, const char *node) * \return iks * */ static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node, - const char *event_type) + const char *event_type, unsigned int cachable) { iks *request = aji_pubsub_iq_create(client, "set"); iks *pubsub, *publish, *item; @@ -3450,8 +3462,24 @@ static iks* aji_build_publish_skeleton(struct aji_client *client, const char *no } item = iks_insert(publish, "item"); iks_insert_attrib(item, "id", node); - return item; + if (cachable == AST_DEVSTATE_NOT_CACHABLE) { + iks *options, *x, *field_form_type, *field_persist; + + options = iks_insert(pubsub, "publish-options"); + x = iks_insert(options, "x"); + iks_insert_attrib(x, "xmlns", "jabber:x:data"); + iks_insert_attrib(x, "type", "submit"); + field_form_type = iks_insert(x, "field"); + iks_insert_attrib(field_form_type, "var", "FORM_TYPE"); + iks_insert_attrib(field_form_type, "type", "hidden"); + iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0); + field_persist = iks_insert(x, "field"); + iks_insert_attrib(field_persist, "var", "pubsub#persist_items"); + iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1); + } + + return item; } /*! @@ -3462,11 +3490,11 @@ static iks* aji_build_publish_skeleton(struct aji_client *client, const char *no * \return void */ static void aji_publish_device_state(struct aji_client *client, const char *device, - const char *device_state) + const char *device_state, unsigned int cachable) { - iks *request = aji_build_publish_skeleton(client, device, "device_state"); + iks *request = aji_build_publish_skeleton(client, device, "device_state", cachable); iks *state; - char eid_str[20]; + char eid_str[20], cachable_str[2]; if (ast_test_flag(&pubsubflags, AJI_PUBSUB_AUTOCREATE)) { if (ast_test_flag(&pubsubflags, AJI_XEP0248)) { aji_create_pubsub_node(client, "leaf", device, "device_state"); @@ -3478,6 +3506,8 @@ static void aji_publish_device_state(struct aji_client *client, const char *devi state = iks_insert(request, "state"); iks_insert_attrib(state, "xmlns", "http://asterisk.org"); iks_insert_attrib(state, "eid", eid_str); + snprintf(cachable_str, sizeof(cachable_str), "%u", cachable); + iks_insert_attrib(state, "cachable", cachable_str); iks_insert_cdata(state, device_state, strlen(device_state)); ast_aji_send(client, iks_root(request)); iks_delete(request); @@ -3497,7 +3527,7 @@ static void aji_publish_mwi(struct aji_client *client, const char *mailbox, char eid_str[20]; iks *mailbox_node, *request; snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context); - request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting"); + request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting", 1); ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default); mailbox_node = iks_insert(request, "mailbox"); iks_insert_attrib(mailbox_node, "xmlns", "http://asterisk.org"); diff --git a/res/res_xmpp.c b/res/res_xmpp.c index 4f7c3b02fb..1a73ca9e8a 100644 --- a/res/res_xmpp.c +++ b/res/res_xmpp.c @@ -919,7 +919,7 @@ static iks* xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *ty * \return iks * */ static iks* xmpp_pubsub_build_publish_skeleton(struct ast_xmpp_client *client, const char *node, - const char *event_type) + const char *event_type, unsigned int cachable) { RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup); iks *request, *pubsub, *publish, *item; @@ -935,6 +935,22 @@ static iks* xmpp_pubsub_build_publish_skeleton(struct ast_xmpp_client *client, c item = iks_insert(publish, "item"); iks_insert_attrib(item, "id", node); + if (cachable == AST_DEVSTATE_NOT_CACHABLE) { + iks *options, *x, *field_form_type, *field_persist; + + options = iks_insert(pubsub, "publish-options"); + x = iks_insert(options, "x"); + iks_insert_attrib(x, "xmlns", "jabber:x:data"); + iks_insert_attrib(x, "type", "submit"); + field_form_type = iks_insert(x, "field"); + iks_insert_attrib(field_form_type, "var", "FORM_TYPE"); + iks_insert_attrib(field_form_type, "type", "hidden"); + iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0); + field_persist = iks_insert(x, "field"); + iks_insert_attrib(field_persist, "var", "pubsub#persist_items"); + iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1); + } + return item; } @@ -1107,7 +1123,7 @@ static void xmpp_pubsub_publish_mwi(struct ast_xmpp_client *client, const char * snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context); - if (!(request = xmpp_pubsub_build_publish_skeleton(client, full_mailbox, "message_waiting"))) { + if (!(request = xmpp_pubsub_build_publish_skeleton(client, full_mailbox, "message_waiting", AST_DEVSTATE_CACHABLE))) { return; } @@ -1131,13 +1147,13 @@ static void xmpp_pubsub_publish_mwi(struct ast_xmpp_client *client, const char * * \return void */ static void xmpp_pubsub_publish_device_state(struct ast_xmpp_client *client, const char *device, - const char *device_state) + const char *device_state, unsigned int cachable) { RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup); iks *request, *state; - char eid_str[20]; + char eid_str[20], cachable_str[2]; - if (!cfg || !cfg->global || !(request = xmpp_pubsub_build_publish_skeleton(client, device, "device_state"))) { + if (!cfg || !cfg->global || !(request = xmpp_pubsub_build_publish_skeleton(client, device, "device_state", cachable))) { return; } @@ -1153,6 +1169,8 @@ static void xmpp_pubsub_publish_device_state(struct ast_xmpp_client *client, con state = iks_insert(request, "state"); iks_insert_attrib(state, "xmlns", "http://asterisk.org"); iks_insert_attrib(state, "eid", eid_str); + snprintf(cachable_str, sizeof(cachable_str), "%u", cachable); + iks_insert_attrib(state, "cachable", cachable_str); iks_insert_cdata(state, device_state, strlen(device_state)); ast_xmpp_client_send(client, iks_root(request)); iks_delete(request); @@ -1195,6 +1213,7 @@ static void xmpp_pubsub_devstate_cb(const struct ast_event *ast_event, void *dat { struct ast_xmpp_client *client = data; const char *device, *device_state; + unsigned int cachable; if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(ast_event, AST_EVENT_IE_EID))) { /* If the event didn't originate from this server, don't send it back out. */ @@ -1204,7 +1223,8 @@ static void xmpp_pubsub_devstate_cb(const struct ast_event *ast_event, void *dat device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE); device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE)); - xmpp_pubsub_publish_device_state(client, device, device_state); + cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE); + xmpp_pubsub_publish_device_state(client, device, device_state, cachable); } /*! @@ -1287,11 +1307,12 @@ static void xmpp_pubsub_subscribe(struct ast_xmpp_client *client, const char *no */ static int xmpp_pubsub_handle_event(void *data, ikspak *pak) { - char *item_id, *device_state, *context; + char *item_id, *device_state, *context, *cachable_str; int oldmsgs, newmsgs; iks *item, *item_content; struct ast_eid pubsub_eid; struct ast_event *event; + unsigned int cachable = AST_DEVSTATE_CACHABLE; item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item"); if (!item) { ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n"); @@ -1306,6 +1327,9 @@ static int xmpp_pubsub_handle_event(void *data, ikspak *pak) } if (!strcasecmp(iks_name(item_content), "state")) { device_state = iks_find_cdata(item, "state"); + if ((cachable_str = iks_find_cdata(item, "cachable"))) { + sscanf(cachable_str, "%30d", &cachable); + } if (!(event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE, AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID, @@ -1330,7 +1354,13 @@ static int xmpp_pubsub_handle_event(void *data, ikspak *pak) iks_name(item_content)); return IKS_FILTER_EAT; } - ast_event_queue_and_cache(event); + + if (cachable == AST_DEVSTATE_CACHABLE) { + ast_event_queue_and_cache(event); + } else { + ast_event_queue(event); + } + return IKS_FILTER_EAT; } @@ -1832,7 +1862,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch { RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup); RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup); - char *aux = NULL, *parse = NULL; + char *parse = NULL; int timeout, jidlen, resourcelen, found = 0; struct timeval start; long diff = 0; @@ -1946,7 +1976,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch continue; } found = 1; - aux = ast_strdupa(message->message); + ast_copy_string(buf, message->message, buflen); AST_LIST_REMOVE_CURRENT(list); xmpp_message_destroy(message); break; @@ -1970,7 +2000,6 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid); return -1; } - ast_copy_string(buf, aux, buflen); return 0; }