From: Christopher Faulet Date: Fri, 29 Oct 2021 12:37:07 +0000 (+0200) Subject: BUG/MEDIUM: http-ana: Drain request data waiting the tarpit timeout expiration X-Git-Tag: v2.5-dev12~12 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=b0c87f1c61edbc4e4affd81d2fd02e113528cf03;p=haproxy-2.5.git BUG/MEDIUM: http-ana: Drain request data waiting the tarpit timeout expiration When a tarpit action is performed, we must be sure to drain data from the request channel. Otherwise, the mux on the frontend side may be blocked because the request channel buffer is full. This may lead to Two bugs. The first one is a HOL blocking on the H2 multiplexer. A tarpitted stream may block all the others because data are not drained for the whole tarpit timeout. The second bug is a ping-pong loop between the multiplexer and the stream. The mux is waiting for more space in the channel buffer, so it wakes up the stream. And the stream systematically re-enables receives. This last part is not pretty clean and it will be addressed with another fix. But draning request data is a good way to fix both bugs in same time. This patch must be backported as far as 2.0. The legacy HTTP mode is probably affected, but I don't know if same bugs may be experienced in this mode. --- diff --git a/src/http_ana.c b/src/http_ana.c index a06a20a..9d11284 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -837,6 +837,8 @@ int http_process_tarpit(struct stream *s, struct channel *req, int an_bit) channel_dont_connect(req); if ((req->flags & (CF_SHUTR|CF_READ_ERROR)) == 0 && !tick_is_expired(req->analyse_exp, now_ms)) { + /* Be sure to drain all data from the request channel */ + channel_htx_erase(req, htxbuf(&req->buf)); DBG_TRACE_DEVEL("waiting for tarpit timeout expiry", STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn); return 0;