CANCEL and final INVITE response glare ("crosses thewire")

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

 



Hi Gang, 

Inline below.

Steve

> -----Original Message-----
> From: pjsip-bounces@xxxxxxxxxxxxxxx [mailto:pjsip-
> bounces at lists.pjsip.org] On Behalf Of Gang Liu
> Sent: Tuesday, 28 February 2012 12:32 PM
> To: pjsip list
> Subject: Re: CANCEL and final INVITE response glare ("crosses
> thewire")
> 
> in line.
> 
> On Mon, Feb 27, 2012 at 7:30 PM, Benny Prijono <bennylp at teluu.com>
> wrote:
> > On Mon, Feb 27, 2012 at 2:32 PM, Gang Liu <gangban.lau at gmail.com>
> wrote:
> >>
> >> 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.
> >
> >
> > It looks like B is following RFC 2543 instead.
> >
> >>
> >> ? For better implementation, B should response 4xx rather than 200
> >> because related dialog already connected before CANCLE arrived.
> >
> >
> > Actually RFC 3261 says that CANCEL should be responded with 200.
> >
> according to RFC 3261, an INVITE server transaction is supposed to be
> terminated by a 200 response. I think the UAS MAY send a 481 response
> to
> the CANCEL since there is no transaction that the CANCEL request
> matches.
> This 481 simply means that there is no matching INVITE server
> transaction
> and CANCEL is not sent to the next hop. Or I am missing something?
> 
[SK] In the case I mentioned, the transaction does exist and is connected (CANCEL received after INVITE final response is sent). A CANCEL received by a UAS in the connected state should always be responded with 200 OK, but has no effect on the transaction state. 
This behavior is defined in RFC3261 9.2:

   Regardless of the method of the original request, as long as the
   CANCEL matched an existing transaction, the UAS answers the CANCEL
   request itself with a 200 (OK) response.

> 
> 
> >> ? 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.
> >>
> >
> > We already have the timer to wait for disconnection, but I think
> we're
> > discussing different case here, i.e. when the call actually gets
> connected
> > instead.
> >
> Yes, pjsip_inv APIs already do very well. I only add more timer to
> call pjsip_inv_terminate
> when necessary.
> 
> > cheers,
> > ?Benny
> >
> >
> >>
> >> 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
> >>
> >> _______________________________________________
> >> 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
> >
> 
> _______________________________________________
> 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