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:
parent
3ed22a4390
commit
47ca54505c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
42
src/chunk.c
42
src/chunk.c
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
35
src/sample.c
35
src/sample.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue