mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-29 01:31:19 +02:00
BUG/MEDIUM: h2: make sure the last stream closes the connection after a timeout
If a timeout strikes on the connection side with some active streams, there is a corner case which can sometimes cause the following sequence to happen : - There are active streams but there are data in the mux buffer (eg: a client suddenly disconnected during a download with pending requests). The timeout is active. - The timeout strikes, h2_timeout_task() is called, kills the task and doesn't close the connection since there are streams left ; The connection is marked in H2_CS_ERROR ; - the streams are woken up and closed ; - when the last stream closes, calling h2_detach(), it sees the tree list is empty, but there is no condition allowing the connection to be closed (mbuf->o > 0), thus it does nothing ; - since the task is dead, there's no more hope to clear this situation later For now we can take care of this by adding a test for the presence of H2_CS_ERROR and !task, implying the timeout task triggered already and will not be able to handle this again. Over the long term it seems like a more reliable test on should be made, so that it is possible to know whether or not someone is still able to close this connection. A big thanks to Janusz Dziemidowicz and Milan Petruzelka for providing many details helping in figuring this bug.
This commit is contained in:
parent
00610960a1
commit
42d55b9b6a
@ -2493,6 +2493,7 @@ 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) ||
|
||||
(!h2c->mbuf->o && /* mux buffer empty, also process clean events below */
|
||||
(conn_xprt_read0_pending(h2c->conn) ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user