[OpenSIPS-Devel] "Early cancel" issue in the tm module

Bogdan-Andrei Iancu bogdan at opensips.org
Thu Dec 10 10:24:05 CET 2015


Hi Maxim,

Basically the strong point of your case is not to stop INVITE 
retransmissions on receiving CANCEL, just to be sure you can cope with a 
potential lost of a provisional reply.

Still, I say it is better to reply with 487 to the INVITE (see my 
demonstration that a 487 or a later 408 are exactly the same in terms of 
risk), while the 487 has no delay and reflects the correct state (call 
was canceled).

Regards,

Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
http://www.opensips-solutions.com

On 08.12.2015 21:12, Maxim Sobolev wrote:
> Bogdan, I don't think that's about one way being better than the 
> other. Stopping retransmitions after first INVITE went out is in fact 
> against the word and spirit of the RFC, as it opens door wide for 
> various inconsistencies between alice and bob (i.e. actual endpoints). 
> IMHO it's not up for an UAC implementation to decide to stop 
> retransmit timer.
>
> As per RFC, CANCEL transaction completes independently of INVITE. This 
> is especially true in forking scenarios. Therefore, UAC CANNOT have 
> any pre-disposition for receiving this reply or that. 408 would be 
> just as good as 487 or 200 OK.
>
> I am working on a test case for the voiptests to test for that 
> specifically. Here is the diagram which illustrates its main idea.
>
> http://sobomax.sippysoft.com/IMG_5229.png
>
> On Tue, Dec 8, 2015 at 5:17 AM, Bogdan-Andrei Iancu 
> <bogdan at opensips.org <mailto:bogdan at opensips.org>> wrote:
>
>     Hi  Maxim,
>
>     In the current implementation, if there was no reply received for
>     the INVITE, on canceling opensips stops retransmissions for INVITE
>     and replies with 487 to it.
>
>     As I understand, you suggest as a better approach to keep doing
>     the retransmissions until either there is an incoming reply,
>     either an internal timeout is generated and a 408 is sent back to UAC.
>
>     The advantage you invoke is related to slow/delayed provisional
>     replies - replies that you might received after the CANCEL and
>     after OpenSIPS sent back the 487 (while the UAS may answer with
>     200 OK). Well, this scenario may happen (maybe with the smaller
>     probability) also if we follow your suggestion ...actually it may
>     happen in any internal timeout scenario. Based on FR timer,
>     OpenSIPS sends back 408 in 5 seconds, while the UAS sends a 200 OK
>     in 7 seconds....what to do here :) ? OpenSIPS follows the RFC3261
>     and lets any 200 OK to pass, even if the transaction was completed
>     - this is done to allow the end points to sort it out (without
>     blaming the proxy in the middle).
>
>     So, IMHO, the issue you are trying to improve exists anyhow (like
>     a late 183/200 after a local timeout) and it is handled as per
>     RFC. The downside of your approach is the ambiguity - if the UAC
>     sends a CANCEL, it expects a 487 or 200 back, but not a timeout....
>
>     What do you think ?
>
>     Best regards,
>
>     Bogdan-Andrei Iancu
>     OpenSIPS Founder and Developer
>     http://www.opensips-solutions.com
>
>     On 16.11.2015 21:21, Maxim Sobolev wrote:
>>     Bogdan, thanks for looking into this for me. So OpenSIPS is
>>     somewhat better than original code, but still not perfect. This
>>     method would work if the INVITE has been lost or never received,
>>     but would still produce inconsistent transaction state if
>>     provisional reply has been lost and INVITE in fact is being
>>     processed by the far end. Then you might not hear from the
>>     downstream UAS until much later when it follows up with either
>>     18x or even 200 OK.
>>
>>     There is no pre-cooked recipe for a stateful proxy in the RFC,
>>     but general UAC CANCEL benaviour is defined pretty clearly,
>>     please see excerpt below. Note the fact that INVITE and CANCEL
>>     transactions need to complete independently, so UAC needs to
>>     continue re-transmit INVITE and hold on to locally generated 487.
>>
>>     If the INVITE transaction timeouts then I think local 408 can be
>>     generated to the UAC by the tm module.
>>
>>     I am pretty sure this would be RFC-correct behavior, but if you
>>     are still in doubt, I can also raise this question on
>>     sip-implementors mailing list and see what the community thinks.
>>
>>     9.1 Client Behavior
>>
>>     [...]
>>        header fields.
>>
>>        Once the CANCEL is constructed, the client SHOULD check whether it
>>        has received any response (provisional or final) for the request
>>        being cancelled (herein referred to as the "original request").
>>
>>        If no provisional response has been received, the CANCEL
>>     request MUST
>>        NOT be sent; rather, the client MUST wait for the arrival of a
>>        provisional response before sending the request.  If the original
>>        request has generated a final response, the CANCEL SHOULD NOT be
>>        sent, as it is an effective no-op, since CANCEL has no effect on
>>        requests that have already generated a final response.  When the
>>        client decides to send the CANCEL, it creates a client transaction
>>        for the CANCEL and passes it the CANCEL request along with the
>>        destination address, port, and transport.  The destination
>>     address,
>>        port, and transport for the CANCEL MUST be identical to those
>>     used to
>>        send the original request.
>>
>>           If it was allowed to send the CANCEL before receiving a
>>     response
>>           for the previous request, the server could receive the CANCEL
>>           before the original request.
>>
>>        Note that both the transaction corresponding to the original
>>     request
>>        and the CANCEL transaction will complete independently. 
>>     However, a
>>        UAC canceling a request cannot rely on receiving a 487 (Request
>>        Terminated) response for the original request, as an RFC 2543-
>>        compliant UAS will not generate such a response.  If there is no
>>        final response for the original request in 64*T1 seconds (T1 is
>>
>>
>>
>>
>>     Rosenberg, et. al.          Standards Track                  
>>      [Page 54]
>>     
>>     RFC 3261            SIP: Session Initiation Protocol          
>>     June 2002
>>
>>
>>        defined in Section 17.1.1.1), the client SHOULD then consider the
>>        original transaction cancelled and SHOULD destroy the client
>>        transaction handling the original request.
>>
>>
>>     On Sat, Nov 14, 2015 at 1:06 PM, Bogdan-Andrei Iancu
>>     <bogdan at opensips.org <mailto:bogdan at opensips.org>> wrote:
>>
>>         Hi Maxim,
>>
>>         Thank you for your detailed email on the matter. Indeed, if
>>         there is no reply received on the branch, OpenSIPS internally
>>         cancel the branch (stops retransmissions and generates a 487
>>         reply for the INVITE). Nevertheless, the branch gets marked
>>         as canceled and as soon as a reply is received on it
>>         (provisional), a CANCEL will be fired to UAS. Of course, the
>>         reply must be received within the transaction lifetime (wait
>>         timer).
>>
>>         With the approach you mentioned:
>>             - could you point to the RFC section mentioning this
>>         behavior ?
>>             - what happens if there is no reply at all from UAS ?
>>
>>         Best regards,
>>
>>         Bogdan-Andrei Iancu
>>         OpenSIPS Founder and Developer
>>         http://www.opensips-solutions.com
>>
>>
>>         On 13.11.2015 01:41, Maxim Sobolev wrote:
>>
>>             Hi Volks, there seems to be an issue in the way how the
>>             tm handles early CANCEL, i.e. when a CANCEL arriving
>>             before the downstream UAS gets chance to generate a 100
>>             Trying reply, or that reply is still in flight (or maybe
>>             100 Trying is lost). In that case the OpenSIPS stops
>>             outbound INVITE re-transmits and generates both 200 OK
>>             for CANCEL and 487 Transaction Terminated for the INVITE.
>>             This only works if initial INVITE has not reached the
>>             target UAS, otherwise inconsistent state of session is
>>             produced, with UAC thinking that the transaction is over
>>             with, while the UAS is still proceeding with call setup.
>>             Needless to say this can produce all kind of weird things
>>             ranging from irritated users to billing mismatches.
>>
>>             This behavior comes from the RFC requirement that UAC
>>             cannot generate CANCEL until at least one provisional
>>             reply has arrived, but implementation is completely wrong
>>             in my view. Instead, it should be only generating 200
>>             Cancelling for cancel immediately (to stop any CANCEL
>>             retransmits) and continue with re-transmitting INVITEs in
>>             due course until either transaction timeout occurs in 32
>>             or so seconds or 100 Trying finally comes and then
>>             outbound CANCEL transaction can be fired immediately and
>>             the rest of the logic can proceed as happens now on
>>             regular CANCEL.
>>
>>             I've made a little diagram explaining the current vs.
>>             "proper" behavior. You can see it at the link below:
>>
>>             https://docs.google.com/document/d/1mkNuqvQdw6a6j0iAmjvTssyu-VF-5i4d2Kut4Eg9qLk/pub
>>
>>             In general this is very non-intuitive, but for INVITE
>>             transactions in no circumstances retransmits should be
>>             terminated. Once the first INVITE has left the port,
>>             there is no way for the SIP proxy to know if missing
>>             provisional response is due to that invite never being
>>             received or due to response being lost or some
>>             propagation/processing delay in between.
>>
>>             This issue tracks back to the original SER code and so
>>             that all releases are affected.
>>
>>
>>             -Max
>>
>>
>>
>>
>>
>>     -- 
>>     Maksym Sobolyev
>>     Sippy Software, Inc.
>>     Internet Telephony (VoIP) Experts
>>     Tel (Canada): +1-778-783-0474 <tel:%2B1-778-783-0474>
>>     Tel (Toll-Free): +1-855-747-7779 <tel:%2B1-855-747-7779>
>>     Fax: +1-866-857-6942 <tel:%2B1-866-857-6942>
>>     Web: http://www.sippysoft.com
>>     MSN: sales at sippysoft.com <mailto:sales at sippysoft.com>
>>     Skype: SippySoft
>
>
>
>
> -- 
> Maksym Sobolyev
> Sippy Software, Inc.
> Internet Telephony (VoIP) Experts
> Tel (Canada): +1-778-783-0474
> Tel (Toll-Free): +1-855-747-7779
> Fax: +1-866-857-6942
> Web: http://www.sippysoft.com
> MSN: sales at sippysoft.com <mailto:sales at sippysoft.com>
> Skype: SippySoft

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opensips.org/pipermail/devel/attachments/20151210/2d9ae561/attachment-0001.htm>


More information about the Devel mailing list