From: Willy Tarreau Date: Thu, 31 Mar 2016 11:45:10 +0000 (+0200) Subject: MEDIUM: proxy: use dynamic allocation for error dumps X-Git-Tag: v1.7-dev3~57 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f3764b79938e175c1f6507f01b56ec33b425f754;p=thirdparty%2Fhaproxy.git MEDIUM: proxy: use dynamic allocation for error dumps There are two issues with error captures. The first one is that the capture size is still hard-coded to BUFSIZE regardless of any possible tune.bufsize setting and of the fact that frontends only capture request errors and that backends only capture response errors. The second is that captures are allocated in both directions for all proxies, which start to count a lot in configs using thousands of proxies. This patch changes this so that error captures are allocated only when needed, and of the proper size. It also refrains from dumping a buffer that was not allocated, which still allows to emit all relevant info such as flags and HTTP states. This way it is possible to save up to 32 kB of RAM per proxy in the default configuration. --- diff --git a/include/types/proxy.h b/include/types/proxy.h index 79a34117f8..e23b4e4bfa 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -221,7 +221,7 @@ struct error_snapshot { 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[BUFSIZE]; /* copy of the beginning of the message */ + char *buf; /* copy of the beginning of the message (may be NULL) */ }; struct email_alert { diff --git a/src/dumpstats.c b/src/dumpstats.c index 447e6f0cc3..341fd56e91 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -7032,12 +7032,12 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si) } /* OK, ptr >= 0, so we have to dump the current line */ - while (appctx->ctx.errors.ptr < es->len && appctx->ctx.errors.ptr < sizeof(es->buf)) { + while (es->buf && appctx->ctx.errors.ptr < es->len && appctx->ctx.errors.ptr < global.tune.bufsize) { int newptr; int newline; newline = appctx->ctx.errors.bol; - newptr = dump_text_line(&trash, es->buf, sizeof(es->buf), es->len, &newline, appctx->ctx.errors.ptr); + newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->len, &newline, appctx->ctx.errors.ptr); if (newptr == appctx->ctx.errors.ptr) return 0; diff --git a/src/proto_http.c b/src/proto_http.c index ddf05448cc..0b2001198d 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -8382,14 +8382,19 @@ void http_capture_bad_message(struct error_snapshot *es, struct stream *s, struct channel *chn = msg->chn; int len1, len2; - es->len = MIN(chn->buf->i, sizeof(es->buf)); + es->len = MIN(chn->buf->i, global.tune.bufsize); len1 = chn->buf->data + chn->buf->size - chn->buf->p; len1 = MIN(len1, es->len); len2 = es->len - len1; /* remaining data if buffer wraps */ - memcpy(es->buf, chn->buf->p, len1); - if (len2) - memcpy(es->buf + len1, chn->buf->data, len2); + if (!es->buf) + es->buf = malloc(global.tune.bufsize); + + if (es->buf) { + memcpy(es->buf, chn->buf->p, len1); + if (len2) + memcpy(es->buf + len1, chn->buf->data, len2); + } if (msg->err_pos >= 0) es->pos = msg->err_pos;