From: Willy Tarreau Date: Tue, 10 Oct 2017 13:16:55 +0000 (+0200) Subject: MEDIUM: h2: detect the presence of the first settings frame X-Git-Tag: v1.8-rc1~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4c3690bf960e3e4274e1689b7d4faebbf6cf6e9c;p=thirdparty%2Fhaproxy.git MEDIUM: h2: detect the presence of the first settings frame Instead of doing a special processing of the first SETTINGS frame, we simply parse its header, check that it matches the expected frame type and flags (ie no ACK), and switch to FRAME_P to parse it as any regular frame. The regular frame parser will take care of decoding it. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index d2d8574fa3..71111eb53d 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -771,7 +771,41 @@ static void h2_process_demux(struct h2c *h2c) h2c->max_id = 0; h2c->st0 = H2_CS_SETTINGS1; } - /* deal with SETTINGS here */ + + if (h2c->st0 == H2_CS_SETTINGS1) { + struct h2_fh hdr; + + /* ensure that what is pending is a valid SETTINGS frame + * without an ACK. + */ + if (!h2_get_frame_hdr(h2c->dbuf, &hdr)) { + /* RFC7540#3.5: a GOAWAY frame MAY be omitted */ + if (h2c->st0 == H2_CS_ERROR) + h2c->st0 = H2_CS_ERROR2; + goto fail; + } + + if (hdr.sid || hdr.ft != H2_FT_SETTINGS || hdr.ff & H2_F_SETTINGS_ACK) { + /* RFC7540#3.5: a GOAWAY frame MAY be omitted */ + h2c_error(h2c, H2_ERR_PROTOCOL_ERROR); + h2c->st0 = H2_CS_ERROR2; + goto fail; + } + + if ((int)hdr.len < 0 || (int)hdr.len > h2c->mfs) { + /* RFC7540#3.5: a GOAWAY frame MAY be omitted */ + h2c_error(h2c, H2_ERR_FRAME_SIZE_ERROR); + h2c->st0 = H2_CS_ERROR2; + goto fail; + } + + /* that's OK, switch to FRAME_P to process it */ + h2c->dfl = hdr.len; + h2c->dsi = hdr.sid; + h2c->dft = hdr.ft; + h2c->dff = hdr.ff; + h2c->st0 = H2_CS_FRAME_P; + } } return;