[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