CANCEL and final INVITE response glare ("crosses the wire")

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Steve,

On 02/23/2012 08:36 AM, Steve King wrote:
> Hi Benny,
> 
>  
> 
> The scenario is:
> 
>  
> 
> A                B
> 
> 1. =====> INVITE
> 
> 2. <====   100 Trying
> 
> 3. =====> CANCEL
> 
> 4. <===== 200 OK (INVITE w SDP)
> 
> 5. =====> ACK
> 
> 6. <===== 200 OK (CANCEL)
> 
>  
> 
> In this case, B sends final INVITE response(4) before receiving
> CANCEL(3), PJSIP receives the response, ACKs it and indicates up to the
> application that the call is connected and its media available (not
> good). The 200 response to the CANCEL is according to spec and
> terminates the tsx for the CANCEL.
> 
>  
> 
> This has been touched on before in a previous thread:
> http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/2009-September/00
> 8945.html 
> 
> But no real conclusion was reached. 
> 
>  
> 
> I think this case can/should be handled in the SIP stack, rather than at
> the application layer. 
> 

We are definitively missing one part of the conversation here: what
does the calleR do, when it ends up with an established dialog,
despite the succeful completion of the CANCEL-Transaction it has
previously issued?!?
At application level is easier to catch and resolve that conflict by
sending a BYE/UAC...

Here is what the standard says about this hop-by-hop request as far
as the UAS is concerned...

9.2 Server Behavior
"If the transaction for the original request still exists, the
behavior of the UAS on receiving a CANCEL request depends on whether
it has already sent a final response for the original request.  If
it has, the CANCEL request has no effect on the processing of the
original request, no effect on any session state, and no effect on
the responses generated for the original request."

IMHO PJSIP is strictly following the 9.2 rule...

The best place to solve this race condition and be fully #3261 ?9
compliant should/would definitively be at the application level.

Best regards,
Alain


>  
> 
> I propose a change to sip_inv.c, in inv_send_ack(). See below:
> 
>  
> 
>     /* Send ACK */
> 
>     status = pjsip_dlg_send_request(inv->dlg, inv->last_ack, -1, NULL);
> 
>     if (status != PJ_SUCCESS) {
> 
>      /* Better luck next time */
> 
>      pj_assert(!"Unable to send ACK!");
> 
>      return status;
> 
>     }
> 
>  
> 
>  
> 
>     /* Set state to CONFIRMED (if we're not in CONFIRMED yet).
> 
>      * But don't set it to CONFIRMED if we're already DISCONNECTED
> 
>      * (this may have been a late 200/OK response.
> 
>      */
> 
>     if (inv->state < PJSIP_INV_STATE_CONFIRMED) {
> 
>  
> 
>         /* Bug: PJSIP does not handle a glare of rx final INVITE
> 
>          *      response and tx CANCEL (when in early state)
> 
>          *
> 
>          * The ACK may be set in response to final INVITE
> 
>          * response, but CANCEL may have been sent prior.
> 
>          * We check here for cancelling inv session, if set,
> 
>          * we end the session and suppress state notification
> 
>          * for confirmed state.
> 
>          */
> 
>         if(inv->cancelling) {
> 
>             PJ_LOG(5,(inv->obj_name, "Suppressing %s notification,
> because cancellation in progress",
> 
>                     inv_state_names[PJSIP_INV_STATE_CONFIRMED]));
> 
>  
> 
>             notify = inv->notify;
> 
>             inv->notify = PJ_FALSE;
> 
>             inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e);
> 
>             inv->notify = notify;
> 
>  
> 
>             status = pjsip_inv_end_session(inv, PJSIP_SC_GONE, NULL,
> &tdata);
> 
>             if( status == PJ_SUCCESS) {
> 
>                 status = pjsip_dlg_send_request(inv->dlg, tdata, -1,
> NULL);
> 
>                 if (status != PJ_SUCCESS) {
> 
>                     /* Better luck next time */
> 
>                     pj_assert(!"Unable to send BYE!");
> 
>                     return status;
> 
>                 }
> 
>             }
> 
>         }
> 
>         else {
> 
>             inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e);
> 
>         }
> 
>     }
> 
>  
> 
>     return PJ_SUCCESS;
> 
>  
> 
> Is this a bad idea? What are your thoughts?
> 
>  
> 
> Steve
> 
>  
> 
> 
> 
> 
> 
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
> 
> pjsip mailing list
> pjsip at lists.pjsip.org
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

-- 
                            ""
                          (o)(o)
                _____o00o__(__)__o00o_____
3072D/146D10DE 2011-09-29    Alain Totouom  <totouom at gmx.de>
PGP Fingerprint 39A4F092 FFA7C746 CC305CB0 69091911 146D10DE



[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux