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

Maxim Sobolev sobomax at sippysoft.com
Thu Dec 10 16:13:14 CET 2015


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 Developerhttp://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>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 Developerhttp://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>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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opensips.org/pipermail/devel/attachments/20151210/f4e5022d/attachment-0001.htm>


More information about the Devel mailing list