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

Maxim Sobolev sobomax at sippysoft.com
Mon Dec 14 21:46:41 CET 2015


Thanks Bogdan, I will be working on test case this week. I'll drop you
a note when it's ready.

On Fri, Dec 11, 2015 at 8:42 AM, Bogdan-Andrei Iancu
<bogdan at opensips.org> wrote:
> 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
>>
>>
>>
>



-- 
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