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;