[Home]

Summary:ASTERISK-24649: Pushing of channel into bridge fails; Stasis fails to get app name
Reporter:John Bigelow (jbigelow)Labels:
Date Opened:2014-12-29 12:51:43.000-0600Date Closed:2015-01-22 12:12:22.000-0600
Priority:MajorRegression?
Status:Closed/CompleteComponents:Resources/res_stasis
Versions:SVN 13.1.0 Frequency of
Occurrence
Occasional
Related
Issues:
is related toASTERISK-25947 Protocol transfers to stasis applications are missing the StasisStart with the replace_channel object.
Environment:Asterisk branches 13 r430162, testsuiteAttachments:( 0) extensions.conf
( 1) full-asterisk.txt
Description:Occasionally the replacement channel (local channel half created for the transfer) fails to enter the Stasis bridge and the channel is hung up. The log shows the following:
{noformat}
[Dec 29 12:23:33] DEBUG[14808] bridge_channel.c: Bridge test_bridge: pushing 0xb33e9a8c(Local/1000@default-00000001;1) into bridge failed
...
[Dec 30 12:23:33] ERROR[14808] stasis/stasis_bridge.c: Failed to get app name for Local/1001@default-00000001;1 (0xa98d27c)
{noformat}

The scenario is:
# Dummy local channel half enters Stasis(testsuite) and the other half enters Echo()
# The stasis bridge {{test_bridge}} is created
# Alice & Bob both place a call to 'sip:stasis@127.0.0.1' where they enter {{Stasis(testsuite,test)}} and are both put into the {{test_bridge}} bridge
# Alice blind transfers Bob to 'sip:1000@127.0.0.1' where one half of the local replacement channel executes {{1000@default}}. The {{Answer()}} is shown as executed but not {{Stasis(otherapp)}}. Instead the above messages are present. The local channel half is then hung up and there of course is not a {{StasisStart}} event for it.
Comments:By: John Bigelow (jbigelow) 2015-01-07 10:47:07.955-0600

Just to point out, the replacement channel (local channel half created for the transfer) fails to enter the Stasis bridge. It appears this is why it fails to get the app name and hangs up the channel.

This message occurs just before the ERROR message:
{code}
[Dec 29 12:23:33] DEBUG[14808] bridge_channel.c: Bridge test_bridge: pushing 0xb33e9a8c(Local/1000@default-00000001;1) into bridge failed
{code}

By: John Bigelow (jbigelow) 2015-01-07 10:56:06.324-0600

I'm seeing this issue in another scenario using an attended transfer but is always occurring.

By: Scott Griepentrog (sgriepentrog) 2015-01-13 15:01:28.807-0600

There is a race condition that can cause the replacement channel to fail to enter stasis due to a missing stasis app name on the channel, where the transfer message was not yet processed that sets the app name to the channel.

When the transfer is started, ast_bridge_transfer_blind() starts creating the stasis transfer_msg, then calls blind_transfer_bridge() which in turn calls ast_bridge_impart() to handle pushing the replacement channel into a stasis bridge with it's own thread, which will need the app name to run stasis again.  Finally ast_bridge_transfer_blind() publishes the stasis transfer_msg.  However, the app name is set on the channel by the bridge_blind_transfer_handler() when it processes the stasis message, which can happen after the channel thread, in which case stasis on the new channel fails and the channel is hung up.

{noformat}
ast_bridge_transfer_blind()
 - creates stasis transfer_msg
 - blind_transfer_bridge()
   - ast_bridge_impart()
       (new channel thread created)
     - bridge_stasis_push()
       - bridge_stasis_run_cb()
         - app_get_replace_channel_app() - may fail to find app name
 - publishes stasis transfer_msg
   - bridge_blind_transfer_handler() processes stasis message
     - set_replacement_channel()
       - app_set_replace_channel_app() - sets app name on channel
{noformat}

Notes:

* The ast_bridge_transfer_blind() does not publish the stasis message until it has determined the success or failure of the individual steps of the transfer.  This makes it difficult to reorder operations without breaking things.
* Stasis is a separate optional loadable module -- thus the separate handler function that knows about the stasis app name. This knowledge cannot be put in ast_bridge_transfer_blind(), although it could be possible to add an additional callback into stasis to allow it to modify conditions during the transfer operation instead of later while processing the transfer_msg.