Stasis: Fix StasisStart/End order and missing events

This corrects several bugs that currently exist in the stasis
application code.

* After a masquerade, the resulting channels have channel topics that
  do not match their uniqueids
** Masquerades now swap channel topics appropriately
* StasisStart and StasisEnd messages are leaked to observer
  applications due to being published on channel topics
** StasisStart and StasisEnd publishing is now properly restricted
   to controlling apps via app topics
* Race conditions exist where StasisStart and StasisEnd messages due to
  a masquerade may be received out of order due to being published on
  different topics
** These messages are now published directly on the app topic so this
   is now a non-issue
* StasisEnds are sometimes missing when sent due to masquerades and
  bridge swaps into and out of Stasis()
** This was due to StasisEnd processing adjusting message-sent flags
   after Stasis() had already exited and Stasis() had been re-entered
** This was corrected by adjusting these flags prior to sending the
   message while the initial Stasis() application was still shutting
   down

Review: https://reviewboard.asterisk.org/r/4213/
ASTERISK-24537 #close
Reported by: Matt DiMeo
........

Merged revisions 429061 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@429062 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kinsey Moore
2014-12-08 15:43:14 +00:00
parent 7fd1227202
commit 55c9a46abd
7 changed files with 47 additions and 95 deletions

View File

@@ -302,10 +302,6 @@ static void sub_default_handler(void *data, struct stasis_subscription *sub,
call_forwarded_handler(app, message);
}
if (stasis_message_type(message) == app_end_message_type()) {
app_end_message_handler(message);
}
/* By default, send any message that has a JSON representation */
json = stasis_message_to_json(message, stasis_app_get_sanitizer());
if (!json) {
@@ -1128,30 +1124,6 @@ int app_is_subscribed_channel_id(struct stasis_app *app, const char *channel_id)
return forwards != NULL;
}
int app_replace_channel_forwards(struct stasis_app *app, const char *old_id, struct ast_channel *new_chan)
{
RAII_VAR(struct app_forwards *, old_forwards, NULL, ao2_cleanup);
struct app_forwards *new_forwards;
old_forwards = ao2_find(app->forwards, old_id, OBJ_SEARCH_KEY | OBJ_UNLINK);
if (!old_forwards) {
return -1;
}
new_forwards = forwards_create_channel(app, new_chan);
if (!new_forwards) {
return -1;
}
new_forwards->interested = old_forwards->interested;
ao2_link_flags(app->forwards, new_forwards, 0);
ao2_cleanup(new_forwards);
/* Clean up old forwards */
forwards_unsubscribe(old_forwards);
return 0;
}
static void *channel_find(const struct stasis_app *app, const char *id)
{
return ast_channel_get_by_name(id);