[asterisk-dev] [Code Review] Asterisk fails to send BYE when UA in a remote bridge hangs up and the final response to a pending INVITE occurs after sip_hangup

Mark Michelson reviewboard at asterisk.org
Thu Mar 8 13:33:45 CST 2012


-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://reviewboard.asterisk.org/r/1807/#review5778
-----------------------------------------------------------

Ship it!


This should do it!

- Mark


On March 8, 2012, 12:13 p.m., Matt Jordan wrote:
> 
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> https://reviewboard.asterisk.org/r/1807/
> -----------------------------------------------------------
> 
> (Updated March 8, 2012, 12:13 p.m.)
> 
> 
> Review request for Asterisk Developers, Joshua Colp and Mark Michelson.
> 
> 
> Summary
> -------
> 
> Scenario:
> 
> Two UAs are connected to Asterisk, where UA1 and UA2 are remotely bridged together (using some directmedia setting).  When UA1 hangs up, a BYE is sent to Asterisk and, assuming nominal conditions, Asterisk responds with a 200 OK.  Immediately following the tear down of the remote bridge, but before the channel hangup is processed, a re-INVITE is sent to UA2 informing it of the change in media destination.  All of this behavior is expected, as (potentially) UA2 isn't going anywhere, and now needs to send its media to Asterisk as opposed to UA1.  As a result, the pendinginvite flag is set on the dialog between Asterisk and UA2.
> 
> The problem arises when the processing of the re-INVITE takes a significant amount of time - for example, the final response takes awhile (lost in transmission), or some authentication has to occur between Asterisk and UA2 before the INVITE request is accepted.  In that case, sip_hangup has potentially been called on UA2, and, since an INVITE is pending, has set the PENDINGBYE flag; this defers sending the BYE request until the INVITE request is finished.
> 
> There are two problems that occur in this scenario:
> 1) The channel object may no longer exist.  This skews the handling of the re-INVITE, as (with no p->owner and no channel state), things start to look more like an initial INVITE then a re-INVITE.
> 2) When we perform a process_pending on receiving a provisional response for the re-INVITE, we note that we need to cancel this request, as we are already hung up.  Unfortunately, when we do that we also clear the pending BYE - so that when the final response for the INVITE is returned, we no longer think we have a pending BYE.
> 
> One scenario where the problem manifests itself is shown below (ASCII art!) - but since this is timing based, you could come up with others:
> 
>   UA1            Asterisk            UA2
> 
>        BYE
> 1 ---------------->
>        200 OK
> 2 <---------------
>                            INVITE
> 3                   ----------------->
>                            401
> 4                   <-----------------
>                            ACK
> 5                   ----------------->
>                            INVITE
> 6                   ----------------->
>                            100
> 7                   <-----------------
>                            CANCEL
> 8                   ----------------->
>                            200
> 9                   <-----------------
>                            487
> 10                  <-----------------
> 
> In the sequence above, the sip_hangup would be called sometime after step 3.  The pending BYE flag would be set on the dialog between Asterisk and UA2, and would be cleared accidentally when the CANCEL is sent in step 8.  Asterisk should, after receiving a 487 terminating the re-INVITE, send a BYE to UA2.
> 
> This patch primarily does three things to address this:
> 1. It adds a call to process_pending when handling 487 responses for INVITE requests
> 2. It prevents clearing the BYE flag in process_pending unless a BYE has actually been sent
> 3. It adds a new enum to chan_sip called invite_types, where the types are INV_TYPE_NONE, INV_TYPE_INITIAL, and INV_TYPE_REINVITE.  Although a new flag is hardly desirable in chan_sip, it is probably necessary as we previously looked at whether or not a dialog had a channel associated with it to determine if the INVITE being processed is a re-INVITE or an initial INVITE.  This makes sense when first processing an INVITE request, however, since the channel can go away before the final response for an INVITE is received, it does not make sense when handling responses.
> 
> I've tried to limit how many places the flag needs to be inserted to minimize the impact.  I purposefully did not change the behavior of existing or similar flags, such as pendinginvite.
> 
> At this point in time, this patch needs some review to see if this solution is on the right track, or if there is a better way to handle this situation that is not overly invasive in chan_sip.
> 
> 
> This addresses bug ASTERISK-19365.
>     https://issues.asterisk.org/jira/browse/ASTERISK-19365
> 
> 
> Diffs
> -----
> 
>   /branches/1.8/channels/chan_sip.c 358643 
> 
> Diff: https://reviewboard.asterisk.org/r/1807/diff
> 
> 
> Testing
> -------
> 
> Ran through the Asterisk Test Suite, which does do some re-INVITE processing.  Tested a nominal remote bridge scenario using two Polycom phones and had no issues (although getting them to exhibit the above problem is also difficult, since the sip_hangup happens immediately after the initial INVITE is sent out).  
> 
> More testing will need to be done by the issue reporter and, hopefully, some more elaborate system level tests.
> 
> 
> Thanks,
> 
> Matt
> 
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-dev/attachments/20120308/94bbac17/attachment-0001.htm>


More information about the asterisk-dev mailing list