aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2009-03-11 21:55:24 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2009-03-11 21:55:24 +0000
commitc2da464fe3c17006f0e1a7260b8f302852be11e2 (patch)
tree13e401776948a6ca9a80a958ba27476fe17b3981 /main
parent2d49839e28139cf36944a57167969ba3d2370171 (diff)
Merged revisions 181424 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r181424 | russell | 2009-03-11 16:49:29 -0500 (Wed, 11 Mar 2009) | 17 lines Merged revisions 181423 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r181423 | russell | 2009-03-11 16:42:58 -0500 (Wed, 11 Mar 2009) | 9 lines Make code that updates BRIDGEPEER variable thread-safe. It is not safe to read the name field of an ast_channel without the channel locked. This patch fixes some places in channel.c where this was being done, and lead to crashes related to masquerades. (closes issue #14623) Reported by: guillecabeza ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@181425 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/channel.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/main/channel.c b/main/channel.c
index e7b2c8626..2c9724ad9 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -4527,6 +4527,29 @@ static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, st
S_OR(c1->cid.cid_num, ""));
}
+static void update_bridgepeer(struct ast_channel *c0, struct ast_channel *c1)
+{
+ const char *c0_name;
+ const char *c1_name;
+
+ ast_channel_lock(c1);
+ c1_name = ast_strdupa(c1->name);
+ ast_channel_unlock(c1);
+
+ ast_channel_lock(c0);
+ if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
+ pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
+ }
+ c0_name = ast_strdupa(c0->name);
+ ast_channel_unlock(c0);
+
+ ast_channel_lock(c1);
+ if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
+ pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
+ }
+ ast_channel_unlock(c1);
+}
+
/*! \brief Bridge two channels together */
enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
@@ -4635,7 +4658,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
res = 0;
break;
}
-
+
if (!to) {
if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
int t = (time_left_ms + 500) / 1000; /* round to nearest second */
@@ -4662,7 +4685,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
continue;
}
-
+
/* Stop if we're a zombie or need a soft hangup */
if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
@@ -4678,17 +4701,14 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
ast_check_hangup(c1) ? "Yes" : "No");
break;
}
-
- /* See if the BRIDGEPEER variable needs to be updated */
- if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
- pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
- if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
- pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
+
+ update_bridgepeer(c0, c1);
+
if (c0->tech->get_pvt_uniqueid)
pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0->tech->get_pvt_uniqueid(c0));
if (c1->tech->get_pvt_uniqueid)
pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1->tech->get_pvt_uniqueid(c1));
-
+
if (c0->tech->bridge &&
(c0->tech->bridge == c1->tech->bridge) &&
!nativefailed && !c0->monitor && !c1->monitor &&
@@ -4734,7 +4754,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
break;
}
}
-
+
if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
(c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
!(c0->generator || c1->generator)) {
@@ -4747,10 +4767,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
o1nativeformats = c1->nativeformats;
}
- if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
- pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
- if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
- pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
+ update_bridgepeer(c0, c1);
res = ast_generic_bridge(c0, c1, config, fo, rc, config->nexteventts);
if (res != AST_BRIDGE_RETRY) {