]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h2: report asynchronous errors in h2_wake_some_streams()
authorWilly Tarreau <w@1wt.eu>
Tue, 18 Dec 2018 15:44:28 +0000 (16:44 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 18 Dec 2018 15:46:24 +0000 (16:46 +0100)
This function is called when dealing with a connection error or a GOAWAY
frame. It used to report a synchronous error instead of an asycnhronous
error, which can lead to data truncation since whatever is still available
in the rxbuf will be ignored. Let's correctly use CS_FL_ERR_PENDING instead
and only fall back to CS_FL_ERROR if CS_FL_EOS was already delivered.

No backport is needed.

src/mux_h2.c

index 4c494d565abb29e472f7b3976de86cfc97c69bec..a76ca0f3fd3bc932fedc069b55b6016829255311 100644 (file)
@@ -1241,7 +1241,7 @@ static void h2_wake_some_streams(struct h2c *h2c, int last, uint32_t flags)
        struct h2s *h2s;
 
        if (h2c->st0 >= H2_CS_ERROR || h2c->conn->flags & CO_FL_ERROR)
-               flags |= CS_FL_ERROR;
+               flags |= CS_FL_ERR_PENDING;
 
        if (conn_xprt_read0_pending(h2c->conn))
                flags |= CS_FL_REOS;
@@ -1260,6 +1260,9 @@ static void h2_wake_some_streams(struct h2c *h2c, int last, uint32_t flags)
                }
 
                h2s->cs->flags |= flags;
+               if ((flags & CS_FL_ERR_PENDING) && (h2s->cs->flags & CS_FL_EOS))
+                       h2s->cs->flags |= CS_FL_ERROR;
+
                if (h2s->recv_wait) {
                        struct wait_event *sw = h2s->recv_wait;
                        sw->wait_reason &= ~SUB_CAN_RECV;
@@ -1268,7 +1271,7 @@ static void h2_wake_some_streams(struct h2c *h2c, int last, uint32_t flags)
                } else if (h2s->cs->data_cb->wake != NULL)
                        h2s->cs->data_cb->wake(h2s->cs);
 
-               if (flags & CS_FL_ERROR && h2s->st < H2_SS_ERROR)
+               if (flags & CS_FL_ERR_PENDING && h2s->st < H2_SS_ERROR)
                        h2s->st = H2_SS_ERROR;
                else if (flags & CS_FL_REOS && h2s->st == H2_SS_OPEN)
                        h2s->st = H2_SS_HREM;