From: Willy Tarreau Date: Thu, 3 Jan 2019 07:27:41 +0000 (+0100) Subject: BUG/MEDIUM: mux-h2: always restart reading if data are available X-Git-Tag: v2.0-dev1~299 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=872e2fac397cf931f237ae9c6ad3c56ec105f417;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-h2: always restart reading if data are available h2c_restart_reading() is used at various place to resume processing of demux data, but this one refrains from doing so if the mux is already subscribed for receiving. It just happens that even if some incoming frame processing is interrupted, the mux is always subscribed for receiving, so this condition alone is not enough, it must be combined with the fact that the demux buffer is empty, otherwise some resume events are lost. This typically happens when we refrain from processing some incoming data due to missing room in the stream's rxbuf, and want to resume in h2c_rcv_buf(). It will become even more visible with trailers since these ones want to have an empty rxbuf before proceeding. This must be backported to 1.9. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index e0859b91ac..c159225573 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -301,7 +301,7 @@ static inline void h2c_restart_reading(const struct h2c *h2c) { if (!h2_recv_allowed(h2c)) return; - if (h2c->wait_event.events & SUB_RETRY_RECV) + if (!b_data(&h2c->dbuf) && (h2c->wait_event.events & SUB_RETRY_RECV)) return; tasklet_wakeup(h2c->wait_event.task); } @@ -4802,8 +4802,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun if (ret && h2c->dsi == h2s->id) { /* demux is blocking on this stream's buffer */ h2c->flags &= ~H2_CF_DEM_SFULL; - if (b_data(&h2c->dbuf) || !(h2c->wait_event.events & SUB_RETRY_RECV)) - h2c_restart_reading(h2c); + h2c_restart_reading(h2c); } end: return ret;