From 872e2fac397cf931f237ae9c6ad3c56ec105f417 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 3 Jan 2019 08:27:41 +0100 Subject: [PATCH] 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. --- src/mux_h2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index e0859b91a..c15922557 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;