diff options
author | Richard Mudgett <rmudgett@digium.com> | 2013-10-22 17:06:21 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2013-10-22 17:06:21 +0000 |
commit | d5db1f76f84f485bb0854b1ed986a04edf72e4c6 (patch) | |
tree | 4416c04acc96e89325c994a07965d4abf3e3327e /main/bridge_channel.c | |
parent | 8f03a463e1e04384fc8d5609d318566de2c7437b (diff) |
Bridging: Fix orphaned bridge if neither of the joining channels can join.
The original issue noted that the bridge is orphaned when res_parking.so
is not loaded and a call uses the dial kK flags.
A similar issue happens when only one of the park flags is used. In this
case you have the bridge with one or the other channel left in it. The
channel and bridge will stay around until the channel hangs up.
* Fixed the initial bridge channel push failure to act as if the channel
were kicked out of the bridge. The bridge then decides if it needs to be
dissolved.
(closes issue ASTERISK-22629)
Reported by: Kevin Harwell
Review: https://reviewboard.asterisk.org/r/2928/
........
Merged revisions 401424 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@401425 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/bridge_channel.c')
-rw-r--r-- | main/bridge_channel.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/main/bridge_channel.c b/main/bridge_channel.c index f8277384f..9256a75d0 100644 --- a/main/bridge_channel.c +++ b/main/bridge_channel.c @@ -1566,7 +1566,6 @@ int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel) || ast_bridge_channel_establish_roles(bridge_channel)) { ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n", bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan)); - ast_bridge_features_remove(bridge_channel->features, AST_BRIDGE_HOOK_REMOVE_ON_PULL); return -1; } bridge_channel->in_bridge = 1; @@ -1969,8 +1968,7 @@ int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel) */ ast_bridge_lock(bridge_channel->bridge); - /* Make sure we're still good to be put into a bridge - */ + /* Make sure we're still good to be put into a bridge */ ast_channel_lock(bridge_channel->chan); if (ast_channel_internal_bridge(bridge_channel->chan) || ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_ZOMBIE)) { @@ -1993,8 +1991,14 @@ int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel) } if (bridge_channel_internal_push(bridge_channel)) { - ast_bridge_channel_leave_bridge(bridge_channel, - BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_channel->bridge->cause); + int cause = bridge_channel->bridge->cause; + + ast_bridge_unlock(bridge_channel->bridge); + ast_bridge_channel_kick(bridge_channel, cause); + ast_bridge_channel_lock_bridge(bridge_channel); + ast_bridge_features_remove(bridge_channel->features, + AST_BRIDGE_HOOK_REMOVE_ON_PULL); + bridge_channel_dissolve_check(bridge_channel); res = -1; } bridge_reconfigured(bridge_channel->bridge, !bridge_channel->inhibit_colp); |