From 3ca18bf0bd45a86f35b9367fde301fa5d9e48731 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Fri, 5 Apr 2019 15:34:34 +0200 Subject: [PATCH] BUG/MEDIUM: h2: Don't attempt to recv from h2_process_demux if we subscribed. Modify h2c_restart_reading() to add a new parameter, to let it know if it should consider if the buffer isn't empty when retrying to read or not, and call h2c_restart_reading() using 0 as a parameter from h2_process_demux(). If we're leaving h2_process_demux() with a non-empty buffer, it means the frame is incomplete, and we're waiting for more data, and if we already subscribed, we'll be waken when more data are available. Failing to do so means we'll be waken up in a loop until more data are available. This should be backported to 1.9. --- src/mux_h2.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index 9894592e58..76343613a1 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -332,11 +332,12 @@ static inline int h2_recv_allowed(const struct h2c *h2c) } /* restarts reading on the connection if it was not enabled */ -static inline void h2c_restart_reading(const struct h2c *h2c) +static inline void h2c_restart_reading(const struct h2c *h2c, int consider_buffer) { if (!h2_recv_allowed(h2c)) return; - if (!b_data(&h2c->dbuf) && (h2c->wait_event.events & SUB_RETRY_RECV)) + if ((!consider_buffer || !b_data(&h2c->dbuf)) + && (h2c->wait_event.events & SUB_RETRY_RECV)) return; tasklet_wakeup(h2c->wait_event.task); } @@ -360,7 +361,7 @@ static int h2_buf_available(void *target) if ((h2c->flags & H2_CF_DEM_DALLOC) && b_alloc_margin(&h2c->dbuf, 0)) { h2c->flags &= ~H2_CF_DEM_DALLOC; - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 1); return 1; } @@ -369,7 +370,7 @@ static int h2_buf_available(void *target) if (h2c->flags & H2_CF_DEM_MROOM) { h2c->flags &= ~H2_CF_DEM_MROOM; - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 1); } return 1; } @@ -378,7 +379,7 @@ static int h2_buf_available(void *target) (h2s = h2c_st_by_id(h2c, h2c->dsi)) && h2s->cs && b_alloc_margin(&h2s->rxbuf, 0)) { h2c->flags &= ~H2_CF_DEM_SALLOC; - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 1); return 1; } @@ -567,7 +568,7 @@ static int h2_init(struct connection *conn, struct proxy *prx, struct session *s conn->ctx = h2c; /* prepare to read something */ - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 1); return 0; fail_stream: hpack_dht_free(h2c->ddht); @@ -2529,7 +2530,7 @@ static void h2_process_demux(struct h2c *h2c) h2s_notify_recv(h2s); } - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 0); } /* process Tx frames from streams to be multiplexed. Returns > 0 if it reached @@ -3011,7 +3012,7 @@ static void h2_detach(struct conn_stream *cs) !h2_frt_has_too_many_cs(h2c)) { /* frontend connection was blocking new streams creation */ h2c->flags &= ~H2_CF_DEM_TOOMANY; - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 1); } /* this stream may be blocked waiting for some data to leave (possibly @@ -3029,7 +3030,7 @@ static void h2_detach(struct conn_stream *cs) */ h2c->flags &= ~H2_CF_DEM_BLOCK_ANY; h2c->flags &= ~H2_CF_MUX_BLOCK_ANY; - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 1); } h2s_destroy(h2s); @@ -5258,7 +5259,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; - h2c_restart_reading(h2c); + h2c_restart_reading(h2c, 1); } return ret; -- 2.39.5