<?xml version='1.0' ?>
<!DOCTYPE rfc SYSTEM 'rfc2629.dtd'>
<rfc ipr='full2026' docName='draft-ietf-sip-congestsafe-01' >
  <?rfc toc='yes' ?>
  <?rfc tocompact='no' ?>
  <?rfc compact='yes' ?>
  <?rfc subcompact='yes' ?>
  <front> 
    
    <title abbrev='SIP Congestion Safety'>
      Session Initiation Protocol Extension to Assure
      Congestion Safety</title>
      <author initials='D.W' surname='Willis' fullname='Dean Willis'>
	 <organization abbrev='dynamicsoft Inc.'>
	   dynamicsoft Inc.
	 </organization>
         <address>
           <postal>
	      <street>5100 Tennyson Parkway</street>
	      <street>Suite 1200</street>
	      <city>Plano</city>
	      <region>TX</region>
	      <code>75028</code>
	      <country>US</country>
	   </postal>
	   <phone>+1 972 473 5455</phone>
	   <email>dean.willis@softarmor.com</email>
	   <uri>http://www.dynamicsoft.com/</uri>
	</address>
      </author>

      <author initials='B.C' surname='Campbell' fullname='Ben Campbell'>
	 <organization abbrev='dynamicsoft Inc.'>
	   dynamicsoft Inc.
	 </organization>
         <address>
           <postal>
	      <street>5100 Tennyson Parkway</street>
	      <street>Suite 1200</street>
	      <city>Plano</city>
	      <region>TX</region>
	      <code>75028</code>
	      <country>US</country>
	   </postal>
	   <phone>+1 972 473 5452</phone>
	   <email>bcampbell@dynamicsoft.com</email>
	   <uri>http://www.dynamicsoft.com/</uri>
	</address>
    </author>
    <date month='Feb' day='12' year='2003' />
    <area>Transport</area>
    <workgroup>SIP -- Session Initiation Protocol Working Group</workgroup>
    <keyword>SIP</keyword>
    <keyword>Congestion</keyword>
    <keyword>TCP</keyword>
    <keyword>UDP</keyword>
    <keyword>SCTP</keyword>

    <abstract> 

      <t>The Session Initiation Protocol allows the use of UDP for
      transport of SIP messages. The use of UDP inherently risks
      network congestion problems, as UDP itself does not define
      congestion prevention, avoidance, detection, or correction
      mechanisms. This problem is aggravated by large SIP messages
      which fragment at the UDP level. Transport protocols in SIP are
      also negotiated on a per-hop basis, at the SIP level, so SIP
      proxies may convert from TCP to UDP and so forth. This document
      defines what it means for SIP nodes to be congestion safe and
      specifies an extension by which a SIP User Agent may require
      that its requests are treated in a congestion safe manner.</t>
    </abstract>
  </front>

  <middle>

    <section title='Terminology'>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
      "OPTIONAL" in this document are to be interpreted as described
      in RFC 2119 [RFC2119].</t>
    </section>

    <section title='Background'>

      <t>The Session Initiation Protocol <xref target='RFC3261'>RFC
      3261</xref> provides application support over multiple transport
      protocols, including UDP and TCP. Transport negotiation is not
      "end to end" with SIP. Instead, each SIP hop individually
      determines which transport to use. For example, a User Agent
      (UA) may use TCP to talk to a proxy, that proxy my use UDP to
      talk to another proxy, and that second proxy may use SCTP to
      talk to a destination UA.</t>

      <t>UDP has inherent issues with congestion management. The
      protocol has no explicit mechanisms for avoiding, detecting, or
      adapting to network congestion. SIP attempts to deal with this
      in two ways:</t>

      <list style='numbers'>
        <t>Retransmission timers with exponential back offs.</t>
        <t>Attempting to limit the size of transmissions over UDP to 
           reduce the effects of fragmentation.</t>
      </list>

      <t>This would appear to be an incomplete solution. One solution
      might be to deprecate UDP entirely for SIP. However, there is a
      large installed base using UDP, and there are legitimately
      places where UDP appears to be quite useful such as tiny mobile
      phones and in extremely high-volume proxies connecting over
      dedicated networks.</t>

      <t>As an alternative, this draft:</t>

      <list style='numbers'>
        <t>Defines what it means for a SIP node to be
        "congestion-safe".</t>

        <t>Defines a mechanism whereby a congestion-safe UA may
        require that any proxy processing its requests be congestion
        safe.</t>

        <t>Defines a mechanism whereby a proxy may reject a request
        that it would be forced to fragment, and in so doing inform
        the originating UA of relevant sizing parameters.</t>

        <t>Defines a mechanism whereby a server may reject requests
        that would result in responses that might not be transmitted
        congestion-safely if the request itself was not received in a
        congestion-safe manner.</t>

      </list>

    </section>
    <section title='Definition of Congestion Safety for SIP'>

        <t>A SIP node can be considered "congestion safe" if it never
        emits a request or response in a manner not known to be congestion
        safe.</t>

        <t>Requests may be considered congestion-safe if any one of
        the following criteria is met:</t>

        <list style="numbers">
           <t>The transport toward the next SIP hop is TCP, SCTP, or
           other transport providing congestion control and the next
           hop is known to be either a UA or a congestion-safe
           proxy.</t>
           <t>The transport toward the next hop is UDP, the next hop
           is known to be a UA or congestion-safe proxy, and the
           network between the two is known to support congestion
           management at a lower layer. Note that this is an uncommon
           case in typical Internet applications.</t>
           <t>If the only available transport toward the next hop is
           UDP and the next hop is known to be a UA or congestion-safe
           proxy, the request MAY be transmitted over UDP or rejected
           by local policy. If the request is transmitted over UDP,
           the procedures described under the heading "Responsible use
           of SIP over UDP" in this document MUST be followed.</t>
        </list>
        
        <t>Responses may be considered congestion-safe if any one of
        the following criteria is met:</t>

        <list style = "numbers">
          <t>The request was congestion-safe, as defined above.</t>
          <t>The response is no larger than the request.</t>
        </list>
         
        <t> The preceding uses the phrase "the next hop is known to be
        either a UA or a congestion-safe proxy." Such knowledge may be
        derived either through administrative configuration or through
        use of the Proxy-Require mechanism defined herein under the
        heading "Assuring Transitive Congestion Safety with
        Proxy-Require".</t>

     </section>

     <section title="Assuring Transitive Congestion Safety with Proxy-Require">
    
       <t>SIP provides a mechanism whereby a user agent making a
       request can be assured that any proxy servicing that request
       support a specific extension or set of behavior. To do so, the
       user agent includes a "Proxy-Require" header field with a value
       indicating a tag for the specific extension or behavior
       required. There is an IANA registration process for these
       tags. As per <xref target="RFC3261" />, proxies not recognizing
       a specific tag or unwilling to support the associated behavior
       reject a request referencing that tag with a 420 response,
       which has the semantic "Unsupported".</t>

       <t>We herein define a tag value of "congestion-safe". A proxy
       forwarding a request containing a Proxy-Require with this tag
       value MUST manifest the property of congestion-safety as
       defined by this document.</t>

     </section>

    <section title="Responsible use of SIP over UDP">

      <t>The fundamental problem with UDP is that it provides no
      feedback mechanism to allow a sender to pace its transmissions
      against the real performance of the network. While this tends to
      have no significant effect on extremely low-volume
      sender-receiver pairs, the impact of high-volume relationships
      on the network can be severe. Consider the following scenario,
      wherein the traffic between multiple UAs is funnelled through a
      single proxy-proxy relationship.</t>

      <figure anchor='figure1'>

        <preamble>Example of large-fan out/fan-in likely to encounter
        congestion:</preamble>

        <artwork><![CDATA[

          
      UA1----\                /----UA10
      UA2-----\              /-----UA11
      UA3------\            /------UA12
      UA4-------\          /-------UA13
      UA5--------P1------P2--------UA14
      UA6-------/          \-------UA15
      UA7------/            \------UA16
      UA8-----/              \-----UA17
      UA9----/                \----UA18
            
        ]]></artwork>         
      </figure>          

      <t>In this scenario, any requests from UA(1..9) to UA(10..18)
      traverse the proxy-proxy link P1&lt-->P2. Assuming current SIP
      practices, if this link is UDP and every UA emits a request
      simultaneously, each proxy will insert nine (one for each UA)
      requests, resulting in eighteen simultaneous requests on the
      P1&lt-->P2 link. Each request may require retransmissions, and
      large requests may require fragmentation to fit the link MTU --
      at the worst case, producing more than one hundred packets per
      request, or approximately 2,000 simultaneously expressed packets
      in this scenario. If the capacity of link P1&lt-->P2 is inadequate
      to deliver these messages within the SIP retransmission window,
      the originating UAs (or the proxies, if acting in
      transaction-stateful mode) generate retransmissions, further
      compounding the problem into a "retransmission
      storm". Real-world scenarios may scale far more seriously. It is
      not unreasonable to assume that there may be tens of thousands
      of UAs on each side of the network.</t>

      <t>Clearly the best thing to do is to use a more sophisticated
      transport protocol (TCP, SCTP, etc.) between P1 and P2, and
      between each UA and its associated proxy. If this is not
      feasible, it may be necessary to fall back to UDP.</t>

      <t>It should be noted that the fundamental problem not just
      between UAs and proxies, but whenever there is a high fan-out or
      fan-in ratio. If in the above example, each UA were behind a
      "residential proxy", the problem would occur in similar
      fashion.</t>

      <t>One might propose that SIP ALWAYS use a congestion-controlled
      transport to talk to proxies, and only fall back to UDP when the
      next hop is a UA. The primary problem with this approach is that
      in general, a SIP node does not and cannot know whether the next
      node is a UA or a proxy -- it is this ability to "insert"
      proxies into a sequence that provides much of the flexibility of
      SIP. A secondary problem is that even if the next hop is a UA,
      some UAs are sufficienty high volume, and some links
      sufficiently narrow, that congestion might still result from the
      incautious use of UDP.</t>

      <section title="Requirements For Use of SIP Over UDP">
        <t>The previously described problems with the general use of
        SIP over UDP lead to the following two requirements for the
        use of UDP as a transport protocol for SIP:</t>

        <list style='numbers'>

          <t>Large messages MUST NOT be transmitted over UDP. The SIP
          specification provides basic guidance for
          UAs. Congestion-safe proxies MUST follow the procedures
          described below under the heading "Proxy Rejects Request
          That Would Require UDP Fragmentation." UAs MAY also make use
          of the MTU feedback techniques in that section.</t>

          <t>Nodes sending requests over UDP MUST pace those requests as
          described under the heading "Pacing SIP requests over UDP."</t>

        </list>

        <t>Response messages SHOULD be constrained to be smaller
        than the MTUs established for requests by the preceding
        mechanisms, and systems implementors should remain aware
        that SIP provides limited support for managing response
        sizes. Further experience may indicate a need for further
        control over response handling.</t>

      </section>
      
      <section title='Pacing SIP Requests Over UDP'>
        <t>One simple way to describe the congestion problem is that
        UDP lets us send packets without knowing whether those packets
        are arriving. The simplest approach to dealing with this at
        the application level is to send a request, then wait for some
        sort of response indicating that the request was received
        before sending anything else. This produces an effect
        described by some as "ping-ponging" -- traffic bounces back
        and forth between two nodes like a ping-pong ball or tennis
        ball in a match. Since there's only one ball in play between
        any two players at any given time, most of the potential for
        congestion cascades is eliminated. </t>

        <t>This pacing or serialization approach has the side-effect
        of significantly reducing the maximum throughput, as
        transmission occurs in only one direction at a time and there
        is at least a 2xRTT delay between transmissions. More
        sophisticated algorithms such as those in TCP and SCTP have
        been developed to address this, and it would be inappropriate
        to duplicate that work here. Consequently, if greater
        efficiency is required than that provided by this simple
        approach, implementors should use TCP, SCTP, or another such
        protocol. But if one absolutely must use UDP, this approach
        works, and is reasonably efficient in the most likely
        application of "edge proxy" to UA and other proxies with large
        fan-outs to individual low-volume nodes.</t>

        <t>SIP has two sorts of request transactions: "invite" and
        "non-invite" tranactions. Invite transaction use a three way
        sequence of "request, response, acknowledgement" and may
        include a "provisional response" between the request and
        response steps. Non-invite transactions use a two-way
        "request, response" sequence, and may also have a provisional
        response although that behavior has been deprecated.</t>

        <t>Congestion-safe use of SIP over UDP requires waiting for
        some sort of response to a request (or a timeout, which has
        backoff properties) before sending another request to that
        same destination. A congestion-safe SIP node (UA or proxy)
        MUST NOT send a request to a given next-hop if there is an
        existing request to that destination which has not received
        some sort of response. The existing transaction MUST either
        receive a response (final or provisional) or time-out before a
        new request can be made to that next-hop.</t>

        <t>This effectively requires congestion-safe proxies to act in
        a transaction-stateful manner on a per-next-hop destination
        basis, at least to the extent of tracking whether some sort of
        request is pending to each next-hop and correlating
        provisional and final responses to that request.</t>

        <t>Some may argue that this puts an excessive burden onto the
        SIP node, and that implementations that are "congestion-safe"
        per this specification will have reduced performance when used
        with UDP over a shared or public network. We counter that
        congestion-safe transport protocols are readily available, and
        that network users which insist on using unsafe transports
        (such as UDP) MUST be responsible for assuring that they do
        not impede the function of other users of the network, even at
        the expense of reducing their own efficiency. It is simply
        irresponsible to "blast away" at the network without regard
        for congestion or its impact on other users of the
        network.</t>

      </section>

          
      <section title="Proxy Rejects Request That Would Require UDP 
         Fragmentation">
     
        <t>A proxy may be faced with a request to deliver a large
        message using UDP as a transport. Fragmentation of such
        messages is problematic in several ways.  Loss of any fragment
        requires time-out and retransmission of the message. The
        fragments are commonly transmitted out the interface at local
        interface (usually LAN) rates, without awareness of
        intervening network conditions. For these reason, we believe it
        in general a bad practice to send large requests over UDP.</t>

        <t>While the actual MTU of a link may not be known, common
        practice seems to indicate that the local interface MTU is
        likely to be a reasonable approximation. Where the actual path
        MTU is known, that value should be used instead. </t>

        <t>When a congestion-safe SIP proxy processing a request
        determines that the next hop is reached via UDP, and that the
        request is larger than the effective MTU toward that hop and
        would consequently be fragmented, the proxy MUST reject that
        request with a 513 response.</t>

        <t>The base SIP specification provides minimal guidance on
        dealing with oversized requests. There is an error response
        code, 513, with the semantic "request too large" that seems
        applicable. However, SIP provides no guidance on how to
        indicate what size might be allowed. We define here two
        extension header fields that may be used in a 513 response to
        indicate by the rejecting proxy the size of message allowed by
        that proxy. The extension header field "Proxy-Max-Size" may be
        used to indicate the largest allowable request to the
        originating UA. The extension header field "Proxy-Seen-Size"
        may be used to indicate the size of the rejected request as
        calculated by the rejecting proxy. In both cases, the size
        value used indicates the SIP message size, which does not
        include IP or transport protocol overhead.</t>

        <t>A congestion-safe SIP proxy which rejects a request based
        on size SHOULD include a "Proxy-Max-Size" header field with a
        value indicating the largest size message allowed by this
        proxy on this link. If a Proxy-Max-Size header field is sent,
        the proxy MUST also include a "Proxy-Seen-Size" header
        indicating the size of the request as seen at this proxy.</t>

        <t>A UA receiving a 513 response has the options of giving up,
        trying a smaller request, or trying a different set of
        proxies. Should it choose to try a smaller request, it may
        estimate the size of the largest message that can be sent by
        taking the original request size, subtracting it from the
        value of the Proxy-Seen-Size header field, and subtracting
        that result from the value of the Proxy-max-Size header
        field. Note that a UA SHOULD NOT repeatedly downsize and retry
        a request. This technique is not an adequate replacement for
        TCP's Path MTU Discovery. Any request that has been rejected
        more than once with a 513 SHOULD either be abandoned or
        re-issued over congestion-safe channels.</t>

      </section>

      <section title="Server Rejects Request Because Response Could Not Be Sent Safely">

         <t>A server receiving a SIP request generates a resposne to
         that request. Delivery of this response may raise issues of
         congestion-safety. Because SIP requires that responses
         traverse exactly the reverse of the route taken by the
         request (recorded in the Via: header fields values), the
         server has no options about routing the response. If the
         request was delivered in a congestion-safe manner, it can be
         safely assumed that the response will also be returned in a
         congestion-safe manner, as it must traverse exactly this
         recorded route. However, if the request was NOT received in a
         congestion-safe manner, the server cannot negotiate a
         congestion-safe path for the response, as the response must
         follow the path of the request.</t>

         <t>If the size of the generated response is less than the
         size of the received request, it may be reasonably assumed
         that since the request arrived intact, a response of equal or
         smaller size is likely to traverse the reverse of that path
         succesfully. However, no such assumptions can be made about
         responses that are larger than the corresponding request.</t>

         <t>When a congestion-safe server generates a response to a
         request that is larger than the request and that request was
         not received over a congestion-safe channel, it cannot be
         assumed that the response can be safely transmitted.  An
         unsafe response cannot be transmitted by a congestion-safe
         server. Instead the server MUST reject the request and return
         an error response using response code 514, which has the
         semantic of "Response Could Not Be Sent Safely".</t>

         <t>A UA receiving a 514 response to a request may either
         retry the request in a congestion-safe manner or abandon the
         request.</t>

      </section>

    </section>

   

    <section title='Syntax of Extensions and Changes to SIP Specifications'>

      <t>The syntax for the Proxy-Max-Size header field is:</t>

      <t>Proxy-Max-Size = "Proxy-Max-Size" HCOLON
      1*DIGIT</t>

      <t>The syntax for the Proxy-Seen-Size header field is:</t>

      <t>Proxy-Seen-Size = "Proxy-Seen-Size"
      HCOLON 1*DIGIT</t>


    </section>

    <section title='IANA Considerations'>

      <t>This document defines the SIP extension header fields
      "Proxy-Max-Size" and "Proxy-Seen-Size" ", which IANA will add to
      the registry of SIP header fields defined in <xref
      target='RFC3261' />.</t>

      <t>This document also defines the SIP option tag "congestion-safe" which
      IANA will add to the registry of SIP option tags defined in
      <xref target='RFC3261' />.</t>

      <t>This document also defines the SIP response code 514, with
      the semantic "Response Cannot Be Sent Safely" which IANA will
      add to the registry of SIP response codes defined in <xref
      target="RFC3261" /> in the section for 5xx clase response codes.</t>

      <t>The following is the registration for the Proxy-Max-Size
      header field:</t>

      <list style='empty'>
        <t>
          <list style='hanging'>
            <t hangText="RFC Number:">RFCXXXX [Note to IANA: Fill in
                with the RFC number of this specification.] </t>
            <t></t>
            <t hangText="Header Field Name:">Proxy-Max-Size</t>
            <t></t>
            <t hangText="Compact Form:">none</t>
            <t></t>
           </list>
        </t>
      </list>
 
      <t>The following is the registration for the Proxy-Seen-Size
      header field:</t>
        <list style='empty'>
          <t>
            <list style='hanging'>
                <t hangText="RFC Number:">RFCXXXX [Note to IANA: Fill in
                    with the RFC number of this specification.] </t>
              <t></t>
              <t hangText="Header Field Name:">Proxy-Seen-Size</t>
              <t></t>
              <t hangText="Compact Form:">none</t>
              <t></t>
            </list>
          </t>
      </list>

      <t>The following is the registration for the congestion-safe option tag: 
        <list style='empty'>
          <t>
            <list style='hanging'>
              <t hangText="RFC Number:">RFCXXXX [Note to IANA: Fill in
                  with the RFC number of this specification.]</t>
              <t></t> 
              <t hangText="Option Tag:">congestion-safe</t>
            </list>
          </t>
        </list>
      </t> 

      <t> The following is the registration for the SIP response code 514: 
        <list style='empty'>
          <t>
            <list style='hanging'>
              <t hangText="RFC Number:">RFCXXXX [Note to IANA: Fill in
                  with the RFC number of this specification.]</t>
              <t></t> 
              <t hangText="Response Code:">514    Response Cannot Be Sent Safely</t>
            </list>
          </t>
        </list>
      </t> 
      
    </section>

    <section title='Acknowledgements'>

      <t>Robert Sparks and Jonathan Rosenberg argued with us
      vociferously over this topic and contributed substantial
      insight.</t>

    </section>

  </middle>

  <back>

    <references title='Normative References'>

      <?rfc include="reference.RFC.2026" ?>
      <?rfc include="reference.RFC.2119" ?>
      <?rfc include="reference.RFC.2223" ?>
      <?rfc include="reference.RFC.3261" ?>
      <?rfc include="reference.RFC.3427" ?>
    </references>

  </back>

</rfc>




















