MINOR: snapshot: split the error snapshots into common and proto-specific parts

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.
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 37a5060..13cc2a4 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -205,26 +205,43 @@
 
 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 {
diff --git a/src/proto_http.c b/src/proto_http.c
index b6d429b..2555c66 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -8024,10 +8024,10 @@
 	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 @@
 	}
 
 	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 @@
 	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 @@
 				     "  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 @@
 		}
 
 		/* 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;