MINOR: mux-h2: only increase the connection window with the first update

Commit dc57236 ("BUG/MINOR: mux-h2: advertise a larger connection window
size") caused a WINDOW_UPDATE message to be sent early with the connection
to increase the connection's window size. It turns out that it causes some
minor trouble that need to be worked around :
  - varnishtest cannot transparently cope with the WU frames during the
    handshake, forcing all tests to explicitly declare the handshake
    sequence ;
  - some vtc scripts randomly fail if the WU frame is sent after another
    expected response frame, adding uncertainty to some tests ;
  - h2spec doesn't correctly identify these WU at the connection level
    that it believes are the responses to some purposely erroneous frames
    it sends, resulting in some errors being reported

None of these are a problem with real clients but they add some confusion
during troubleshooting.

Since the fix above was intended to increase the upload bandwidth, we
have another option which is to increase the window size with the first
WU frame sent for the connection. This way, no WU frame is sent until
one is really needed, and this first frame will adjust the window to
the maximum value. It will make the window increase slightly later, so
the client will experience the first round trip when uploading data,
but this should not be perceptible, and is not worth the extra hassle
needed to maintain our debugging abilities. As an extra bonus, a few
extra bytes are saved for each connection until the first attempt to
upload data.

This should possibly be backported to 1.9 and 1.8.
This commit is contained in:
Willy Tarreau 2018-12-23 09:49:04 +01:00
parent fba74ea7b0
commit 97aaa67658
1 changed files with 10 additions and 1 deletions

View File

@ -61,6 +61,7 @@ static const struct h2s *h2_idle_stream;
#define H2_CF_GOAWAY_FAILED 0x00002000 // a GOAWAY frame failed to be sent #define H2_CF_GOAWAY_FAILED 0x00002000 // a GOAWAY frame failed to be sent
#define H2_CF_WAIT_FOR_HS 0x00004000 // We did check that at least a stream was waiting for handshake #define H2_CF_WAIT_FOR_HS 0x00004000 // We did check that at least a stream was waiting for handshake
#define H2_CF_IS_BACK 0x00008000 // this is an outgoing connection #define H2_CF_IS_BACK 0x00008000 // this is an outgoing connection
#define H2_CF_WINDOW_OPENED 0x00010000 // demux increased window already advertised
/* H2 connection state, in h2c->st0 */ /* H2 connection state, in h2c->st0 */
enum h2_cs { enum h2_cs {
@ -436,7 +437,7 @@ static int h2_init(struct connection *conn, struct proxy *prx, struct session *s
h2c->conn = conn; h2c->conn = conn;
h2c->max_id = -1; h2c->max_id = -1;
h2c->errcode = H2_ERR_NO_ERROR; h2c->errcode = H2_ERR_NO_ERROR;
h2c->rcvd_c = H2_INITIAL_WINDOW_INCREMENT; h2c->rcvd_c = 0;
h2c->rcvd_s = 0; h2c->rcvd_s = 0;
h2c->nb_streams = 0; h2c->nb_streams = 0;
h2c->nb_cs = 0; h2c->nb_cs = 0;
@ -1542,6 +1543,14 @@ static int h2c_send_conn_wu(struct h2c *h2c)
if (h2c->rcvd_c <= 0) if (h2c->rcvd_c <= 0)
return 1; return 1;
if (!(h2c->flags & H2_CF_WINDOW_OPENED)) {
/* increase the advertised connection window to 2G on
* first update.
*/
h2c->flags |= H2_CF_WINDOW_OPENED;
h2c->rcvd_c += H2_INITIAL_WINDOW_INCREMENT;
}
/* send WU for the connection */ /* send WU for the connection */
ret = h2c_send_window_update(h2c, 0, h2c->rcvd_c); ret = h2c_send_window_update(h2c, 0, h2c->rcvd_c);
if (ret > 0) if (ret > 0)