]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h2/htx: Always set CS flags before exiting h2_rcv_buf()
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 14 Feb 2019 14:12:14 +0000 (15:12 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 18 Feb 2019 15:25:06 +0000 (16:25 +0100)
It is especially important when some data are blocked in the RX buf and the
channel buffer is already full. In such case, instead of exiting the function
directly, we need to set right flags on the conn_stream. CS_FL_RCV_MORE and
CS_FL_WANT_ROOM must be set, otherwise, the stream-interface will subscribe to
receive events, thinking it is not blocked.

This bug leads to connection freeze when everything was received with some data
blocked in the RX buf and a channel full.

This patch must be backported to 1.9.

src/mux_h2.c

index adf8f144dbf6a3f22d465fdd94f4ddb73e92c1f4..9b50f7ecab24f2f8e0a089e09edb11e8cf2dd1fe 100644 (file)
@@ -5089,10 +5089,10 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
                /* in HTX mode we ignore the count argument */
                h2s_htx = htx_from_buf(&h2s->rxbuf);
                if (htx_is_empty(h2s_htx)) {
-                       if (cs->flags & CS_FL_REOS)
-                               cs->flags |= CS_FL_EOS;
-                       if (cs->flags & CS_FL_ERR_PENDING)
-                               cs->flags |= CS_FL_ERROR;
+                       /* Here htx_to_buf() will set buffer data to 0 because
+                        * the HTX is empty.
+                        */
+                       htx_to_buf(h2s_htx, &h2s->rxbuf);
                        goto end;
                }
 
@@ -5115,6 +5115,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
                ret = b_xfer(buf, &h2s->rxbuf, count);
        }
 
+  end:
        if (b_data(&h2s->rxbuf))
                cs->flags |= (CS_FL_RCV_MORE | CS_FL_WANT_ROOM);
        else {
@@ -5134,7 +5135,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
                h2c->flags &= ~H2_CF_DEM_SFULL;
                h2c_restart_reading(h2c);
        }
-end:
+
        return ret;
 }