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.
This commit is contained in:
Willy Tarreau 2012-12-23 20:22:19 +01:00
parent 3ed22a4390
commit 47ca54505c
7 changed files with 63 additions and 50 deletions

View File

@ -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)
{

View File

@ -26,10 +26,6 @@
#include <types/sample.h>
#include <types/stick_table.h>
/* 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 */

View File

@ -18,6 +18,48 @@
#include <common/config.h>
#include <common/chunk.h>
/* 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 <chk>, respecting the limit of
* at most chk->size chars. If the chk->len is over, nothing is added. Returns

View File

@ -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));

View File

@ -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);

View File

@ -26,13 +26,6 @@
/* static sample used in sample_process() when <p> 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);

View File

@ -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;