<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<tt>Hi Maxim,<br>
<br>
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.<br>
<br>
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.<br>
<br>
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).<br>
<br>
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....<br>
<br>
What do you think ?<br>
<br>
Best regards,<br>
</tt>
<pre class="moz-signature" cols="72">Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
<a class="moz-txt-link-freetext" href="http://www.opensips-solutions.com">http://www.opensips-solutions.com</a></pre>
<div class="moz-cite-prefix">On 16.11.2015 21:21, Maxim Sobolev
wrote:<br>
</div>
<blockquote
cite="mid:CAH7qZfvGL_CrRaK=msrcQhjm0ZCVnmSwJ3vDOEEOoO00L9xWvQ@mail.gmail.com"
type="cite">
<div dir="ltr">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.
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>If the INVITE transaction timeouts then I think local 408
can be generated to the UAC by the tm module.</div>
<div><br>
</div>
<div>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.</div>
<div><br>
<div>
<div>9.1 Client Behavior</div>
<div><br>
</div>
<div>[...]</div>
<div> header fields.</div>
<div><br>
</div>
<div> Once the CANCEL is constructed, the client SHOULD
check whether it</div>
<div> has received any response (provisional or final) for
the request</div>
<div> being cancelled (herein referred to as the "original
request").</div>
<div><br>
</div>
<div> If no provisional response has been received, the
CANCEL request MUST</div>
<div> NOT be sent; rather, the client MUST wait for the
arrival of a</div>
<div> provisional response before sending the request. If
the original</div>
<div> request has generated a final response, the CANCEL
SHOULD NOT be</div>
<div> sent, as it is an effective no-op, since CANCEL has
no effect on</div>
<div> requests that have already generated a final
response. When the</div>
<div> client decides to send the CANCEL, it creates a
client transaction</div>
<div> for the CANCEL and passes it the CANCEL request
along with the</div>
<div> destination address, port, and transport. The
destination address,</div>
<div> port, and transport for the CANCEL MUST be identical
to those used to</div>
<div> send the original request.</div>
<div><br>
</div>
<div> If it was allowed to send the CANCEL before
receiving a response</div>
<div> for the previous request, the server could
receive the CANCEL</div>
<div> before the original request.</div>
<div><br>
</div>
<div> Note that both the transaction corresponding to the
original request</div>
<div> and the CANCEL transaction will complete
independently. However, a</div>
<div> UAC canceling a request cannot rely on receiving a
487 (Request</div>
<div> Terminated) response for the original request, as an
RFC 2543-</div>
<div> compliant UAS will not generate such a response. If
there is no</div>
<div> final response for the original request in 64*T1
seconds (T1 is</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div>Rosenberg, et. al. Standards Track
[Page 54]</div>
<div></div>
<div>RFC 3261 SIP: Session Initiation Protocol
June 2002</div>
<div><br>
</div>
<div><br>
</div>
<div> defined in Section 17.1.1.1), the client SHOULD then
consider the</div>
<div> original transaction cancelled and SHOULD destroy
the client</div>
<div> transaction handling the original request.</div>
<div><br>
</div>
</div>
</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Sat, Nov 14, 2015 at 1:06 PM,
Bogdan-Andrei Iancu <span dir="ltr"><<a
moz-do-not-send="true" href="mailto:bogdan@opensips.org"
target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:bogdan@opensips.org">bogdan@opensips.org</a></a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Maxim,<br>
<br>
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).<br>
<br>
With the approach you mentioned:<br>
- could you point to the RFC section mentioning this
behavior ?<br>
- what happens if there is no reply at all from UAS ?<br>
<br>
Best regards,<br>
<br>
Bogdan-Andrei Iancu<br>
OpenSIPS Founder and Developer<br>
<a moz-do-not-send="true"
href="http://www.opensips-solutions.com" rel="noreferrer"
target="_blank">http://www.opensips-solutions.com</a>
<div class="HOEnZb">
<div class="h5"><br>
<br>
On 13.11.2015 01:41, Maxim Sobolev wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
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.<br>
<br>
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.<br>
<br>
I've made a little diagram explaining the current vs.
"proper" behavior. You can see it at the link below:<br>
<br>
<a moz-do-not-send="true"
href="https://docs.google.com/document/d/1mkNuqvQdw6a6j0iAmjvTssyu-VF-5i4d2Kut4Eg9qLk/pub"
rel="noreferrer" target="_blank">https://docs.google.com/document/d/1mkNuqvQdw6a6j0iAmjvTssyu-VF-5i4d2Kut4Eg9qLk/pub</a><br>
<br>
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.<br>
<br>
This issue tracks back to the original SER code and so
that all releases are affected.<br>
<br>
<br>
-Max<br>
</blockquote>
<br>
</div>
</div>
</blockquote>
</div>
<br>
<br clear="all">
<div><br>
</div>
-- <br>
<div class="gmail_signature">
<div dir="ltr">Maksym Sobolyev<br>
Sippy Software, Inc.<br>
Internet Telephony (VoIP) Experts<br>
Tel (Canada): +1-778-783-0474<br>
Tel (Toll-Free): +1-855-747-7779<br>
Fax: +1-866-857-6942<br>
Web: <a moz-do-not-send="true"
href="http://www.sippysoft.com" target="_blank">http://www.sippysoft.com</a><br>
MSN: <a moz-do-not-send="true"
href="mailto:sales@sippysoft.com" target="_blank">sales@sippysoft.com</a><br>
Skype: SippySoft<br>
</div>
</div>
</div>
</blockquote>
<br>
</body>
</html>