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