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

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

 



Hi,
   I saw this scenario before. The B sip device was VOS which it is a
popular but not good implemented
soft switch.
   I found that call was disconnected at side B when it sent back
CANCEL 200 OK response. And if
A sent out BYE to clear the dialog, the response from B was 481.
   I don't think B is following RFC 3261 well.
   For better implementation, B should response 4xx rather than 200
because related dialog already
connected before CANCLE arrived.
   And for A, normally we need a timer to wait for DISCONNECTED event
call back from pjsip-ua
to make sure related dialog resource is released. Then we could easy
detect this race condition at there
when that timer timeout.

regards,
Gang

On Fri, Feb 24, 2012 at 6:28 AM, Steve King <sking at zetron.com> wrote:
> Hi Alan,
>
> Thanks for the email.
>
> In this instance, PJSIP is acting as UAC, not UAS so Rule 9.2 does not apply to it.
> At B, 9.2 rule is followed correctly.
> The standard does not seem to mention this particular scenario.
>
> Logically, as the app, I have requested PJSIP end that session, however PJ does not do that and allows the session to be established.
>
> In effect, *all* PJSIP based applications are then forced to perform a check if the session is being ended when the session is reported as established/confirmed. Does pjsua handle this scenario?
>
> Imho, I think its sensible for PJSIP to take about this.
>
> Steve
>
>> -----Original Message-----
>> From: pjsip-bounces@xxxxxxxxxxxxxxx [mailto:pjsip-
>> bounces at lists.pjsip.org] On Behalf Of Alain Totouom
>> Sent: Thursday, 23 February 2012 07:51 PM
>> To: pjsip list
>> Subject: Re: CANCEL and final INVITE response glare ("crosses
>> the wire")
>>
>> 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
>>
>> _______________________________________________
>> 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
>
> _______________________________________________
> 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



[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