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)
{
#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,
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 */
#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
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));
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';
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);
/* 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)
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 */
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;
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;
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;
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);
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);
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;