mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
bridging: Ensure locking during snapshot creation
While the vast majority of bridge snapshot creation is locked properly, there are currently some instances that are not. This adds the missing locking to ensure bridge state is not malleable during snapshot creation. (closes issue ASTERISK-22904) Review: https://reviewboard.asterisk.org/r/3415/ Reported by: Matt Jordan git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@412193 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -615,7 +615,10 @@ static struct stasis_message *create_bridge_snapshot_message(struct ast_bridge *
|
||||
{
|
||||
RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
|
||||
|
||||
ast_bridge_lock(bridge);
|
||||
snapshot = ast_bridge_snapshot_create(bridge);
|
||||
ast_bridge_unlock(bridge);
|
||||
|
||||
if (!snapshot) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -689,7 +692,9 @@ struct ast_bridge *bridge_register(struct ast_bridge *bridge)
|
||||
{
|
||||
if (bridge) {
|
||||
bridge->construction_completed = 1;
|
||||
ast_bridge_lock(bridge);
|
||||
ast_bridge_publish_state(bridge);
|
||||
ast_bridge_unlock(bridge);
|
||||
if (!ao2_link(bridges, bridge)) {
|
||||
ast_bridge_destroy(bridge, 0);
|
||||
bridge = NULL;
|
||||
@@ -4067,7 +4072,9 @@ static void publish_blind_transfer(int is_external, enum ast_transfer_result res
|
||||
struct ast_bridge_channel_pair pair;
|
||||
pair.channel = transferer;
|
||||
pair.bridge = bridge;
|
||||
ast_bridge_lock(bridge);
|
||||
ast_bridge_publish_blind_transfer(is_external, result, &pair, context, exten);
|
||||
ast_bridge_unlock(bridge);
|
||||
}
|
||||
|
||||
enum ast_transfer_result ast_bridge_transfer_blind(int is_external,
|
||||
@@ -4294,7 +4301,7 @@ enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_tra
|
||||
RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
|
||||
struct ast_bridge *the_bridge;
|
||||
struct ast_bridge *the_bridge = NULL;
|
||||
struct ast_channel *chan_bridged;
|
||||
struct ast_channel *chan_unbridged;
|
||||
int transfer_prohibited;
|
||||
@@ -4412,8 +4419,10 @@ enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_tra
|
||||
set_transfer_variables_all(to_transferee, channels, 1);
|
||||
|
||||
if (do_bridge_transfer) {
|
||||
res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, &publication);
|
||||
goto end;
|
||||
ast_bridge_lock(the_bridge);
|
||||
res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, &publication);
|
||||
ast_bridge_unlock(the_bridge);
|
||||
goto end;
|
||||
}
|
||||
|
||||
transferee = get_transferee(channels, chan_bridged);
|
||||
@@ -4430,7 +4439,9 @@ enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_tra
|
||||
|
||||
ast_bridge_remove(the_bridge, chan_bridged);
|
||||
|
||||
ast_bridge_lock(the_bridge);
|
||||
publish_attended_transfer_app(&publication, app);
|
||||
ast_bridge_unlock(the_bridge);
|
||||
res = AST_BRIDGE_TRANSFER_SUCCESS;
|
||||
|
||||
end:
|
||||
@@ -4438,7 +4449,20 @@ end:
|
||||
* All failure paths have deferred publishing a stasis message until this point
|
||||
*/
|
||||
if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
|
||||
if (to_transferee_bridge && to_target_bridge) {
|
||||
ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
|
||||
} else if (the_bridge) {
|
||||
ast_bridge_lock(the_bridge);
|
||||
}
|
||||
|
||||
publish_attended_transfer_fail(&publication, res);
|
||||
|
||||
if (to_transferee_bridge && to_target_bridge) {
|
||||
ast_bridge_unlock(to_transferee_bridge);
|
||||
ast_bridge_unlock(to_target_bridge);
|
||||
} else if (the_bridge) {
|
||||
ast_bridge_unlock(the_bridge);
|
||||
}
|
||||
}
|
||||
stasis_publish_data_cleanup(&publication);
|
||||
return res;
|
||||
|
@@ -1534,8 +1534,11 @@ static void publish_transfer_success(struct attended_transfer_properties *props)
|
||||
.bridge = props->target_bridge,
|
||||
};
|
||||
|
||||
ast_bridge_lock_both(transferee.bridge, transfer_target.bridge);
|
||||
ast_bridge_publish_attended_transfer_bridge_merge(0, AST_BRIDGE_TRANSFER_SUCCESS,
|
||||
&transferee, &transfer_target, props->transferee_bridge);
|
||||
ast_bridge_unlock(transferee.bridge);
|
||||
ast_bridge_unlock(transfer_target.bridge);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1556,8 +1559,11 @@ static void publish_transfer_threeway(struct attended_transfer_properties *props
|
||||
.bridge = props->transferee_bridge,
|
||||
};
|
||||
|
||||
ast_bridge_lock_both(transferee.bridge, transfer_target.bridge);
|
||||
ast_bridge_publish_attended_transfer_threeway(0, AST_BRIDGE_TRANSFER_SUCCESS,
|
||||
&transferee, &transfer_target, &threeway);
|
||||
ast_bridge_unlock(transferee.bridge);
|
||||
ast_bridge_unlock(transfer_target.bridge);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1574,8 +1580,11 @@ static void publish_transfer_fail(struct attended_transfer_properties *props)
|
||||
.bridge = props->target_bridge,
|
||||
};
|
||||
|
||||
ast_bridge_lock_both(transferee.bridge, transfer_target.bridge);
|
||||
ast_bridge_publish_attended_transfer_fail(0, AST_BRIDGE_TRANSFER_FAIL,
|
||||
&transferee, &transfer_target);
|
||||
ast_bridge_unlock(transferee.bridge);
|
||||
ast_bridge_unlock(transfer_target.bridge);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
Reference in New Issue
Block a user