From: Christopher Faulet Date: Wed, 10 Nov 2021 14:12:47 +0000 (+0100) Subject: BUG/MEDIUM: conn-stream: Don't reset CS flags on close X-Git-Tag: v2.5-dev14~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f14d750bf;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: conn-stream: Don't reset CS flags on close cs_close() and cs_drain_and_close() are called to close a conn-stream. cs_shutr() and cs_shutw() are called with the appropriate modes. But the conn-stream is not released at this stage. However the flags are reset. Thus, after a cs_close(), we loose shutdown flags. If cs_close() is performed several times, it is a problem. And indeed, it is possible. On one hand, the stream-interface may close the conn-stream. On the other end, the stream always closes it when it is released. It is a problem for the H1 multiplexer. Because the conn-stream flags are reset, the shutr and shutw are performed twice. For a delayed shutdown, the dirty mode is used instead of the normal one because the last call to h1_shutw() overwrite H1C flags set by the first call. This leads to dirty shutdowns while normal ones are required. At the end, it is possible to truncate the messages. This bug was revealed by the commit a85c522d4 ("BUG/MINOR: mux-h1: Save shutdown mode if the shutdown is delayed"). This patch is related to the issue #1450. It must be backported as far as 2.0. --- diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index 49f5d3f0fa..c42ca17e6b 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -271,7 +271,6 @@ static inline void cs_close(struct conn_stream *cs) { cs_shutw(cs, CS_SHW_SILENT); cs_shutr(cs, CS_SHR_RESET); - cs->flags = CS_FL_NONE; } /* completely close a conn_stream after draining possibly pending data (but do not detach it) */ @@ -279,7 +278,6 @@ static inline void cs_drain_and_close(struct conn_stream *cs) { cs_shutw(cs, CS_SHW_SILENT); cs_shutr(cs, CS_SHR_DRAIN); - cs->flags = CS_FL_NONE; } /* sets CS_FL_ERROR or CS_FL_ERR_PENDING on the cs */