mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-30 01:52:53 +00:00
[MEDIUM] stick-tables: add support for arguments to data_types
Some data types will require arguments (eg: period for a rate counter). This patch adds support for such arguments between parenthesis in the "store" directive of the stick-table statement. Right now only integers are supported.
This commit is contained in:
parent
b084e9ccb9
commit
888617dc3b
@ -23,6 +23,7 @@
|
||||
#ifndef _PROTO_STICK_TABLE_H
|
||||
#define _PROTO_STICK_TABLE_H
|
||||
|
||||
#include <common/errors.h>
|
||||
#include <types/stick_table.h>
|
||||
|
||||
#define stktable_data_size(type) (sizeof(((union stktable_data*)0)->type))
|
||||
@ -48,21 +49,27 @@ int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_t
|
||||
int stktable_get_data_type(char *name);
|
||||
struct proxy *find_stktable(const char *name);
|
||||
|
||||
/* reserve some space for data type <type>. Return non-0 if OK, or 0 if already
|
||||
* allocated (or impossible type).
|
||||
/* reserve some space for data type <type>, and associate argument at <sa> if
|
||||
* not NULL. Returns PE_NONE (0) if OK or an error code among :
|
||||
* - PE_ENUM_OOR if <type> does not exist
|
||||
* - PE_EXIST if <type> is already registered
|
||||
*/
|
||||
static inline int stktable_alloc_data_type(struct stktable *t, int type)
|
||||
static inline int stktable_alloc_data_type(struct stktable *t, int type, const char *sa)
|
||||
{
|
||||
if (type >= STKTABLE_DATA_TYPES)
|
||||
return 0;
|
||||
return PE_ENUM_OOR;
|
||||
|
||||
if (t->data_ofs[type])
|
||||
/* already allocated */
|
||||
return 0;
|
||||
return PE_EXIST;
|
||||
|
||||
t->data_size += stktable_data_types[type].data_length;
|
||||
t->data_ofs[type] = -t->data_size;
|
||||
return 1;
|
||||
/* right now only int type is supported, but we may later support type-
|
||||
* specific arg type.
|
||||
*/
|
||||
t->data_arg[type].i = sa ? atoi(sa) : 0;
|
||||
return PE_NONE;
|
||||
}
|
||||
|
||||
/* return pointer for data type <type> in sticky session <ts> of table <t>, or
|
||||
|
@ -50,6 +50,13 @@ enum {
|
||||
STKTABLE_DATA_TYPES /* Number of data types, must always be last */
|
||||
};
|
||||
|
||||
/* The types of optional arguments to stored data */
|
||||
enum {
|
||||
ARG_T_NONE = 0, /* data type takes no argument (default) */
|
||||
ARG_T_INT, /* signed integer */
|
||||
ARG_T_DELAY, /* a delay which supports time units */
|
||||
};
|
||||
|
||||
/* stick_table extra data. This is mainly used for casting or size computation */
|
||||
union stktable_data {
|
||||
int server_id;
|
||||
@ -64,6 +71,7 @@ union stktable_data {
|
||||
struct stktable_data_type {
|
||||
const char *name; /* name of the data type */
|
||||
int data_length; /* length of this type, or 0 if variable (eg: string) */
|
||||
int arg_type; /* type of optional argument, ARG_T_* */
|
||||
};
|
||||
|
||||
/* stick table key type flags */
|
||||
@ -104,6 +112,11 @@ struct stktable {
|
||||
int expire; /* time to live for sticky sessions (milliseconds) */
|
||||
int data_size; /* the size of the data that is prepended *before* stksess */
|
||||
int data_ofs[STKTABLE_DATA_TYPES]; /* negative offsets of present data types, or 0 if absent */
|
||||
union {
|
||||
int i;
|
||||
unsigned int u;
|
||||
void *p;
|
||||
} data_arg[STKTABLE_DATA_TYPES]; /* optional argument of each data type */
|
||||
};
|
||||
|
||||
struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
|
||||
|
@ -2276,15 +2276,31 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
}
|
||||
else if (strcmp(args[myidx], "store") == 0) {
|
||||
int type;
|
||||
char *cw, *nw;
|
||||
char *cw, *nw, *sa;
|
||||
|
||||
myidx++;
|
||||
nw = args[myidx];
|
||||
while (*nw) {
|
||||
/* the "store" keyword supports a comma-separated list */
|
||||
cw = nw;
|
||||
while (*nw && *nw != ',')
|
||||
sa = NULL; /* store arg */
|
||||
while (*nw && *nw != ',') {
|
||||
if (*nw == '(') {
|
||||
*nw = 0;
|
||||
sa = ++nw;
|
||||
while (*nw != ')') {
|
||||
if (!*nw) {
|
||||
Alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
|
||||
file, linenum, args[0], cw);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
nw++;
|
||||
}
|
||||
*nw = '\0';
|
||||
}
|
||||
nw++;
|
||||
}
|
||||
if (*nw)
|
||||
*nw++ = '\0';
|
||||
type = stktable_get_data_type(cw);
|
||||
@ -2294,7 +2310,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
if (!stktable_alloc_data_type(&curproxy->table, type)) {
|
||||
if (stktable_alloc_data_type(&curproxy->table, type, sa)) {
|
||||
Warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
|
||||
file, linenum, args[0], cw);
|
||||
err_code |= ERR_WARN;
|
||||
@ -4910,7 +4926,7 @@ int check_config_validity()
|
||||
else {
|
||||
free((void *)mrule->table.name);
|
||||
mrule->table.t = &(target->table);
|
||||
stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID);
|
||||
stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4943,7 +4959,7 @@ int check_config_validity()
|
||||
else {
|
||||
free((void *)mrule->table.name);
|
||||
mrule->table.t = &(target->table);
|
||||
stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID);
|
||||
stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user