proposed WINDOW_UPDATE text for session flow control windows

Here's my commit in my github fork of the HTTP/2.0 spec:
https://github.com/willchan/http2-spec/commit/8ba562d34e33e784aad3549a8bab8a6bba87d508

Here's the HTML generated for that (it looks very broken, sorry, I am n00b
at this tooling):
http://htmlpreview.github.com/?https://github.com/willchan/http2-spec/blob/master/draft-ietf-httpbis-http2.html#WINDOW_UPDATE

Roberto and I have had some minimal discussion about this at my pull
request to his SPDY spec repo:
https://github.com/grmocg/SPDY-Specification/pull/4.

Note, I did not update the flow control principles section. I also did not
update the SETTINGS section, although arguably the SETTINGS id
SETTINGS_INITIAL_WINDOW_SIZE should be renamed to
SETTINGS_INITIAL_STREAM_WINDOW_SIZE to be explicit.

My diff is rather simple. It changes the text to indicate stream 0 is used
for the session window. It also does some minor wordsmithing because the
original text was pretty ambiguous. I'm included the full updated
WINDOW_UPDATE text here:

========================================

3.6.8.  WINDOW_UPDATE

   The WINDOW_UPDATE control frame is used to implement per stream and
   per session flow control in HTTP/2.0.  Flow control in HTTP/2.0 is
   per hop, that is, only between the two endpoints of a HTTP/2.0
   connection.  If there are one or more intermediaries between the
   client and the origin server, flow control signals are not explicitly
   forwarded by the intermediaries.  (However, throttling of data
   transfer by any recipient may have the effect of indirectly
   propagating flow control information upstream back to the original
   sender.)  Flow control only applies to the data portion of data
   frames.

   Flow control in SPDY is implemented by a data transfer window for



Belshe, et al.           Expires August 14, 2013               [Page 26]

Internet-Draft                  HTTP/2.0                   February 2013


   each stream and one for the entire session.  The data transfer window
   is a simple uint32 that indicates how many bytes of data the sender
   can transmit.  When the session starts, the sender initializes the
   session window to the initial session window size.  After a stream is
   created, but before any data frames have been transmitted, the sender
   initializes the stream window to the initial stream window size.  The
   window size is a measure of the buffering capability of the
   recipient.  The sender MUST NOT send a data frame with a data length
   greater than the session window size or the stream window size.
   After sending each data frame, the sender decrements both the per
   stream window size and the session window size by the amount of data
   transmitted.  When a stream window size becomes less than or equal to
   0, the sender MUST NOT send data frames for that stream, except for a
   zero length data frame with the FIN flag set.  Likewise, when the
   session window size becomes less than or equal to 0, the sender the
   sender MUST NOT send data frames for that stream, except for a zero
   length data frame with the FIN flag set.  The recipient can send a
   WINDOW_UPDATE frame back to notify the sender that it has consumed
   some data and freed up buffer space to receive more data for the
   stream or session.

   +----------------------------------+
   |1|   unused     |         9       |
   +----------------------------------+
   | 0 (flags) |     8 (length)       |
   +----------------------------------+
   |X|     Stream-ID (31-bits)        |
   +----------------------------------+
   |X|  Delta-Window-Size (31-bits)   |
   +----------------------------------+

   Control bit: The control bit is always 1 for this message.

   Unused

   Type: The message type for a WINDOW_UPDATE message is 9.

   Length: The length field is always 8 for this frame (there are 8
   bytes after the length field).

   Stream-ID: The stream ID that this WINDOW_UPDATE control frame is
   for.  If the stream ID value is 0, the WINDOW_UPDATE frame applies to
   the session window.

   Delta-Window-Size: The additional number of bytes that the sender can
   transmit in addition to existing remaining window size.  The legal
   range for this field is 1 to 2^31 - 1 (0x7fffffff) bytes.




Belshe, et al.           Expires August 14, 2013               [Page 27]

Internet-Draft                  HTTP/2.0                   February 2013


   The window size as kept by the sender must never exceed 2^31
   (although it can become negative in one special case).  If a sender
   receives a WINDOW_UPDATE that causes the window size to exceed this
   limit, then if the Stream-ID was 0, it MUST send a GOAWAY frame with
   status code FLOW_CONTROL_ERROR to terminate the session.  And if the
   Stream-ID references an active stream, it must send a RST_STREAM
   frame with status code FLOW_CONTROL_ERROR to terminate the stream.

   When a HTTP/2.0 connection is first established, the default initial
   window size for all streams is 64KB and the initial window size for
   the session is 64KB.  An endpoint can use the SETTINGS control frame
   to adjust the initial window size for the streams in the session.
   That is, its peer can start out using the 64KB default initial stream
   window size when sending data frames before receiving a SETTINGS
   frame.  Because SETTINGS is asynchronous, there may be a race
   condition if the recipient wants to decrease the initial window size,
   but its peer immediately sends 64KB on the creation of a new
   connection, before waiting for the SETTINGS to arrive.  This is one
   case where the window size kept by the sender will become negative.
   Once the sender detects this condition, it must stop sending data
   frames and wait for the recipient to catch up.  The recipient has two
   choices:

      immediately send RST_STREAM with FLOW_CONTROL_ERROR status code.

      allow the head of line blocking (as there is only one stream for
      the session and the amount of data in flight is bounded by the
      default initial window size), and send WINDOW_UPDATE as it
      consumes data.

   In the case of option 2, both sides must compute the stream window
   size based on the initial stream window size in the SETTINGS.  For
   example, if the recipient sets the initial stream window size to be
   16KB, and the sender sends 64KB for a stream immediately on session
   establishment, the sender will discover its window size is -48KB on
   receipt of the SETTINGS.  As the recipient consumes the first 16KB,
   it can send a WINDOW_UPDATE of 16KB back to the sender.  This
   interaction continues until the sender's window size becomes positive
   again, and it can resume transmitting data frames.

   After the recipient reads in a data frame with FLAG_FIN that marks
   the end of the data stream, it should not send WINDOW_UPDATE frames
   for the stream as it consumes the last data frame.  A sender should
   ignore all the WINDOW_UPDATE frames associated with the stream after
   it send the last frame for the stream.

   The data frames from the sender and the WINDOW_UPDATE frames from the
   recipient are completely asynchronous with respect to each other.



Belshe, et al.           Expires August 14, 2013               [Page 28]

Internet-Draft                  HTTP/2.0                   February 2013


   This property allows a recipient to aggressively update the window
   size kept by the sender to prevent the stream from stalling.

Received on Sunday, 10 February 2013 08:03:38 UTC