]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
DEBUG: mux-h1: Add debug counters to track some errors
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 22 Oct 2024 15:39:29 +0000 (17:39 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 22 Oct 2024 15:39:32 +0000 (17:39 +0200)
Debug counters are added to track errors about wrong the payload length
during the message formatting (on the sending path). Aborts are also
concerned. connection shutdowns and errors while the end of the message was
not reached are now tracked. On the sending path, shutdown performed while
all the message was not forwarded are tracked too.

src/mux_h1.c

index c2f17825590d52fe9d8c14ad802463b61958da28..54acad8e2c5f479a1cc6908372b2321a3679ae18 100644 (file)
@@ -2285,6 +2285,7 @@ static size_t h1_process_demux(struct h1c *h1c, struct buffer *buf, size_t count
                                if (h1m->state <= H1_MSG_LAST_LF && b_data(&h1c->ibuf))
                                        htx->flags |= HTX_FL_PARSING_ERROR;
                                se_fl_set(h1s->sd, SE_FL_ERROR);
+                               COUNT_IF(1, "H1C EOS before the end of the message");
                                TRACE_ERROR("message aborted, set error on SC", H1_EV_RX_DATA|H1_EV_H1S_ERR, h1c->conn, h1s);
                        }
 
@@ -2297,6 +2298,7 @@ static size_t h1_process_demux(struct h1c *h1c, struct buffer *buf, size_t count
                if (h1c->flags & H1C_F_ERROR) {
                        /* Report a terminal error to the SE if a previous read error was detected */
                        se_fl_set(h1s->sd, SE_FL_ERROR);
+                       COUNT_IF(h1m->state < H1_MSG_DONE, "H1C ERROR before the end of the message");
                        TRACE_STATE("report ERROR to SE", H1_EV_RX_DATA|H1_EV_H1S_ERR, h1c->conn, h1s);
                }
        }
@@ -2913,6 +2915,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
 
                if (h1m->flags & H1_MF_CLEN) {
                        if (count > h1m->curr_len) {
+                               COUNT_IF(1, "more payload than announced (0-copy)");
                                TRACE_ERROR("more payload than announced",
                                            H1_EV_TX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                                goto error;
@@ -2936,6 +2939,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
                        /* If is a new chunk, prepend the chunk size */
                        if (h1m->state == H1_MSG_CHUNK_CRLF || h1m->state == H1_MSG_CHUNK_SIZE) {
                                if (h1m->curr_len) {
+                                       COUNT_IF(1, "chunk bigger than announced (0-copy)");
                                        TRACE_ERROR("chunk bigger than announced",
                                                    H1_EV_TX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                                        goto error;
@@ -2963,6 +2967,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
                        /* It is the end of the message, add the last chunk with the extra CRLF */
                        if (eom) {
                                if (h1m->curr_len) {
+                                       COUNT_IF(1, "chunk smaller than announced (0-copy)");
                                        TRACE_ERROR("chunk smaller than announced",
                                                    H1_EV_TX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                                        goto error;
@@ -2987,6 +2992,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
        /* Handle now case of CRLF at the end of a chun. */
        if ((h1m->flags & H1_MF_CHNK) && h1m->state == H1_MSG_CHUNK_CRLF) {
                if (h1m->curr_len) {
+                       COUNT_IF(1, "chunk bigger than announced");
                        TRACE_ERROR("chunk bigger than announced",
                                    H1_EV_TX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                        goto error;
@@ -3060,6 +3066,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
 
                        if (h1m->flags & H1_MF_CLEN) {
                                if (vlen > h1m->curr_len) {
+                                       COUNT_IF(1, "more payload than announced");
                                        TRACE_ERROR("more payload than announced",
                                                    H1_EV_TX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                                        goto error;
@@ -3076,6 +3083,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
                                }
                                if (last_data) {
                                        if (h1m->curr_len) {
+                                               COUNT_IF(1, "chunk smaller than announced");
                                                TRACE_ERROR("chunk smaller than announced",
                                                            H1_EV_TX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                                                goto error;
@@ -3472,6 +3480,7 @@ static size_t h1_process_mux(struct h1c *h1c, struct buffer *buf, size_t count)
                                htx->flags |= HTX_FL_PROCESSING_ERROR;
                                h1s->flags |= H1S_F_PROCESSING_ERROR;
                                se_fl_set(h1s->sd, SE_FL_ERROR);
+                               COUNT_IF(1, "processing error during message formatting");
                                TRACE_ERROR("processing error", H1_EV_TX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                                break;
                }
@@ -4411,6 +4420,7 @@ static void h1_detach(struct sedesc *sd)
 
        if (h1c->state == H1_CS_RUNNING && !(h1c->flags & H1C_F_IS_BACK) && h1s->req.state != H1_MSG_DONE) {
                h1c->state = H1_CS_DRAINING;
+               COUNT_IF(1, "Deferring H1S destroy to drain message");
                TRACE_DEVEL("Deferring H1S destroy to drain message", H1_EV_STRM_END, h1s->h1c->conn, h1s);
                /* If we have a pending data, process it immediately or
                 * subscribe for reads waiting for new data
@@ -4446,6 +4456,9 @@ static void h1_shut(struct stconn *sc, unsigned int mode, struct se_abort_info *
                goto end;
 
   do_shutw:
+       COUNT_IF((h1c->flags & H1C_F_IS_BACK) && (h1s->res.state < H1_MSG_DONE), "Abort sending of the response");
+       COUNT_IF(!(h1c->flags & H1C_F_IS_BACK) && (h1s->req.state < H1_MSG_DONE), "Abort sending of the request");
+
        h1_close(h1c);
        if (!(mode & SE_SHW_NORMAL))
                h1c->flags |= H1C_F_SILENT_SHUT;
@@ -5009,6 +5022,7 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
                if (total > h1m->curr_len) {
                        h1s->flags |= H1S_F_PARSING_ERROR;
                        se_fl_set(h1s->sd, SE_FL_ERROR);
+                       COUNT_IF(1, "more payload than announced");
                        TRACE_ERROR("too much payload, more than announced",
                                    H1_EV_STRM_RECV|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
                        goto end;
@@ -5046,6 +5060,7 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
                else {
                        se_fl_set(h1s->sd, SE_FL_ERROR);
                        h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_ERROR;
+                       COUNT_IF(1, "H1C EOS before the end of the message");
                        TRACE_ERROR("message aborted, set error on SC", H1_EV_STRM_RECV|H1_EV_H1S_ERR, h1c->conn, h1s);
                }
                h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_EOS;
@@ -5054,6 +5069,7 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
        if (h1c->conn->flags & CO_FL_ERROR) {
                se_fl_set(h1s->sd, SE_FL_ERROR);
                h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_ERROR;
+               COUNT_IF(h1m->state < H1_MSG_DONE, "H1C ERROR before the end of the message");
                TRACE_DEVEL("connection error", H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
        }