]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h2: wait for the mux buffer to be empty before closing the connection
authorWilly Tarreau <w@1wt.eu>
Thu, 31 Jan 2019 17:48:20 +0000 (18:48 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 31 Jan 2019 18:38:25 +0000 (19:38 +0100)
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

index dc91756dc78436240f875873a2e7a3a596d8aae6..503c40da1bdc9b205c40bde38087970ab54f5d10 100644 (file)
@@ -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) ||