summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2016-04-13 13:20:23 -0500
committerRichard Mudgett <rmudgett@digium.com>2016-04-22 15:45:47 -0500
commit71dfa355403e41850fd7c4cb4228626e5d9476b9 (patch)
treedc681da696cd8141907768755e604010de0e7af8 /bridges
parent57c908c7a59056f6ea66ebe1453f2454be837233 (diff)
bridge_softmix.c: Fix crash if channel fails to join mixing tech.
softmix_bridge_join() failed because of an allocation failure. To address this, the softmix bridge technology now checks if the channel failed to join softmix successfully. In addition, the bridge now begins the process of kicking the channel out of the bridge so we don't have channels partially in the bridge for very long. * Fix the test_channel_feature_hooks.c unit tests. The test channel must have a valid codec to join the simple_bridge technology. This patch makes joining a bridge more strict by not allowing partially joined channels to remain in the bridge. Change-Id: I97e2ade6a2bcd1214f24fb839fda948825b61a2b
Diffstat (limited to 'bridges')
-rw-r--r--bridges/bridge_softmix.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c
index bad3e43c4..0991e2897 100644
--- a/bridges/bridge_softmix.c
+++ b/bridges/bridge_softmix.c
@@ -359,6 +359,9 @@ static void set_softmix_bridge_data(int rate, int interval, struct ast_bridge_ch
struct ast_format *slin_format;
int setup_fail;
+ /* The callers have already ensured that sc is never NULL. */
+ ast_assert(sc != NULL);
+
slin_format = ast_format_cache_get_slin_by_rate(rate);
ast_mutex_lock(&sc->lock);
@@ -714,7 +717,7 @@ static int softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_cha
{
int res = 0;
- if (!bridge->tech_pvt || (bridge_channel && !bridge_channel->tech_pvt)) {
+ if (!bridge->tech_pvt || !bridge_channel || !bridge_channel->tech_pvt) {
/* "Accept" the frame and discard it. */
return 0;
}
@@ -984,6 +987,11 @@ static int softmix_mixing_loop(struct ast_bridge *bridge)
AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
struct softmix_channel *sc = bridge_channel->tech_pvt;
+ if (!sc) {
+ /* This channel failed to join successfully. */
+ continue;
+ }
+
/* Update the sample rate to match the bridge's native sample rate if necessary. */
if (update_all_rates) {
set_softmix_bridge_data(softmix_data->internal_rate, softmix_data->internal_mixing_interval, bridge_channel, 1);
@@ -1019,7 +1027,8 @@ static int softmix_mixing_loop(struct ast_bridge *bridge)
AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
struct softmix_channel *sc = bridge_channel->tech_pvt;
- if (bridge_channel->suspended) {
+ if (!sc || bridge_channel->suspended) {
+ /* This channel failed to join successfully or is suspended. */
continue;
}