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

Bogdan-Andrei Iancu bogdan at opensips.org
Fri Dec 11 17:42:35 CET 2015


Roger that, thanks for the detailed explanations - let's be consistent 
in handling the INVITE cancelling, in terms of letting all the time the 
final UAS to generate the final reply (if still alive).

Best regards,

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

On 11.12.2015 05:28, Maxim Sobolev wrote:
> Bogdan, please don't get me wrong. There is probably an use case where
> ability to cancel call locally instead of having to wait for 64*T1 for
> the outbound INVITE transaction to expire is important. What I am
> trying to tell you that it needs to be implemented properly. By which
> I mean that the tm module, if it wishes to generate an early 487 for
> an INVITE, needs to continue proper re-transmit course. On top of that
> it also needs to have an ability to ACK+BYE an incoming 200 OK for
> those branches, i.e. assume some of b2b functionality for a little
> while. This should not be too difficult, as I believe it can already
> forge ACK, and it's pretty close to BYE anyways.
>
> Right now, what OpenSIPS does is kinda like ostrich trying to hide
> head in the sand, i.e. stop re-transmission and pretend nothing
> happened in the hope for good. But the INVITE got out, and it might
> still be lurking somewhere out there, trying to ring people's phones
> and using precious resources.
>
> On top of that, there are other use cases where people like us would
> be really like OpenSIPS not to make up any "pre-mature" SIP error
> codes and just delay final response on INVITE until all outbound
> transactions have gracefully timeouted.
>
> On Thu, Dec 10, 2015 at 7:13 AM, Maxim Sobolev <sobomax at sippysoft.com> wrote:
>> Bogdan, the point here is that the call cannot be considered cancelled by
>> the proxy until INVITE transaction either timeouts retransmits in 32 seconds
>> or final response is received from the UAS. Cancelling it early violates RFC
>> and creates a possibility of creating inconsistent state on inbound or
>> outbound call legs. I don't see any real benefits of doing that. UAC that
>> issued CANCEL in the first place by the RFC is expected to be prepared to
>> handle any final response to the original INVITE including 200 OK as well as
>> to wait at least 64*T1 time for the response to be generated. I don't see
>> any "risks" involved here, it's just that we need to follow protocol rules
>> set forth in the RFC. The tm module is just UAS-UAC put back-to-back and it
>> needs to behave just like any other RFC-compliant SIP UAC would.
>>
>> On Thu, Dec 10, 2015 at 1:24 AM, Bogdan-Andrei Iancu <bogdan at opensips.org>
>> wrote:
>>> 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>
>>> 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> 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 (Toll-Free): +1-855-747-7779
>>>> Fax: +1-866-857-6942
>>>> Web: http://www.sippysoft.com
>>>> MSN: 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
>>> 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
>> Skype: SippySoft
>
>




More information about the Devel mailing list