From 97aaa6765870d9fd32900ab83d124e58fec6d09b Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 23 Dec 2018 09:49:04 +0100 Subject: [PATCH] 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. --- src/mux_h2.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index 5274071220..5ad32147ad 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -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_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_WINDOW_OPENED 0x00010000 // demux increased window already advertised /* H2 connection state, in h2c->st0 */ enum h2_cs { @@ -436,7 +437,7 @@ static int h2_init(struct connection *conn, struct proxy *prx, struct session *s h2c->conn = conn; h2c->max_id = -1; h2c->errcode = H2_ERR_NO_ERROR; - h2c->rcvd_c = H2_INITIAL_WINDOW_INCREMENT; + h2c->rcvd_c = 0; h2c->rcvd_s = 0; h2c->nb_streams = 0; h2c->nb_cs = 0; @@ -1542,6 +1543,14 @@ static int h2c_send_conn_wu(struct h2c *h2c) if (h2c->rcvd_c <= 0) 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 */ ret = h2c_send_window_update(h2c, 0, h2c->rcvd_c); if (ret > 0)