]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: snapshot: split the error snapshots into common and proto-specific parts
authorWilly Tarreau <w@1wt.eu>
Thu, 6 Sep 2018 17:41:22 +0000 (19:41 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 7 Sep 2018 14:13:45 +0000 (16:13 +0200)
The idea will be to make the error snapshot feature accessible to other
protocols than just HTTP. This patch only introduces an "http_snapshot"
structure and renames a few fields to make things more explicit. The
HTTP part was installed inside a union so that we can easily add more
protocols in the future.

include/types/proxy.h
src/proto_http.c

index 37a50609ca8dfc72bba00b27486e912877383cb1..13cc2a4e844c31057147d0b7061b70b0af1f21e1 100644 (file)
@@ -205,26 +205,43 @@ enum PR_SRV_STATE_FILE {
 
 struct stream;
 
-struct error_snapshot {
-       struct timeval when;            /* date of this event, (tv_sec == 0) means "never" */
-       unsigned int len;               /* original length of the last invalid request/response */
-       unsigned int pos;               /* position of the first invalid character */
+struct http_snapshot {
        unsigned int sid;               /* ID of the faulty stream */
-       unsigned int ev_id;             /* event number (counter incremented for each capture) */
        unsigned int state;             /* message state before the error (when saved) */
        unsigned int b_flags;           /* buffer flags */
        unsigned int s_flags;           /* stream flags */
+
        unsigned int t_flags;           /* transaction flags */
        unsigned int m_flags;           /* message flags */
-       unsigned int b_out;             /* pending output bytes */
-       unsigned int b_wrap;            /* position where the buffer is expected to wrap */
-       unsigned long long b_tot;       /* total bytes transferred via this buffer */
        unsigned long long m_clen;      /* chunk len for this message */
        unsigned long long m_blen;      /* body len for this message */
-       struct server *srv;             /* server associated with the error (or NULL) */
-       struct proxy *oe;               /* other end = frontend or backend involved */
-       struct sockaddr_storage src;    /* client's address */
-       char *buf;                      /* copy of the beginning of the message (may be NULL) */
+};
+
+union error_snapshot_ctx {
+       struct http_snapshot http;
+};
+
+struct error_snapshot {
+       /**** common part ****/
+       struct timeval when;            /* date of this event, (tv_sec == 0) means "never" */
+       /* @16 */
+       char *buf;                      /* copy of the beginning of the message (may be NULL) */
+       unsigned long long buf_ofs;     /* relative position of the buffer's input inside its container */
+       /* @32 */
+       unsigned int buf_out;           /* pending output bytes _before_ the buffer's input (0..buf->data-1) */
+       unsigned int buf_len;           /* original length of the last invalid request/response (0..buf->data-1-buf_out) */
+       unsigned int buf_err;           /* buffer-relative position where the error was detected (0..len-1) */
+       unsigned int buf_wrap;          /* buffer-relative position where the buffer is expected to wrap (1..buf_size) */
+       /* @48 */
+       struct proxy *oe;               /* other end = frontend or backend involved */
+       struct server *srv;             /* server associated with the error (or NULL) */
+       /* @64 */
+       unsigned int ev_id;             /* event number (counter incremented for each capture) */
+       /* @68: 4 bytes hole here */
+       struct sockaddr_storage src;    /* client's address */
+
+       /**** protocol-specific part ****/
+       union error_snapshot_ctx ctx;
 };
 
 struct email_alert {
index b6d429ba16e5d1816440e30af7c3dfaf83a0a5b3..2555c66994a6646a541d1bd45071e2e45e163f96 100644 (file)
@@ -8024,10 +8024,10 @@ void http_capture_bad_message(struct proxy *proxy, struct error_snapshot *es, st
        int len1, len2;
 
        HA_SPIN_LOCK(PROXY_LOCK, &proxy->lock);
-       es->len = MIN(ci_data(chn), global.tune.bufsize);
+       es->buf_len = MIN(ci_data(chn), global.tune.bufsize);
        len1 = b_wrap(&chn->buf) - ci_head(chn);
-       len1 = MIN(len1, es->len);
-       len2 = es->len - len1; /* remaining data if buffer wraps */
+       len1 = MIN(len1, es->buf_len);
+       len2 = es->buf_len - len1; /* remaining data if buffer wraps */
 
        if (!es->buf)
                es->buf = malloc(global.tune.bufsize);
@@ -8039,12 +8039,11 @@ void http_capture_bad_message(struct proxy *proxy, struct error_snapshot *es, st
        }
 
        if (msg->err_pos >= 0)
-               es->pos = msg->err_pos;
+               es->buf_err = msg->err_pos;
        else
-               es->pos = msg->next;
+               es->buf_err = msg->next;
 
        es->when = date; // user-visible date
-       es->sid  = s->uniq_id;
        es->srv  = objt_server(s->target);
        es->oe   = other_end;
        if (objt_conn(sess->origin))
@@ -8052,17 +8051,20 @@ void http_capture_bad_message(struct proxy *proxy, struct error_snapshot *es, st
        else
                memset(&es->src, 0, sizeof(es->src));
 
-       es->state = state;
        es->ev_id = HA_ATOMIC_XADD(&error_snapshot_id, 1);
-       es->b_flags = chn->flags;
-       es->s_flags = s->flags;
-       es->t_flags = s->txn->flags;
-       es->m_flags = msg->flags;
-       es->b_out = co_data(chn);
-       es->b_wrap = b_wrap(&chn->buf) - ci_head(chn);
-       es->b_tot = chn->total;
-       es->m_clen = msg->chunk_len;
-       es->m_blen = msg->body_len;
+       es->buf_wrap = b_wrap(&chn->buf) - ci_head(chn);
+       es->buf_out  = co_data(chn);
+       es->buf_ofs  = chn->total;
+
+       /* http-specific part now */
+       es->ctx.http.sid  = s->uniq_id;
+       es->ctx.http.state = state;
+       es->ctx.http.b_flags = chn->flags;
+       es->ctx.http.s_flags = s->flags;
+       es->ctx.http.t_flags = s->txn->flags;
+       es->ctx.http.m_flags = msg->flags;
+       es->ctx.http.m_clen = msg->chunk_len;
+       es->ctx.http.m_blen = msg->body_len;
        HA_SPIN_UNLOCK(PROXY_LOCK, &proxy->lock);
 }
 
@@ -12772,11 +12774,12 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                                     "  pending %d bytes, wrapping at %d, error at position %d:\n \n",
                                     es->srv ? es->srv->id : "<NONE>", es->srv ? es->srv->puid : -1,
                                     es->ev_id,
-                                    pn, port, es->sid, es->s_flags,
-                                    h1_msg_state_str(es->state), es->state, es->m_flags, es->t_flags,
-                                    es->m_clen, es->m_blen,
-                                    es->b_flags, es->b_out, es->b_tot,
-                                    es->len, es->b_wrap, es->pos);
+                                    pn, port, es->ctx.http.sid, es->ctx.http.s_flags,
+                                    h1_msg_state_str(es->ctx.http.state), es->ctx.http.state,
+                                    es->ctx.http.m_flags, es->ctx.http.t_flags,
+                                    es->ctx.http.m_clen, es->ctx.http.m_blen,
+                                    es->ctx.http.b_flags, es->buf_out, es->buf_ofs,
+                                    es->buf_len, es->buf_wrap, es->buf_err);
 
                        if (ci_putchk(si_ic(si), &trash) == -1) {
                                /* Socket buffer full. Let's try again later from the same point */
@@ -12799,12 +12802,12 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                }
 
                /* OK, ptr >= 0, so we have to dump the current line */
-               while (es->buf && appctx->ctx.errors.ptr < es->len && appctx->ctx.errors.ptr < global.tune.bufsize) {
+               while (es->buf && appctx->ctx.errors.ptr < es->buf_len && appctx->ctx.errors.ptr < global.tune.bufsize) {
                        int newptr;
                        int newline;
 
                        newline = appctx->ctx.errors.bol;
-                       newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->len, &newline, appctx->ctx.errors.ptr);
+                       newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, appctx->ctx.errors.ptr);
                        if (newptr == appctx->ctx.errors.ptr)
                                return 0;