diff --git a/include/common/chunk.h b/include/common/chunk.h index 191f9e75dc..18f41af54f 100644 --- a/include/common/chunk.h +++ b/include/common/chunk.h @@ -47,6 +47,8 @@ int chunk_htmlencode(struct chunk *dst, struct chunk *src); int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc); int chunk_strcmp(const struct chunk *chk, const char *str); int chunk_strcasecmp(const struct chunk *chk, const char *str); +int alloc_trash_buffers(int bufsize); +struct chunk *get_trash_chunk(void); static inline void chunk_reset(struct chunk *chk) { diff --git a/include/proto/sample.h b/include/proto/sample.h index 5241a3a7ec..77d6c18175 100644 --- a/include/proto/sample.h +++ b/include/proto/sample.h @@ -26,10 +26,6 @@ #include #include -/* only exported for late memory allocation, do not use */ -extern char *sample_trash_buf1; -extern char *sample_trash_buf2; - struct sample_expr *sample_parse_expr(char **str, int *idx, char *err, int err_size); struct sample *sample_process(struct proxy *px, struct session *l4, void *l7, unsigned int dir, struct sample_expr *expr, @@ -38,6 +34,5 @@ struct sample *sample_fetch_string(struct proxy *px, struct session *l4, void *l unsigned int opt, struct sample_expr *expr); void sample_register_fetches(struct sample_fetch_kw_list *psl); void sample_register_convs(struct sample_conv_kw_list *psl); -struct chunk *sample_get_trash_chunk(void); #endif /* _PROTO_SAMPLE_H */ diff --git a/src/chunk.c b/src/chunk.c index d027569b43..9463abb28e 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -18,6 +18,48 @@ #include #include +/* trash chunks used for various conversions */ +static struct chunk *trash_chunk; +static struct chunk trash_chunk1; +static struct chunk trash_chunk2; + +/* trash buffers used for various conversions */ +static int trash_size; +static char *trash_buf1; +static char *trash_buf2; + +/* +* Returns a pre-allocated and initialized trash chunk that can be used for any +* type of conversion. Two chunks and their respective buffers are alternatively +* returned so that it is always possible to iterate data transformations without +* losing the data being transformed. The blocks are initialized to the size of +* a standard buffer, so they should be enough for everything. +*/ +struct chunk *get_trash_chunk(void) +{ + char *trash_buf; + + if (trash_chunk == &trash_chunk1) { + trash_chunk = &trash_chunk2; + trash_buf = trash_buf2; + } + else { + trash_chunk = &trash_chunk1; + trash_buf = trash_buf1; + } + chunk_init(trash_chunk, trash_buf, trash_size); + return trash_chunk; +} + +/* Allocates the trash buffers. Returns 0 in case of failure. */ +int alloc_trash_buffers(int bufsize) +{ + trash_size = bufsize; + trash_buf1 = (char *)calloc(1, bufsize); + trash_buf2 = (char *)calloc(1, bufsize); + return trash_buf1 && trash_buf2; +} + /* * Does an snprintf() at the beginning of chunk , respecting the limit of * at most chk->size chars. If the chk->len is over, nothing is added. Returns diff --git a/src/haproxy.c b/src/haproxy.c index b62d261ff7..0d826d23ff 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -759,11 +759,9 @@ void init(int argc, char **argv) global.nbproc = 1; swap_buffer = (char *)calloc(1, global.tune.bufsize); - sample_trash_buf1 = (char *)calloc(1, global.tune.bufsize); - sample_trash_buf2 = (char *)calloc(1, global.tune.bufsize); get_http_auth_buff = (char *)calloc(1, global.tune.bufsize); static_table_key = calloc(1, sizeof(*static_table_key) + global.tune.bufsize); - + alloc_trash_buffers(global.tune.bufsize); fdinfo = (struct fdinfo *)calloc(1, sizeof(struct fdinfo) * (global.maxsock)); diff --git a/src/proto_http.c b/src/proto_http.c index f664b8ee38..60b630dc3a 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -8481,7 +8481,7 @@ smp_fetch_hdr_ip(struct proxy *px, struct session *l4, void *l7, unsigned int op smp->type = SMP_T_IPV4; break; } else { - struct chunk *temp = sample_get_trash_chunk(); + struct chunk *temp = get_trash_chunk(); if (smp->data.str.len < temp->size - 1) { memcpy(temp->str, smp->data.str.str, smp->data.str.len); temp->str[smp->data.str.len] = '\0'; @@ -8632,11 +8632,12 @@ static int smp_fetch_base32_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt, const struct arg *args, struct sample *smp) { - struct chunk *temp = sample_get_trash_chunk(); + struct chunk *temp; if (!smp_fetch_base32(px, l4, l7, opt, args, smp)) return 0; + temp = get_trash_chunk(); memcpy(temp->str + temp->len, &smp->data.uint, sizeof(smp->data.uint)); temp->len += sizeof(smp->data.uint); diff --git a/src/sample.c b/src/sample.c index 3c0d01ef4a..b3898e0a82 100644 --- a/src/sample.c +++ b/src/sample.c @@ -26,13 +26,6 @@ /* static sample used in sample_process() when

is NULL */ static struct sample temp_smp; -/* trash chunk used for sample conversions */ -static struct chunk trash_chunk; - -/* trash buffers used or sample conversions */ -char *sample_trash_buf1; -char *sample_trash_buf2; - /* list head of all known sample fetch keywords */ static struct sample_fetch_kw_list sample_fetches = { .list = LIST_HEAD_INIT(sample_fetches.list) @@ -101,24 +94,6 @@ struct sample_conv *find_sample_conv(const char *kw, int len) return NULL; } - -/* -* Returns a static trash struct chunk to use in sample casts or format conversions -* Swiths the 2 available trash buffers to protect data during convert -*/ -struct chunk *sample_get_trash_chunk(void) -{ - char *sample_trash_buf; - - sample_trash_buf = sample_trash_buf1; - sample_trash_buf1 = sample_trash_buf2; - sample_trash_buf2 = sample_trash_buf1; - - chunk_init(&trash_chunk, sample_trash_buf, global.tune.bufsize); - - return &trash_chunk; -} - /******************************************************************/ /* Sample casts functions */ /* Note: these functions do *NOT* set the output type on the */ @@ -133,7 +108,7 @@ static int c_ip2int(struct sample *smp) static int c_ip2str(struct sample *smp) { - struct chunk *trash = sample_get_trash_chunk(); + struct chunk *trash = get_trash_chunk(); if (!inet_ntop(AF_INET, (void *)&smp->data.ipv4, trash->str, trash->size)) return 0; @@ -152,7 +127,7 @@ static int c_ip2ipv6(struct sample *smp) static int c_ipv62str(struct sample *smp) { - struct chunk *trash = sample_get_trash_chunk(); + struct chunk *trash = get_trash_chunk(); if (!inet_ntop(AF_INET6, (void *)&smp->data.ipv6, trash->str, trash->size)) return 0; @@ -189,7 +164,7 @@ static int c_str2ipv6(struct sample *smp) static int c_bin2str(struct sample *smp) { - struct chunk *trash = sample_get_trash_chunk(); + struct chunk *trash = get_trash_chunk(); unsigned char c; int ptr = 0; @@ -205,7 +180,7 @@ static int c_bin2str(struct sample *smp) static int c_int2str(struct sample *smp) { - struct chunk *trash = sample_get_trash_chunk(); + struct chunk *trash = get_trash_chunk(); char *pos; pos = ultoa_r(smp->data.uint, trash->str, trash->size); @@ -222,7 +197,7 @@ static int c_int2str(struct sample *smp) static int c_datadup(struct sample *smp) { - struct chunk *trash = sample_get_trash_chunk(); + struct chunk *trash = get_trash_chunk(); trash->len = smp->data.str.len < trash->size ? smp->data.str.len : trash->size; memcpy(trash->str, smp->data.str.str, trash->len); diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 0c0876905c..87eff2b7c4 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -1446,7 +1446,7 @@ smp_fetch_ssl_c_serial(struct proxy *px, struct session *l4, void *l7, unsigned if (!crt) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (ssl_sock_get_serial(crt, smp_trash) <= 0) goto out; @@ -1481,7 +1481,7 @@ smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigne if (!crt) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0) goto out; @@ -1521,7 +1521,7 @@ smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned in if (!name) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (args && args[0].type == ARGT_STR) { int pos = 1; @@ -1567,7 +1567,7 @@ smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsign if (!crt) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0) goto out; @@ -1607,7 +1607,7 @@ smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned in if (!name) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (args && args[0].type == ARGT_STR) { int pos = 1; @@ -1799,7 +1799,7 @@ smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned if (!crt) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (ssl_sock_get_serial(crt, smp_trash) <= 0) goto out; @@ -1830,7 +1830,7 @@ smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigne if (!crt) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0) goto out; @@ -1862,7 +1862,7 @@ smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsign if (!crt) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0) goto out; @@ -1989,7 +1989,7 @@ smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned in if (!name) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (args && args[0].type == ARGT_STR) { int pos = 1; @@ -2037,7 +2037,7 @@ smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned in if (!name) goto out; - smp_trash = sample_get_trash_chunk(); + smp_trash = get_trash_chunk(); if (args && args[0].type == ARGT_STR) { int pos = 1;