<div dir="ltr">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&#39;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&#39;t see any &quot;risks&quot; involved here, it&#39;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. </div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 10, 2015 at 1:24 AM, Bogdan-Andrei Iancu <span dir="ltr">&lt;<a href="mailto:bogdan@opensips.org" target="_blank">bogdan@opensips.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    <tt>Hi Maxim,<br>
      <br>
      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.<br>
      <br>
      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).<br>
      <br>
      Regards,<br>
    </tt><span class="">
    <pre cols="72">Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
<a href="http://www.opensips-solutions.com" target="_blank">http://www.opensips-solutions.com</a></pre>
    </span><div><div class="h5"><div>On 08.12.2015 21:12, Maxim Sobolev
      wrote:<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr">Bogdan, I don&#39;t think that&#39;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&#39;s not up for an
        UAC implementation to decide to stop retransmit timer.
        <div><br>
        </div>
        <div>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.<br>
        </div>
        <div>
          <div><br>
          </div>
          <div>I am working on a test case for the voiptests to test for
            that specifically. Here is the diagram which illustrates its
            main idea. </div>
        </div>
        <div><br>
        </div>
        <div><a href="http://sobomax.sippysoft.com/IMG_5229.png" target="_blank">http://sobomax.sippysoft.com/IMG_5229.png</a></div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Tue, Dec 8, 2015 at 5:17 AM,
          Bogdan-Andrei Iancu <span dir="ltr">&lt;<a href="mailto:bogdan@opensips.org" target="_blank"></a><a href="mailto:bogdan@opensips.org" target="_blank">bogdan@opensips.org</a>&gt;</span> wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div 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><span>
                <pre cols="72">Bogdan-Andrei Iancu
OpenSIPS Founder and Developer
<a href="http://www.opensips-solutions.com" target="_blank">http://www.opensips-solutions.com</a></pre>
              </span>
              <div>
                <div>
                  <div>On 16.11.2015 21:21, Maxim Sobolev wrote:<br>
                  </div>
                  <blockquote 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 &quot;original request&quot;).</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 href="mailto:bogdan@opensips.org" target="_blank"></a><a href="mailto:bogdan@opensips.org" target="_blank">bogdan@opensips.org</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 href="http://www.opensips-solutions.com" rel="noreferrer" target="_blank">http://www.opensips-solutions.com</a>
                          <div>
                            <div><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&#39;ve made a little diagram explaining
                                the current vs. &quot;proper&quot; behavior. You
                                can see it at the link below:<br>
                                <br>
                                <a 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>
                        <div dir="ltr">Maksym Sobolyev<br>
                          Sippy Software, Inc.<br>
                          Internet Telephony (VoIP) Experts<br>
                          Tel (Canada): <a href="tel:%2B1-778-783-0474" value="+17787830474" target="_blank">+1-778-783-0474</a><br>
                          Tel (Toll-Free): <a href="tel:%2B1-855-747-7779" value="+18557477779" target="_blank">+1-855-747-7779</a><br>
                          Fax: <a href="tel:%2B1-866-857-6942" value="+18668576942" target="_blank">+1-866-857-6942</a><br>
                          Web: <a href="http://www.sippysoft.com" target="_blank">http://www.sippysoft.com</a><br>
                          MSN: <a href="mailto:sales@sippysoft.com" target="_blank">sales@sippysoft.com</a><br>
                          Skype: SippySoft<br>
                        </div>
                      </div>
                    </div>
                  </blockquote>
                  <br>
                </div>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
        <br clear="all">
        <div><br>
        </div>
        -- <br>
        <div>
          <div dir="ltr">Maksym Sobolyev<br>
            Sippy Software, Inc.<br>
            Internet Telephony (VoIP) Experts<br>
            Tel (Canada): <a href="tel:%2B1-778-783-0474" value="+17787830474" target="_blank">+1-778-783-0474</a><br>
            Tel (Toll-Free): <a href="tel:%2B1-855-747-7779" value="+18557477779" target="_blank">+1-855-747-7779</a><br>
            Fax: <a href="tel:%2B1-866-857-6942" value="+18668576942" target="_blank">+1-866-857-6942</a><br>
            Web: <a href="http://www.sippysoft.com" target="_blank">http://www.sippysoft.com</a><br>
            MSN: <a href="mailto:sales@sippysoft.com" target="_blank">sales@sippysoft.com</a><br>
            Skype: SippySoft<br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </div></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 href="http://www.sippysoft.com" target="_blank">http://www.sippysoft.com</a><br>MSN: <a href="mailto:sales@sippysoft.com" target="_blank">sales@sippysoft.com</a><br>Skype: SippySoft<br></div></div>
</div>