summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/app_dial.c8
-rw-r--r--apps/app_queue.c11
-rw-r--r--main/features.c23
3 files changed, 23 insertions, 19 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c
index d76a0cf6a..b43674088 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -2395,14 +2395,6 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
peer = wait_for_answer(chan, outgoing, &to, peerflags, opt_args, &pa, &num, &result,
dtmf_progress, ignore_cc, &forced_clid, &stored_clid);
- /* The ast_channel_datastore_remove() function could fail here if the
- * datastore was moved to another channel during a masquerade. If this is
- * the case, don't free the datastore here because later, when the channel
- * to which the datastore was moved hangs up, it will attempt to free this
- * datastore again, causing a crash
- */
- if (!ast_channel_datastore_remove(chan, datastore))
- ast_datastore_free(datastore);
if (!peer) {
if (result) {
res = result;
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 5c348b752..465356e61 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -4567,17 +4567,6 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
if (need_weight)
ao2_unlock(queues);
lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed, update_connectedline);
- /* The ast_channel_datastore_remove() function could fail here if the
- * datastore was moved to another channel during a masquerade. If this is
- * the case, don't free the datastore here because later, when the channel
- * to which the datastore was moved hangs up, it will attempt to free this
- * datastore again, causing a crash
- */
- ast_channel_lock(qe->chan);
- if (datastore && !ast_channel_datastore_remove(qe->chan, datastore)) {
- ast_datastore_free(datastore);
- }
- ast_channel_unlock(qe->chan);
ao2_lock(qe->parent);
if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_RRORDERED) {
store_next_rr(qe, outgoing);
diff --git a/main/features.c b/main/features.c
index cf08c68ab..f77962347 100644
--- a/main/features.c
+++ b/main/features.c
@@ -3416,6 +3416,22 @@ static void add_features_datastores(struct ast_channel *caller, struct ast_chann
return;
}
+static void clear_dialed_interfaces(struct ast_channel *chan)
+{
+ struct ast_datastore *di_datastore;
+
+ ast_channel_lock(chan);
+ if ((di_datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL))) {
+ if (option_debug) {
+ ast_log(LOG_DEBUG, "Removing dialed interfaces datastore on %s since we're bridging\n", chan->name);
+ }
+ if (!ast_channel_datastore_remove(chan, di_datastore)) {
+ ast_datastore_free(di_datastore);
+ }
+ }
+ ast_channel_unlock(chan);
+}
+
/*!
* \brief bridge the call and set CDR
* \param chan,peer,config
@@ -3601,6 +3617,13 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
ast_clear_flag(bridge_cdr, AST_CDR_FLAG_DIALED);
}
ast_cel_report_event(chan, AST_CEL_BRIDGE_START, NULL, NULL, NULL);
+
+ /* If we are bridging a call, stop worrying about forwarding loops. We presume that if
+ * a call is being bridged, that the humans in charge know what they're doing. If they
+ * don't, well, what can we do about that? */
+ clear_dialed_interfaces(chan);
+ clear_dialed_interfaces(peer);
+
for (;;) {
struct ast_channel *other; /* used later */