QUIC flow control

585 views
Skip to first unread message

Felix Maurer

unread,
Jun 1, 2015, 3:48:50 PM6/1/15
to proto...@chromium.org
Hi, I'm also currently looking into the flow control of QUIC. First to make sure that I did understand everything correctly so far.
QUIC does not increase the sending window on ACKs, only on WINDOW_UPDATE frames.

I have problems with sending more than 16kB of data in a QuicDataStream. (I'm trying not to use any SPDY related functions, including the headers stream)
I noticed that in the ReliableQuicStream, the flow controller is initialized so that receive_window_offset and max_receive_window are the same.
After looking at the code of MaybeSendWindowUpate I converted the the condition on when to send the the window update message on the condition that receive_window_offset and max_receive_window are the same.

(rwo - bc) < (mrw / 2)   rwo = mrw
(rwo - bc) < (rwo / 2)    /rwo
(1 - bc/rwo) < (1 / 2) / * -1 + 1
(bc/rwo) > (1/2) / * rwo
(bc) > (rwo/2)

To me it seems that, by default, the byte count send has to be more than half the receive_window_offset. Also, I found out that the default for the send_window_offset is 16kB and the default of the receive_window_offset is 64kb, so the equation will never be true. I could solve this by setting a custom send_window_offset.
However, the server still does not send window update frames. Am I missing something? Are window update frames only sent in a special stream?

In general, is there documentation about how the flow control works? The design document does not cover much.

Romain Jacotin

unread,
Jun 1, 2015, 4:29:00 PM6/1/15
to proto...@chromium.org
I drew a diagram :


Ryan Hamilton

unread,
Jun 1, 2015, 5:12:52 PM6/1/15
to proto...@chromium.org
Clearly we need a doc to make this more clear. I'll get to work on one :> In the mean time, Section 5.2. (Flow Control) of the HTTP/2 RFC does a decent job of laying out the flow control scheme used by both QUIC and HTTP/2. (Although since QUIC is unreliable, the QUIC WINDOW_UPDATE frame needs to speak in absolute offset terms, whereas the HTTP/2 WINDOW_UPDATE frame speaks in terms of deltas).


On Mon, Jun 1, 2015 at 12:48 PM, Felix Maurer <felix0...@gmail.com> wrote:
Hi, I'm also currently looking into the flow control of QUIC. First to make sure that I did understand everything correctly so far.
QUIC does not increase the sending window on ACKs, only on WINDOW_UPDATE frames.

​That's correct. TCP is quite similar in this regard.
 
I have problems with sending more than 16kB of data in a QuicDataStream. (I'm trying not to use any SPDY related functions, including the headers stream)
I noticed that in the ReliableQuicStream, the flow controller is initialized so that receive_window_offset and max_receive_window are the same.
After looking at the code of MaybeSendWindowUpate I converted the the condition on when to send the the window update message on the condition that receive_window_offset and max_receive_window are the same.

(rwo - bc) < (mrw / 2)   rwo = mrw
(rwo - bc) < (rwo / 2)    /rwo
(1 - bc/rwo) < (1 / 2) / * -1 + 1
(bc/rwo) > (1/2) / * rwo
(bc) > (rwo/2)

To me it seems that, by default, the byte count send has to be more than half the receive_window_offset.

​By default, the QUIC flow controller will not send a WINDOW_UPDATE until at least half of the window has been consumed.​
 
Also, I found out that the default for the send_window_offset is 16kB and the default of the receive_window_offset is 64kb, so the equation will never be true. I could solve this by setting a custom send_window_offset.
However, the server still does not send window update frames. Am I missing something?

​I don't think I understand the question. If you add logging to the toy quic_client or quic_server and send requests back and forth, you should see WINDOW_UPDATE frames being received. 
 
Are window update frames only sent in a special stream?

Note, these are QUIC frames which are not delivered in the payload of a particular stream​ but instead have a stream_id field in them.

Cheers,

Ryan

Felix Maurer

unread,
Jun 2, 2015, 9:29:28 AM6/2/15
to proto...@chromium.org
 
Also, I found out that the default for the send_window_offset is 16kB and the default of the receive_window_offset is 64kb, so the equation will never be true. I could solve this by setting a custom send_window_offset.
However, the server still does not send window update frames. Am I missing something?

​I don't think I understand the question. If you add logging to the toy quic_client or quic_server and send requests back and forth, you should see WINDOW_UPDATE frames being received. 

I don't use the toy quic_client and quic_server, I'm trying to write a QUIC application that does not use SPDY.
When I don't specify a size for the windows, the client will use a 16kB send_window_offset and the server will use a 64kB receive_window_offset. Therefore the server will never send a WINDOW_UPDATE frame by default.
When I set a send_window_offset of 48kB, the MaybeSendWindowUpdate in the server is called, but the WINDOW_UPDATE frame is only queued in the packet generator and not sent.

I don't really understand under which conditions these WINDOW_UPDATE frames will be sent.
 
 
Are window update frames only sent in a special stream?

Note, these are QUIC frames which are not delivered in the payload of a particular stream​ but instead have a stream_id field in them.

Oh OK, that makes sense.

Regards
Felix

Ryan Hamilton

unread,
Jun 2, 2015, 10:06:45 AM6/2/15
to proto...@chromium.org
On Tue, Jun 2, 2015 at 6:29 AM, Felix Maurer <felix0...@gmail.com> wrote:
 
Also, I found out that the default for the send_window_offset is 16kB and the default of the receive_window_offset is 64kb, so the equation will never be true. I could solve this by setting a custom send_window_offset.
However, the server still does not send window update frames. Am I missing something?

​I don't think I understand the question. If you add logging to the toy quic_client or quic_server and send requests back and forth, you should see WINDOW_UPDATE frames being received. 

I don't use the toy quic_client and quic_server, I'm trying to write a QUIC application that does not use SPDY.

​Understood, but if you're trying to understand how the code works, I recommend following what happens when the quic_client talks to the quic_server.​
 
When I don't specify a size for the windows, the client will use a 16kB send_window_offset and the server will use a 64kB receive_window_offset. Therefore the server will never send a WINDOW_UPDATE frame by default.
When I set a send_window_offset of 48kB, the MaybeSendWindowUpdate in the server is called, but the WINDOW_UPDATE frame is only queued in the packet generator and not sent.

​That's surprising.​
 
​When a frame is sent to the packet generator, it should be sent very soon after. Perhaps something else is going on.​

I don't really understand under which conditions these WINDOW_UPDATE frames will be sent.

​A WINDOW_UPDATE is sent when half of the available window has been consumed. (This is the behavior of our implementation, not a requirement of the protocol)

Cheers,

Ryan

Felix Maurer

unread,
Jun 9, 2015, 5:38:39 AM6/9/15
to proto...@chromium.org
My bad :/ I forgot to activate the outbound stream. Now everything works fine.
Reply all
Reply to author
Forward
0 new messages