]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-h1: Don't report a final error whe a message is aborted
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 10 Oct 2022 14:36:10 +0000 (16:36 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 17 Nov 2022 13:33:15 +0000 (14:33 +0100)
When the H1 connection is aborted, we no longer set a final error. To do so,
the flag H1C_F_ABORTED was added. For now, it is only set when a error is
detected on the H1 stream. Idea is to use ERR_PENDING/ERROR for upgoing
errors and ABRT_PENDING/ABRTED for downgoing errors.

include/haproxy/mux_h1-t.h
src/mux_h1.c

index 450707e5b3f204f8bfb374a272e085528067fcfe..23b5822186cc80da12610e0480204aabe099ea06 100644 (file)
 #define H1C_F_ERROR          0x00000400 /* A read error was detected (handled has an abort) */
 #define H1C_F_SILENT_SHUT    0x00000800 /* if H1C is closed closed, silent (or dirty) shutdown must be performed */
 #define H1C_F_ABRT_PENDING   0x00001000 /* An error must be sent (previous attempt failed) and H1 connection must be closed ASAP */
-#define H1C_F_WANT_SPLICE    0x00002000 /* Don't read into a buffer because we want to use or we are using splicing */
-#define H1C_F_WAIT_NEXT_REQ  0x00004000 /*  waiting for the next request to start, use keep-alive timeout */
-#define H1C_F_UPG_H2C        0x00008000 /* set if an upgrade to h2 should be done */
-#define H1C_F_CO_MSG_MORE    0x00010000 /* set if CO_SFL_MSG_MORE must be set when calling xprt->snd_buf() */
-#define H1C_F_CO_STREAMER    0x00020000 /* set if CO_SFL_STREAMER must be set when calling xprt->snd_buf() */
+#define H1C_F_ABRTED         0x00002000 /* An error must be sent (previous attempt failed) and H1 connection must be closed ASAP */
+#define H1C_F_WANT_SPLICE    0x00004000 /* Don't read into a buffer because we want to use or we are using splicing */
+#define H1C_F_WAIT_NEXT_REQ  0x00008000 /*  waiting for the next request to start, use keep-alive timeout */
+#define H1C_F_UPG_H2C        0x00010000 /* set if an upgrade to h2 should be done */
+#define H1C_F_CO_MSG_MORE    0x00020000 /* set if CO_SFL_MSG_MORE must be set when calling xprt->snd_buf() */
+#define H1C_F_CO_STREAMER    0x00040000 /* set if CO_SFL_STREAMER must be set when calling xprt->snd_buf() */
 
 /* 0x00040000 - 0x40000000 unusued*/
 #define H1C_F_IS_BACK        0x80000000 /* Set on outgoing connection */
@@ -67,9 +68,9 @@ static forceinline char *h1c_show_flags(char *buf, size_t len, const char *delim
        _(H1C_F_OUT_ALLOC, _(H1C_F_OUT_FULL,
        _(H1C_F_IN_ALLOC, _(H1C_F_IN_FULL, _(H1C_F_IN_SALLOC,
        _(H1C_F_EOS, _(H1C_F_ERR_PENDING, _(H1C_F_ERROR,
-       _(H1C_F_SILENT_SHUT, _(H1C_F_ABRT_PENDING, _(H1C_F_WANT_SPLICE,
-       _(H1C_F_WAIT_NEXT_REQ, _(H1C_F_UPG_H2C, _(H1C_F_CO_MSG_MORE,
-       _(H1C_F_CO_STREAMER, _(H1C_F_IS_BACK))))))))))))))));
+       _(H1C_F_SILENT_SHUT, _(H1C_F_ABRT_PENDING, _(H1C_F_ABRTED,
+       _(H1C_F_WANT_SPLICE, _(H1C_F_WAIT_NEXT_REQ, _(H1C_F_UPG_H2C, _(H1C_F_CO_MSG_MORE,
+       _(H1C_F_CO_STREAMER, _(H1C_F_IS_BACK)))))))))))))))));
        /* epilogue */
        _(~0U);
        return buf;
index 5f3f121e28c785da5fbe1b4602f120432d4bbd66..d600c78f8cf087fb8e1a4721470ab90f0db8ce12 100644 (file)
@@ -852,12 +852,8 @@ static void h1s_destroy(struct h1s *h1s)
                h1c->flags &= ~(H1C_F_WANT_SPLICE|
                                H1C_F_OUT_FULL|H1C_F_OUT_ALLOC|H1C_F_IN_SALLOC|
                                H1C_F_CO_MSG_MORE|H1C_F_CO_STREAMER);
-               if (h1s->flags & H1S_F_ERROR_MASK) {
-                       h1c->flags |= H1C_F_ERROR;
-                       TRACE_ERROR("h1s on error, set error on h1c", H1_EV_H1S_END|H1_EV_H1C_ERR, h1c->conn, h1s);
-               }
 
-               if (!(h1c->flags & (H1C_F_EOS|H1C_F_ERR_PENDING|H1C_F_ERROR)) &&             /* No error/read0 */
+               if (!(h1c->flags & (H1C_F_EOS|H1C_F_ERR_PENDING|H1C_F_ERROR|H1C_F_ABRT_PENDING|H1C_F_ABRTED)) &&  /* No error/read0/abort */
                    h1_is_alive(h1c) &&                                                      /* still alive */
                    (h1s->flags & H1S_F_WANT_KAL) &&                                         /* K/A possible */
                    h1s->req.state == H1_MSG_DONE && h1s->res.state == H1_MSG_DONE) {        /* req/res in DONE state */
@@ -2638,7 +2634,7 @@ static int h1_send_error(struct h1c *h1c)
                h1s_destroy(h1c->h1s);
        }
 
-       h1c->flags &= ~H1C_F_ABRT_PENDING;
+       h1c->flags = (h1c->flags & ~H1C_F_ABRT_PENDING) | H1C_F_ABRTED;
        h1c->state = H1_CS_CLOSING;
   out:
        TRACE_LEAVE(H1_EV_H1C_ERR, h1c->conn);
@@ -2678,6 +2674,7 @@ static int h1_handle_parsing_error(struct h1c *h1c)
 
        if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) {
                h1c->state = H1_CS_CLOSING;
+               h1c->flags |= H1C_F_ABRTED;
                goto end;
        }
 
@@ -2710,6 +2707,7 @@ static int h1_handle_not_impl_err(struct h1c *h1c)
 
        if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) {
                h1c->state = H1_CS_CLOSING;
+               h1c->flags |= H1C_F_ABRTED;
                goto end;
        }
 
@@ -2739,6 +2737,7 @@ static int h1_handle_req_tout(struct h1c *h1c)
 
        if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) {
                h1c->state = H1_CS_CLOSING;
+               h1c->flags |= H1C_F_ABRTED;
                goto end;
        }
 
@@ -3011,7 +3010,7 @@ static int h1_process(struct h1c * h1c)
         *  - a read0 was received or
         *  - a silent shutdown was emitted and all outgoing data sent
         */
-       if ((h1c->flags & (H1C_F_EOS|H1C_F_ERROR|H1C_F_ABRT_PENDING)) ||
+       if ((h1c->flags & (H1C_F_EOS|H1C_F_ERROR|H1C_F_ABRT_PENDING|H1C_F_ABRTED)) ||
            (h1c->state >= H1_CS_CLOSING && (h1c->flags & H1C_F_SILENT_SHUT) && !b_data(&h1c->obuf))) {
                if (h1c->state != H1_CS_RUNNING) {
                        /* No stream connector or upgrading */