From: Willy Tarreau Date: Sun, 23 Dec 2012 19:22:19 +0000 (+0100) Subject: MINOR: chunks: centralize the trash chunk allocation X-Git-Tag: v1.5-dev16~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47ca54505c87ffac1fe5037c5ec5376ca975bfcf;p=thirdparty%2Fhaproxy.git MINOR: chunks: centralize the trash chunk allocation At the moment, we need trash chunks almost everywhere and the only correctly implemented one is in the sample code. Let's move this to the chunks so that all other places can use this allocator. Additionally, the get_trash_chunk() function now really returns two different chunks. Previously it used to always overwrite the same chunk and point it to a different buffer, which was a bit tricky because it's not obvious that two consecutive results do alias each other. --- 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;