summaryrefslogtreecommitdiff
path: root/main/channel.c
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-01-14 15:58:01 +0000
committerDavid M. Lee <dlee@digium.com>2013-01-14 15:58:01 +0000
commitd3bb2506a17ee210f893dd57b9dbc69f235de87e (patch)
tree6578ee28f450a1b833f90649dd910dcec09fd8ba /main/channel.c
parenta91a2891540d72ec6653796ad7a332539e794932 (diff)
Gently reduce masquerade insanity
Masquerades are an insane implementation detail within Asterisk. It generates a number of useless and confusing events, and manipulates channels in a way that semantically doesn't make sense. I've given a fairly thorough review of masquerade code and its usage on the wiki at https://wiki.asterisk.org/wiki/x/IwBRAQ. While ultimately it makes the most sense to abandon masquerades altogether, it will take some time to completely irradicate. Even then, there may always be code that's not worth rewriting to get rid of the masquerade. This patch does two things to make masquerades slightly less insane: * When swapping the names of the original and clone channel, only emit a single rename event of original -> original<ZOMBIE>. The original code issued three rename events to accomplish the same end. * In addition to swapping the names of the channels, also swap their uniqueid's. This allows the 'Uniqueid' field to be used as a stable identifier for a channel from and external interface, such as AMI. Review: https://reviewboard.asterisk.org/r/2266/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@379023 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/main/channel.c b/main/channel.c
index 0023946cf..048975d12 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -6865,10 +6865,8 @@ int ast_do_masquerade(struct ast_channel *original)
struct ast_format rformat;
struct ast_format wformat;
struct ast_format tmp_format;
- char newn[AST_CHANNEL_NAME];
- char orig[AST_CHANNEL_NAME];
- char masqn[AST_CHANNEL_NAME];
- char zombn[AST_CHANNEL_NAME];
+ char tmp_name[AST_CHANNEL_NAME];
+ const char *tmp_id;
char clone_sending_dtmf_digit;
struct timeval clone_sending_dtmf_tv;
@@ -6971,12 +6969,18 @@ int ast_do_masquerade(struct ast_channel *original)
<parameter name="Clone">
<para>The name of the channel whose information will be going into the Original channel.</para>
</parameter>
+ <parameter name="CloneUniqueid">
+ <para>The uniqueid of the channel whose information will be going into the Original channel.</para>
+ </parameter>
<parameter name="CloneState">
<para>The current state of the clone channel.</para>
</parameter>
<parameter name="Original">
<para>The name of the channel whose information will be replaced by the Clone channel's information.</para>
</parameter>
+ <parameter name="OriginalUniqueid">
+ <para>The uniqueid of the channel whose information will be replaced by the Clone channel's information.</para>
+ </parameter>
<parameter name="OriginalState">
<para>The current state of the original channel.</para>
</parameter>
@@ -6985,10 +6989,12 @@ int ast_do_masquerade(struct ast_channel *original)
***/
ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
"Clone: %s\r\n"
+ "CloneUniqueid: %s\r\n"
"CloneState: %s\r\n"
"Original: %s\r\n"
+ "OriginalUniqueid: %s\r\n"
"OriginalState: %s\r\n",
- ast_channel_name(clonechan), ast_state2str(ast_channel_state(clonechan)), ast_channel_name(original), ast_state2str(ast_channel_state(original)));
+ ast_channel_name(clonechan), ast_channel_uniqueid(clonechan), ast_state2str(ast_channel_state(clonechan)), ast_channel_name(original), ast_channel_uniqueid(original), ast_state2str(ast_channel_state(original)));
/*
* Remember the original read/write formats. We turn off any
@@ -7003,18 +7009,23 @@ int ast_do_masquerade(struct ast_channel *original)
clone_sending_dtmf_digit = ast_channel_sending_dtmf_digit(clonechan);
clone_sending_dtmf_tv = ast_channel_sending_dtmf_tv(clonechan);
- /* Save the original name */
- ast_copy_string(orig, ast_channel_name(original), sizeof(orig));
- /* Save the new name */
- ast_copy_string(newn, ast_channel_name(clonechan), sizeof(newn));
- /* Create the masq name */
- snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
+ /* Swap uniqueid's of the channels. This needs to happen before channel renames,
+ * so rename events get the proper id's.
+ */
+ tmp_id = ast_strdupa(ast_channel_uniqueid(clonechan));
+ ast_channel_uniqueid_set(clonechan, ast_channel_uniqueid(original));
+ ast_channel_uniqueid_set(original, tmp_id);
- /* Mangle the name of the clone channel */
- __ast_change_name_nolink(clonechan, masqn);
+ /* Swap channel names. This uses ast_channel_name_set directly, so we
+ * don't get any spurious rename events.
+ */
+ ast_copy_string(tmp_name, ast_channel_name(clonechan), sizeof(tmp_name));
+ ast_channel_name_set(clonechan, ast_channel_name(original));
+ ast_channel_name_set(original, tmp_name);
- /* Copy the name from the clone channel */
- __ast_change_name_nolink(original, newn);
+ /* Now zombify the clonechan. This gets a real rename event. */
+ snprintf(tmp_name, sizeof(tmp_name), "%s<ZOMBIE>", ast_channel_name(clonechan)); /* quick, hide the brains! */
+ __ast_change_name_nolink(clonechan, tmp_name);
/* share linked id's */
ast_channel_set_linkgroup(original, clonechan);
@@ -7081,10 +7092,6 @@ int ast_do_masquerade(struct ast_channel *original)
ast_channel_state_set(original, ast_channel_state(clonechan));
ast_channel_state_set(clonechan, origstate);
- /* Mangle the name of the clone channel */
- snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */
- __ast_change_name_nolink(clonechan, zombn);
-
/* Update the type. */
t_pvt = ast_channel_monitor(original);
ast_channel_monitor_set(original, ast_channel_monitor(clonechan));