From 7d013e796cef9113cc69f151fa40fd05cc637f09 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 15 Dec 2020 16:56:50 +0100 Subject: [PATCH] BUG/MEDIUM: mux-h2: Xfer rxbuf to the upper layer when creating a front stream Just like the H1 muliplexer, when a new frontend H2 stream is created, the rxbuf is xferred to the stream at the upper layer. Originally, it is not a bug fix, but just an api standardization. And in fact, it fixes a crash when a h2 stream is aborted after the request parsing but before the first call to process_stream(). It crashes since the commit 8bebd2fe5 ("MEDIUM: http-ana: Don't process partial or empty request anymore"). It is now totally unexpected to have an HTTP stream without a valid request. But here the stream is unable to get the request because the client connection was aborted. Passing it during the stream creation fixes the bug. But the true problem is that the stream-interfaces are still relying on the connection state while only the muxes should do so. This fix is specific for 2.4. No backport needed. --- src/mux_h2.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index fd03ea8c46..5d14755970 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -1458,9 +1458,12 @@ static struct h2s *h2s_new(struct h2c *h2c, int id) } /* creates a new stream on the h2c connection and returns it, or NULL in - * case of memory allocation error. + * case of memory allocation error. is used as input buffer for the new + * stream. On success, it is transferred to the stream and the mux is no longer + * responsible of it. On error, is unchanged, thus the mux must still + * take care of it. */ -static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id) +static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id, struct buffer *input) { struct session *sess = h2c->conn->owner; struct conn_stream *cs; @@ -1484,7 +1487,7 @@ static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id) cs->ctx = h2s; h2c->nb_cs++; - if (stream_create_from_cs(cs, &BUF_NULL) < 0) + if (stream_create_from_cs(cs, input) < 0) goto out_free_cs; /* We want the accept date presented to the next stream to be the one @@ -2663,15 +2666,17 @@ static struct h2s *h2c_frt_handle_headers(struct h2c *h2c, struct h2s *h2s) /* Note: we don't emit any other logs below because ff we return * positively from h2c_frt_stream_new(), the stream will report the error, * and if we return in error, h2c_frt_stream_new() will emit the error. + * + * Xfer the rxbuf to the stream. On success, the new stream owns the + * rxbuf. On error, it is released here. */ - h2s = h2c_frt_stream_new(h2c, h2c->dsi); + h2s = h2c_frt_stream_new(h2c, h2c->dsi, &rxbuf); if (!h2s) { h2s = (struct h2s*)h2_refused_stream; goto send_rst; } h2s->st = H2_SS_OPEN; - h2s->rxbuf = rxbuf; h2s->flags |= flags; h2s->body_len = body_len; -- 2.39.5