From 3087c82eb64a490217700735d40dbc7cddf80239 Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <holger@moiji-mobile.com>
Date: Wed, 10 Apr 2019 05:30:25 +0100
Subject: [PATCH] stasis: Call callbacks when imparting fails

After a bridge has been deleted the stasis control will depart
the channel and might attempt to re-add it to the dial bridge.

The later can fail and this can lead to a situation that the stasis
control is unlinked but the after_bridge_cb_failed cb is executed trying
to access a dangling control object.

Fix it by calling the after_cb's before bridge_channel_impart_signal.

ASTERISK-26718

Change-Id: Ib4e8f70d7a21bd54afe3cb51cc6717ef7c355496
---
 include/asterisk/bridge.h | 3 +++
 main/bridge.c             | 1 +
 2 files changed, 4 insertions(+)

diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h
index 621ed0d248..1111d63893 100644
--- a/include/asterisk/bridge.h
+++ b/include/asterisk/bridge.h
@@ -645,6 +645,9 @@ enum ast_bridge_impart_flags {
  * it were placed into the bridge by ast_bridge_join().
  * Channels placed into a bridge by ast_bridge_join() are
  * removed by a third party using ast_bridge_remove().
+ *
+ * \note Any callbacks on the channel will be invoked on failure
+ * with the reason as AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED.
  */
 int ast_bridge_impart(struct ast_bridge *bridge,
 	struct ast_channel *chan,
diff --git a/main/bridge.c b/main/bridge.c
index 5752001381..366d375d89 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -1928,6 +1928,7 @@ int ast_bridge_impart(struct ast_bridge *bridge,
 	res = bridge_impart_internal(bridge, chan, swap, features, flags, &cond);
 	if (res) {
 		/* Impart failed.  Signal any other waiting impart threads */
+		ast_bridge_discard_after_callback(chan, AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED);
 		bridge_channel_impart_signal(chan);
 	}
 
-- 
GitLab