From 4dbda620f2872b33aefc8c87ac34f7c71dbd1701 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 31 Jan 2019 18:48:20 +0100 Subject: [PATCH] BUG/MEDIUM: mux-h2: wait for the mux buffer to be empty before closing the connection When finishing to respond on a stream, a shutw() is called (resulting in either an end of stream or RST), then h2_detach() is called, and may decide to kill the connection is a number of conditions are satisfied. Actually one of these conditions is that a GOAWAY frame was already sent or attempted to be sent. This one is wrong, because it can happen in at least these two situations : - a shutw() sends a GOAWAY to obey tcp-request content reject - a graceful shutdown is pending In both cases, the connection will be aborted with the mux buffer holding some data. In case of a strong abort the client will not see the GOAWAY or RST and might want to try again, which is counter-productive. In case of the graceful shutdown, it could result in truncated data. It looks like a valid candidate for the issue reported here : https://www.mail-archive.com/haproxy@formilux.org/msg32433.html A backport to 1.9 and 1.8 is necessary. --- src/mux_h2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index dc91756dc..503c40da1 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3003,7 +3003,6 @@ static void h2_detach(struct conn_stream *cs) if (eb_is_empty(&h2c->streams_by_id) && /* don't close if streams exist */ ((h2c->conn->flags & CO_FL_ERROR) || /* errors close immediately */ (h2c->st0 >= H2_CS_ERROR && !h2c->task) || /* a timeout stroke earlier */ - (h2c->flags & (H2_CF_GOAWAY_FAILED | H2_CF_GOAWAY_SENT)) || (!(h2c->conn->owner)) || /* Nobody's left to take care of the connection, drop it now */ (!b_data(&h2c->mbuf) && /* mux buffer empty, also process clean events below */ (conn_xprt_read0_pending(h2c->conn) ||