<?xml version="1.0" encoding="US-ASCII"?>
<!-- Convert to HTML and Text with xml2rfc: http://xml.resource.org. -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
  <!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
  <!ENTITY RFC0793 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.0793.xml">
  <!ENTITY RFC6181 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6181.xml">
  <!ENTITY RFC5681 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5681.xml">
  <!ENTITY RFC3465 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3465.xml">
  <!ENTITY I-D.ietf-mptcp-multiaddressed SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-ietf-mptcp-multiaddressed-04">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>

<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>

<rfc category="exp" docName="draft-agache-tcpm-sndbufadv-00" ipr="trust200902">
  <front>  
    <title abbrev="TCP Sendbuffer Advertising">TCP Sendbuffer Advertising</title>
    
    <author fullname="Alexandru Agache" initials="A." surname="Agache">
      <organization>University Politehnica of Bucharest</organization>
      <address>
        <postal>
          <street>Splaiul Independentei 313</street>
          <city>Bucharest</city>
          <code></code>
          <country>Romania</country>
        </postal>
        <email>alexandru.agache@cs.pub.ro</email>
      </address>
    </author>
        
    <author fullname="Costin Raiciu" initials="C." surname="Raiciu">
      <organization>University Politehnica of Bucharest</organization>
      <address>
        <postal>
          <street>Splaiul Independentei 313</street>
          <city>Bucharest</city>
          <code></code>
          <country>Romania</country>
        </postal>
        <email>costin.raiciu@cs.pub.ro</email>
      </address>
    </author>

    <date day="20" month="July" year="2015" />

    <area>General</area>
    
    <workgroup>Internet Engineering Task Force</workgroup>
    
    <keyword>tcp option sendbuffer header field reuse</keyword>
    
    <abstract>
    <t>Network operators have difficulty in understanding the
      end-to-end performance of TCP connections through their
      networks. By observing packets at
      different vantage points on their path and maintaining per flow state, 
      network operators can detect packet losses, retransmission and estimate
      RTTs, among other metrics. A key information needed by networks is whether a connection is limited by
      the network or by the application. This information is very difficult to 
      accurately infer by passive measurements.</t>

      <t>We propose to advertise sendbuffer occupancy in TCP:
      each segment will carry the amount of backlogged data present in the sender's buffer.
      This information allows networks to discern between application-limited, network-limited
      and flow-control limited flows, creating new avenues of network optimization.
      </t>
    </abstract>
    
  </front>

  <middle>
  
  <section title="Requirements Language">
  <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 <xref target="RFC2119">RFC 2119</xref>.</t>
  </section>
  
  <section title="Introduction" anchor="sec_intro">
  <t>Aggregate link statistics, such as packet and loss counts, are easily available in modern
    networks, but they convey a fairly limited picture of network performance. In many cases,
    the network needs information about individual flows' demand for bandwidth to take the 
    appropriate resource allocation decisions.</t>

  <t>One example is a mobile phone streaming audio or video over a WiFi connection. The default
    strategy is to always stick to WiFi when available, despite the fact that performance may 
    be terrible and seriously impair user experience. If the mobile network knew the multimedia stream needs
    more bandwidth, it could fire-up the cellular connection and migrate traffic over there 
    by using mobile client offloading software relying on Multipath TCP <xref target="NSDI-12" /> 
    or Mobile IP <xref target="RFC5944" />. </t>

  <t>Another example is in datacenters with Clos topologies (such as
    the popular FatTree topology <xref target="FatTree" />), where elephant flows are
    randomly placed on paths with flow-level Equal Cost Multipath
    Routing; when one or more elephant flows are placed on the same link,
    performance degrades despite existing capacity elsewhere in the
    network. The network can reroute such flows by using tunnels or
    programmable switches (e.g. Openflow) but the one thing missing is
    the information regarding which flows could utilize more capacity
    if given a better path. </t>

    <t>Determining if a TCP connection is network limited or not is
      difficult to do by passive monitoring. The network needs to keep
      per-flow state, to estimate the sender congestion window and to
      accurately monitor flight-size. When flight-size is smaller than the
      congestion window and the receive window, the connection is limited by 
      the application and does not need more capacity. </t>

    <t> We propose that each TCP segment should also encode the amount of backlogged data in the TCP sendbuffer.
      This information enables network boxes and receivers to easily identify connections that need more capacity.
      Our goal is to have this extension "always on", and it is therefore very important to reduce its overhead.
      Next, we discuss how to compute and report the amount of backlogged data. We follow with a discussion of
      signaling options for conveying sendbuffer information. </t>
      
  </section>
  
  <section title="TCP Sendbuffer Structure" anchor="sec_struct">

    <figure>
    <artwork align="left"><![CDATA[           

                     1          2     
            ---|----------|----------|--->
            SND.UNA    SND.NXT   WRITE.SEQ
                                     

        1 - sequence numbers of unacknowledged, in flight data            
        2 - sequence numbers of backlogged data. 
         
                 Anatomy of the TCP Sendbuffer
            ]]></artwork>
</figure>

  <t>The figure above shows the anatomy of the TCP sendbuffer. 
  SND.UNA represents the oldest sequence number sent but not yet acknowledged. At the other end there is WRITE.SEQ, the
  tail sequence number of data held in the sendbuffer. Somewhere in-between we have SND.NXT, the sequence number of the 
  next byte to be sent. From SND.NXT to WRITE.SEQ we have backlogged data, written by the application but not yet 
  transmitted. </t>

  <t>SND.NXT is constrained by both the receive window and the congestion window as follows: </t>
  <figure>
    <artwork align="left"><![CDATA[           
        SND.NXT <= SND.UNA + min(SND.WND, SND.CWND)
            ]]></artwork>
  </figure>

  <t>As long as the receive window is not a bottleneck, and in the absence of hardware issues or software bugs, 
    having SND.NXT smaller than WRITE.SEQ indicates that the congestion window is not large enough, so the connection 
    is network limited at that point in time.
    The easiest way to implement sendbuffer advertising is to simply copy the amount of backlogged data (WRITE.SEQ-SND.NXT) 
    into the segment when it leaves the TCP stack. However, this will result in non-zero sendbuffer advertisement when
    the connection is application-limited but the application writes bursts of a few packets. These packets will be sent
    out immediately on the wire, yet the first packets in the burst will report that the application is backlogged,
    when in fact it isn't. </t>

  <t>To correctly implement sendbuffer advertisement, the sender MUST advertise the amount of backlogged according 
    to the formula below:</t>

  <figure>
    <artwork align="left"><![CDATA[           
        SEG.SNDBUF = WRITE.SEQ-SND.UNA - min(SND.WND, SND.CWND), 
                      if WRITE.SEQ > SND.UNA + min(SND.WND, SND.CWND)

        SEG.SNDBUF = 0, otherwise
            ]]></artwork>
  </figure>
  
  <t>This formula ensures that if an application write fits in the current receive and congestion windows,
  all the resulting segments will advertise zero backlog data. </t>

  </section>
  
  <section title="Negotiating sendbuffer advertising" anchor="sec_negotiate">

    <t>The standard way to extend TCP is to negotiate the extension during the three-way handshake. The TCP
      option space, however, is already very crowded in the SYN exchange. Until solutions that extend
      the TCP option space are standardized, negotiation in the SYN exchange is, in our view, not a feasible option
      for sendbuffer advertising.
      </t>
      
    <t>Fortunately, sendbuffer advertising is a sender-side only modification to TCP, and the information it makes
      available can be used anyone that understands it, be it the network or the receiver. This implies 
      that we can simply bypass the three way handshake as long as the actual encoding of the sendbuffer information 
      in TCP segments does not have negative effects to legacy routers, middleboxes and TCP receivers. We
      discuss encoding in the next section.</t>

    <t>TCP sendbuffer advertising will therefore be a simple sender-only enhancement to the TCP stack that can
    be enabled by using system-wide configuration (e.g. sysctl in Linux). </t>

  </section>
    
  <section title="Encoding sendbuffer information" anchor="sec_encoding">

    <t>In this section we discuss two encoding alternatives for sendbuffer information: as new TCP options,
      in the acknowledgement field of data segments and in the receive-window field.</t>

    <t>The first solution is to simply encode sendbuffer information in a new TCP option on every segment
      carrying data in a TCP connection, without negotiating this extension in the three way handshake. This 
      only adds 6B of overhead to each TCP segment. This option is feasible only when there is sufficient space 
      in the TCP option field of the corresponding data segment.</t>

      <t>Avoding the option negotiation will work really well in datacenters
      where it can be ensured out-of-band that all machines either know sendbuffer advertising or are unaffected
      by segments carrying new options. In the Internet, before advertising sendbuffer information in new TCP options 
	we need to ensure that: a) existing TCP stacks are robust to unknown options, simply ignoring them, and b) middleboxes do not 
      drop segments carrying unknown options. 
	Existing studies <xref target="IMC-11" /> imply that the wide majority of network paths
      either allow unknown options or drop the options, allowing the segments through. Only a very small fraction
    of paths drop the segments with unknown options. To cope with such cases, the implementation MUST NOT include
    sendbuffer information on retransmitted packets, to ensure that the connection makes some progress even in the
    presence of such middleboxes.</t>

  <t>Our second solution is based on the observation that while TCP
    itself is bidirectional, most connections in practice will
    transfer data unidirectionally most times. The endpoints can be
    either data senders or receivers at different moments, but they
    rarely act as both at the same time. When traffic is
    unidirectional, the sender sends the same value for the
    acknowledgement number and receive window field over and over
    again. </t>
  
  <t>We propose to reuse one or both of these fields to
    advertise sendbuffer information instead when traffic is
    unidirectional. To detect unidirectional traffic, the sender will maintain a state variable 
    called SND.NUM_SEG that is initially set to zero, and is zeroed whenever
    a segment with a valid ACK field is sent out. SND.NUM_SEG will be incremented whenever a segment 
    is received. A sendbuffer advertisment SHOULD be encoded in outgoing segments only when
    SND.NUM_SEG = 0.
  </t>
      
  <t>Sendbuffer advertising will encode the proper value in the ACK field and NOT set the ACK flag. 
  This ensures the receiver and other on-path hosts will ignore the field altogether. We still need,
  however, to inform parties interested in sendbuffer information they can use the value of the ACK field.</t>
  
  <t>In datacenters, we can simply define one of the reserved TCP flags as the sendbuffer advertisement flag.
    When this flag is set, the sendbuffer value is encoded in the ACK field. The sendbuffer advertisement
    flag and the ACK flag CANNOT be set simultaneously.
  </t>

  <t>In the Internet, redefining the meaning of one of the reserved
    flags will simply not work through existing middleboxes;
    additionally, certain middleboxes may zero the ACK field when the
    ACK flag is not set. In this context, we propose to use the
    receive window field in segments carrying sendbuffer information
    to encode a checksum of this information.  Interested parties
    will: a) scan for data segments with the ACK flag not set, b)
    compute a 1's complement checksum of the ACK field and check it
    against the receive window field. In case of a match, the
    sendbuffer information can be used. To understand the feasibility
    of this encoding, however, tests must to be conducted to check the
    behaviour of middleboxes when the ACK flag is not set.</t>
  </section>
  </middle>
  
  <back>
    <references title="Normative References">
      &RFC2119;
    </references>
    
    <references title="Informative References">
      <reference anchor="RFC5944"><front><title>IP Mobility Support for IPv4, Revised</title><author initials="C." surname="Perkins" fullname="C. Perkins"><organization/></author><date year="2010" month="November"/><abstract><t>This document specifies protocol enhancements that allow transparent routing of IP datagrams to mobile nodes in the Internet.  Each mobile node is always identified by its home address, regardless of its current point of attachment to the Internet.  While situated away from its home, a mobile node is also associated with a care-of address, which provides information about its current point of attachment to the Internet.  The protocol provides for registering the care-of address with a home agent.  The home agent sends datagrams destined for the mobile node through a tunnel to the care-of address.  After arriving at the end of the tunnel, each datagram is then delivered to the mobile node. [STANDARDS-TRACK]</t></abstract></front><seriesInfo name="RFC" value="5944"/><format type="TXT" octets="239935" target="http://www.rfc-editor.org/rfc/rfc5944.txt"/></reference>
      <reference anchor="NSDI-12" target="http://dl.acm.org/citation.cfm?id=2228298.2228338"><front><title>How hard can it be? designing and implementing a deployable multipath tcp</title><author fullname="Costin Raiciu" initials="C." surname="Raiciu" /><author fullname="Christoph Paasch" initials="C." surname="Paasch" /><author fullname="Sebastien Barre" initials="S." surname="Barre" /><author fullname="Alan Ford" initials="A." surname="Ford" /><author fullname="Michio Honda" initials="M." surname="Honda" /><author fullname="Fabien Duchene" initials="F." surname="Duchene" /><author fullname="Olivier Bonaventure" initials="O." surname="Bonaventure" /><author fullname="Mark Handley" initials="M." surname="Handley" /><date year="2012" /></front></reference>
      <reference anchor="FatTree" target="http://doi.acm.org/10.1145/1402958.1402967"><front><title>A scalable, commodity data center network architecture</title><author fullname="Mohammad Al-Fares" initials="M." surname="Al-Fares" /><author fullname="Alexander Loukissas" initials="A." surname="Loukissas" /><author fullname="Amin Vahdat" initials="A." surname="Vahdat" /><date year="2008" /><keyword>data center topology</keyword><keyword> equal-cost routing</keyword></front></reference>
      <reference anchor="IMC-11" target="http://doi.acm.org/10.1145/2068816.2068834"><front><title>Is it still possible to extend tcp?</title><author fullname="Michio Honda" initials="M." surname="Honda" /><author fullname="Yoshifumi Nishida" initials="Y." surname="Nishida" /><author fullname="Costin Raiciu" initials="C." surname="Raiciu" /><author fullname="Adam Greenhalgh" initials="A." surname="Greenhalgh" /><author fullname="Mark Handley" initials="M." surname="Handley" /><author fullname="Hideyuki Tokuda" initials="H." surname="Tokuda" /><date year="2011" /><keyword>TCP</keyword><keyword> measurements</keyword><keyword> middleboxes</keyword><keyword> protocol design</keyword></front></reference>
    </references>
  </back>
</rfc>
