From: Willy Tarreau Date: Fri, 19 Jan 2024 17:20:21 +0000 (+0100) Subject: MINOR: mux-h2: count excess of CONTINUATION frames as a glitch X-Git-Tag: v3.0-dev3~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28dfd006ca7289889f6238c1befca2f0d622a879;p=thirdparty%2Fhaproxy.git MINOR: mux-h2: count excess of CONTINUATION frames as a glitch Here we consider that if a HEADERS frame is made of more than 4 fragments whose average size is lower than 1kB, that's very likely an abuse so we count a glitch per 16 fragments, which means 1 glitch per 1kB frame in a 16kB buffer. This means that an abuser sending 1600 1-byte frames would increase the counter by 100, and that sending 100 headers per request in individual frames each results in a count of ~7 to be added per request. A test consisting in sending 100M requests made of 101 frames each over a connection resulted in ~695M glitches to be counted for this connection. Note that no special care is taken to avoid wrapping since it already takes a very long time to reach 100M and there's no particular impact of wrapping here (roughly 1M/s). --- diff --git a/src/mux_h2.c b/src/mux_h2.c index 6b9ca4b71f..19aecf352c 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -5128,7 +5128,8 @@ static int h2c_dec_hdrs(struct h2c *h2c, struct buffer *rxbuf, uint32_t *flags, struct buffer *copy = NULL; unsigned int msgf; struct htx *htx = NULL; - int flen; // header frame len + int flen = 0; // header frame len + int fragments = 0; int hole = 0; int ret = 0; int outlen; @@ -5203,6 +5204,7 @@ next_frame: hole += h2c->dpl + 9; h2c->dpl = 0; TRACE_STATE("waiting for next continuation frame", H2_EV_RX_FRAME|H2_EV_RX_FHDR|H2_EV_RX_CONT|H2_EV_RX_HDR, h2c->conn); + fragments++; goto next_frame; } @@ -5391,6 +5393,16 @@ next_frame: htx_to_buf(htx, rxbuf); free_trash_chunk(copy); TRACE_LEAVE(H2_EV_RX_FRAME|H2_EV_RX_HDR, h2c->conn); + + /* Check for abuse of CONTINUATION: more than 4 fragments and less than + * 1kB per fragment is clearly unusual and suspicious enough to count + * one glitch per 1kB fragment in a 16kB buffer, which means that an + * abuser sending 1600 1-byte frames in a 16kB buffer would increment + * its counter by 100. + */ + if (unlikely(fragments > 4) && fragments > flen / 1024 && ret != 0) + h2c->glitches += (fragments + 15) / 16; + return ret; fail: