]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h2: always restart reading if data are available
authorWilly Tarreau <w@1wt.eu>
Thu, 3 Jan 2019 07:27:41 +0000 (08:27 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 3 Jan 2019 08:28:59 +0000 (09:28 +0100)
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

index e0859b91ace0f709698afab0fd534e0340bc2f5a..c15922557336bf460b297350b7646dc6593bad6c 100644 (file)
@@ -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;