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

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

 



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. 

 

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

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20120223/13034d25/attachment.html>


[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