[Asterisk-code-review] bridge basic: Ignore answer from transfer target when they'v... (asterisk[master])

Joshua Colp asteriskteam at digium.com
Mon Nov 20 14:54:49 CST 2017


Joshua Colp has submitted this change and it was merged. ( https://gerrit.asterisk.org/7253 )

Change subject: bridge_basic: Ignore answer from transfer target when they've timed out.
......................................................................

bridge_basic: Ignore answer from transfer target when they've timed out.

This is a fun one.

Given the following attended transfer scenario:

1. Transfer target is called
2. Transferer hangs up
3. Transfer target call attempt reaches timeout
4. Transfer target is told to hang up
5. Transfer target answers before channel is hung up
6. Transferer recall target is called

A crash would occur. This is because the transfer target call
attempt, despite being told to hang up, would raise a recall
target answer before the recall target had been answered. As it
had not answered there would be no recall target channel and it
would implode.

This change makes it so that if the transfer target has been
hung up we don't tell the attended transfer code that it has
answered. We also clear out the stimulus that the recall target
has been answered after telling the transfer target to hang up,
in case it was able to raise the information before we told it
to hangup.

ASTERISK-27361

Change-Id: Ifb8b255a9c4d2c5c1b8ad77bf54f659ed286df99
---
M main/bridge_basic.c
1 file changed, 23 insertions(+), 1 deletion(-)

Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  Jenkins2: Approved for Submit



diff --git a/main/bridge_basic.c b/main/bridge_basic.c
index e31f385..fd6bac0 100644
--- a/main/bridge_basic.c
+++ b/main/bridge_basic.c
@@ -1547,6 +1547,23 @@
 	ao2_unlock(props);
 }
 
+static void remove_attended_transfer_stimulus(struct attended_transfer_properties *props,
+		enum attended_transfer_stimulus stimulus)
+{
+	struct stimulus_list *list;
+
+	ao2_lock(props);
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&props->stimulus_queue, list, next) {
+		if (list->stimulus == stimulus) {
+			AST_LIST_REMOVE_CURRENT(next);
+			ast_free(list);
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+	ao2_unlock(props);
+}
+
 /*!
  * \brief Get a desired transfer party for a bridge the transferer is not in.
  *
@@ -2339,6 +2356,10 @@
 		return TRANSFER_RESUME;
 	case STIMULUS_TIMEOUT:
 		ast_softhangup(props->recall_target, AST_SOFTHANGUP_EXPLICIT);
+		/* It is possible before we hung them up that they queued up a recall target answer
+		 * so we remove it if present as it should not exist.
+		 */
+		remove_attended_transfer_stimulus(props, STIMULUS_RECALL_TARGET_ANSWER);
 	case STIMULUS_RECALL_TARGET_HANGUP:
 		props->recall_target = ast_channel_unref(props->recall_target);
 		return TRANSFER_RECALLING;
@@ -2803,7 +2824,8 @@
 
 	if (event == AST_FRAMEHOOK_EVENT_READ &&
 			frame && frame->frametype == AST_FRAME_CONTROL &&
-			frame->subclass.integer == AST_CONTROL_ANSWER) {
+			frame->subclass.integer == AST_CONTROL_ANSWER &&
+			!ast_check_hangup(chan)) {
 
 		ast_debug(1, "Detected an answer for recall attempt on attended transfer %p\n", props);
 		if (props->superstate == SUPERSTATE_TRANSFER) {

-- 
To view, visit https://gerrit.asterisk.org/7253
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ifb8b255a9c4d2c5c1b8ad77bf54f659ed286df99
Gerrit-Change-Number: 7253
Gerrit-PatchSet: 2
Gerrit-Owner: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Jenkins2
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20171120/16c74d69/attachment-0001.html>


More information about the asterisk-code-review mailing list