<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">&lt;<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>&gt;</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>