[asterisk-bugs] [JIRA] (ASTERISK-23987) BridgeWait: channel entering into holding bridge that is being destroyed fails to successfully join the newly created holding bridge

Matt Jordan (JIRA) noreply at issues.asterisk.org
Wed Jul 2 17:22:57 CDT 2014


Matt Jordan created ASTERISK-23987:
--------------------------------------

             Summary: BridgeWait: channel entering into holding bridge that is being destroyed fails to successfully join the newly created holding bridge
                 Key: ASTERISK-23987
                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-23987
             Project: Asterisk
          Issue Type: Bug
      Security Level: None
          Components: Applications/app_bridgewait, Core/Bridging
    Affects Versions: 12.3.2
            Reporter: Matt Jordan


Holding bridges created by {{BridgeWait}} are a bit interesting: each named holding bridge can be shared by multiple participants. This creates an interesting race condition.

When the last channel leaves a bridge created by {{BridgeWait}}, we have to destroy the bridge. However, in some cases, a channel may be trying to enter the named holding bridge at the same time. Because {{BridgeWait}} cannot hold onto a reference to the bridge (as otherwise the bridge would never get disposed of), there is a case where a channel will attempt to join a holding bridge that just got destroyed.

The code handles this case: when this occurs, {{ast_bridge_join}} will fail. If {{ast_bridge_join}} fails, we attempt again - the attempt in and of itself will cause a new named holding bridge to be created, and from the perspective of the user, the join succeeds.

{code}
	for (;;) {
		RAII_VAR(struct wait_bridge_wrapper *, bridge_wrapper, get_wait_bridge_wrapper(bridge_name), wait_wrapper_removal);

		if (!bridge_wrapper) {
			ast_log(LOG_WARNING, "Failed to find or create waiting bridge '%s' for '%s'.\n", bridge_name, ast_channel_name(chan));
			bridge_join_failed = 1;
			break;
		}

		ast_verb(3, "%s is entering waiting bridge %s:%s\n", ast_channel_name(chan), bridge_name, bridge_wrapper->bridge->uniqueid);

		if (ast_bridge_join(bridge_wrapper->bridge, chan, NULL, &chan_features, NULL, 0)) {
			/* It's possible for a holding bridge to vanish out from under us since we can't lock it.
			 * Unlink the wrapper and then loop if the bridge we try to enter is dissolved. */
			ast_verb(3, "Waiting bridge '%s:%s' is no longer joinable. Creating new bridge and trying again.\n",
				bridge_name, bridge_wrapper->bridge->uniqueid);
			ao2_unlink(wait_bridge_wrappers, bridge_wrapper);
			continue;
		}

		break;
	}
{code}

Unfortunately, this doesn't quite work. When the {{ast_bridge_join}} fails, we do create a new holding bridge, and we do attempt to put the channel into it. Unfortunately, the channel immediately bounces out of it:

{noformat}
    -- Executing [s at hold:1] BridgeWait("PJSIP/103-00000017", "holding_lot") in new stack
    -- PJSIP/103-00000017 is entering waiting bridge holding_lot:7b69b650-22d7-4ed0-83bf-d7b00acd23ba
    -- Waiting bridge 'holding_lot:7b69b650-22d7-4ed0-83bf-d7b00acd23ba' is no longer joinable. Creating new bridge and trying again.
    -- PJSIP/103-00000017 is entering waiting bridge holding_lot:24828e7f-ff78-4aa4-93d4-cee8cd4eced9
    -- Channel PJSIP/103-00000017 joined 'holding_bridge' base-bridge <24828e7f-ff78-4aa4-93d4-cee8cd4eced9>
    -- Started music on hold, class 'default', on channel 'PJSIP/103-00000017'
    -- Stopped music on hold on PJSIP/103-00000017
    -- Channel PJSIP/103-00000017 left 'holding_bridge' base-bridge <24828e7f-ff78-4aa4-93d4-cee8cd4eced9>
{noformat}

For some reason, we're immediately entering and bouncing right back out of the newly created holding bridge. When the race condition isn't hit, the channel joins just fine.



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list