From fcd99f8eecc28af8aa451ea879627264166f8d23 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 31 Oct 2016 11:27:21 +0100 Subject: [PATCH] MINOR: flt_trace: Add hexdump option to dump forwarded data This is pretty verbose, but it can be handy to have it in HAProxy. --- src/flt_trace.c | 69 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/src/flt_trace.c b/src/flt_trace.c index ce3bf5ccc7..76081b2d56 100644 --- a/src/flt_trace.c +++ b/src/flt_trace.c @@ -10,6 +10,8 @@ * */ +#include + #include #include #include @@ -32,6 +34,7 @@ struct trace_config { char *name; int rand_parsing; int rand_forwarding; + int hexdump; }; #define TRACE(conf, fmt, ...) \ @@ -39,10 +42,11 @@ struct trace_config { (int)now.tv_sec, (int)now.tv_usec, (conf)->name, \ ##__VA_ARGS__) -#define STRM_TRACE(conf, strm, fmt, ...) \ - fprintf(stderr, "%d.%06d [%-20s] [strm %p(%x)] " fmt "\n", \ - (int)now.tv_sec, (int)now.tv_usec, (conf)->name, \ - strm, (strm ? ((struct stream *)strm)->uniq_id : ~0U), \ +#define STRM_TRACE(conf, strm, fmt, ...) \ + fprintf(stderr, "%d.%06d [%-20s] [strm %p(%x) 0x%08x 0x%08x] " fmt "\n", \ + (int)now.tv_sec, (int)now.tv_usec, (conf)->name, \ + strm, (strm ? ((struct stream *)strm)->uniq_id : ~0U), \ + (strm ? strm->req.analysers : 0), (strm ? strm->res.analysers : 0), \ ##__VA_ARGS__) @@ -72,6 +76,42 @@ filter_type(const struct filter *f) return (f->flags & FLT_FL_IS_BACKEND_FILTER) ? "backend" : "frontend"; } +static void +trace_hexdump(struct buffer *buf, int len) +{ + unsigned char p[len]; + int block1, block2, i, j, padding; + + block1 = len; + if (block1 > bi_contig_data(buf)) + block1 = bi_contig_data(buf); + block2 = len - block1; + + memcpy(p, buf->p, block1); + memcpy(p+block1, buf->data, block2); + + padding = ((len % 16) ? (16 - len % 16) : 0); + for (i = 0; i < len + padding; i++) { + if (!(i % 16)) + fprintf(stderr, "\t0x%06x: ", i); + else if (!(i % 8)) + fprintf(stderr, " "); + + if (i < len) + fprintf(stderr, "%02x ", p[i]); + else + fprintf(stderr, " "); + + /* print ASCII dump */ + if (i % 16 == 15) { + fprintf(stderr, " |"); + for(j = i - 15; j <= i && j < len; j++) + fprintf(stderr, "%c", (isprint(p[j]) ? p[j] : '.')); + fprintf(stderr, "|\n"); + } + } +} + /*************************************************************************** * Hooks that manage the filter lifecycle (init/check/deinit) **************************************************************************/ @@ -86,9 +126,10 @@ trace_init(struct proxy *px, struct flt_conf *fconf) else memprintf(&conf->name, "TRACE/%s", px->id); fconf->conf = conf; - TRACE(conf, "filter initialized [read random=%s - fwd random=%s]", + TRACE(conf, "filter initialized [read random=%s - fwd random=%s - hexdump=%s]", (conf->rand_parsing ? "true" : "false"), - (conf->rand_forwarding ? "true" : "false")); + (conf->rand_forwarding ? "true" : "false"), + (conf->hexdump ? "true" : "false")); return 0; } @@ -188,6 +229,7 @@ trace_chn_start_analyze(struct stream *s, struct filter *filter, channel_label(chn), proxy_mode(s), stream_pos(s)); filter->pre_analyzers |= (AN_REQ_ALL | AN_RES_ALL); filter->post_analyzers |= (AN_REQ_ALL | AN_RES_ALL); + register_data_filter(s, chn, filter); return 1; } @@ -305,7 +347,6 @@ trace_http_headers(struct stream *s, struct filter *filter, cur_hdr += hdr_idx->v[cur_idx].len + hdr_idx->v[cur_idx].cr + 1; cur_idx = hdr_idx->v[cur_idx].next; } - register_data_filter(s, msg->chn, filter); return 1; } @@ -392,6 +433,12 @@ trace_http_forward_data(struct stream *s, struct filter *filter, channel_label(msg->chn), proxy_mode(s), stream_pos(s), len, FLT_NXT(filter, msg->chn), FLT_FWD(filter, msg->chn), ret); + if (conf->hexdump) { + b_adv(msg->chn->buf, FLT_FWD(filter, msg->chn)); + trace_hexdump(msg->chn->buf, ret); + b_rew(msg->chn->buf, FLT_FWD(filter, msg->chn)); + } + if ((ret != len) || (FLT_NXT(filter, msg->chn) != FLT_FWD(filter, msg->chn) + ret)) task_wakeup(s->task, TASK_WOKEN_MSG); @@ -436,6 +483,12 @@ trace_tcp_forward_data(struct stream *s, struct filter *filter, struct channel * channel_label(chn), proxy_mode(s), stream_pos(s), len, FLT_FWD(filter, chn), ret); + if (conf->hexdump) { + b_adv(chn->buf, FLT_FWD(filter, chn)); + trace_hexdump(chn->buf, ret); + b_rew(chn->buf, FLT_FWD(filter, chn)); + } + if (ret != len) task_wakeup(s->task, TASK_WOKEN_MSG); return ret; @@ -514,6 +567,8 @@ parse_trace_flt(char **args, int *cur_arg, struct proxy *px, conf->rand_parsing = 1; else if (!strcmp(args[pos], "random-forwarding")) conf->rand_forwarding = 1; + else if (!strcmp(args[pos], "hexdump")) + conf->hexdump = 1; else break; pos++;