]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: mux-h2: make sure to honor KILL_CONN in do_shut{r,w}
authorWilly Tarreau <w@1wt.eu>
Tue, 14 May 2019 08:44:40 +0000 (10:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 14 May 2019 13:47:57 +0000 (15:47 +0200)
If the stream closes and quits while there's no room in the mux buffer
to send an RST frame, next time it is attempted it will not lead to
the connection being closed because the conn_stream will have been
released and the KILL_CONN flag with it as well.

This patch reserves a new H2_SF_KILL_CONN flag that is copied from
the CS when calling shut{r,w} so that the stream remains autonomous
on this even when the conn_stream leaves.

This should ideally be backported to 1.9 though it depends on several
previous patches that may or may not be suitable for backporting. The
severity is very low so there's no need to insist in case of trouble.

src/mux_h2.c

index 8dcf27855b144af45c1dfd3f2f5f1dc3ea17caf7..bf6c53de45d5752754d78d168f21549cff5288a6 100644 (file)
@@ -180,6 +180,7 @@ enum h2_ss {
 
 #define H2_SF_WANT_SHUTR        0x00008000  // a stream couldn't shutr() (mux full/busy)
 #define H2_SF_WANT_SHUTW        0x00010000  // a stream couldn't shutw() (mux full/busy)
+#define H2_SF_KILL_CONN         0x00020000  // kill the whole connection with this stream
 
 
 /* H2 stream descriptor, describing the stream as it appears in the H2C, and as
@@ -3170,7 +3171,7 @@ static void h2_do_shutr(struct h2s *h2s)
         * normally used to limit abuse. In this case we schedule a goaway to
         * close the connection.
         */
-       if ((h2s->cs && h2s->cs->flags & CS_FL_KILL_CONN) &&
+       if ((h2s->flags & H2_SF_KILL_CONN) &&
            !(h2c->flags & (H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED))) {
                h2c_error(h2c, H2_ERR_ENHANCE_YOUR_CALM);
                h2s_error(h2s, H2_ERR_ENHANCE_YOUR_CALM);
@@ -3236,7 +3237,7 @@ static void h2_do_shutw(struct h2s *h2s)
                 * normally used to limit abuse. In this case we schedule a goaway to
                 * close the connection.
                 */
-               if ((h2s->cs && h2s->cs->flags & CS_FL_KILL_CONN) &&
+               if ((h2s->flags & H2_SF_KILL_CONN) &&
                    !(h2c->flags & (H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED))) {
                        h2c_error(h2c, H2_ERR_ENHANCE_YOUR_CALM);
                        h2s_error(h2s, H2_ERR_ENHANCE_YOUR_CALM);
@@ -3313,6 +3314,9 @@ static void h2_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
 {
        struct h2s *h2s = cs->ctx;
 
+       if (cs->flags & CS_FL_KILL_CONN)
+               h2s->flags |= H2_SF_KILL_CONN;
+
        if (!mode)
                return;
 
@@ -3324,6 +3328,9 @@ static void h2_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
 {
        struct h2s *h2s = cs->ctx;
 
+       if (cs->flags & CS_FL_KILL_CONN)
+               h2s->flags |= H2_SF_KILL_CONN;
+
        h2_do_shutw(h2s);
 }