diff --git a/doc/configuration.txt b/doc/configuration.txt index a9a5793b0..ad4a3ceb0 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -4995,7 +4995,7 @@ stick store-request [table ] [{if | unless} ] stick-table type {ip | integer | string [len ] } size - [expire ] [nopurge] + [expire ] [nopurge] [store ]* Configure the stickiness table for the current backend May be used in sections : defaults | frontend | listen | backend no | no | yes | yes @@ -5049,6 +5049,12 @@ stick-table type {ip | integer | string [len ] } size be removed once full. Be sure not to use the "nopurge" parameter if not expiration delay is specified. + is used to store additional information in the stick-table. This + may be used by ACLs in order to control various criteria related + to the activity of the client matching the stick-table. For each + item specified here, the size of each entry will be inflated so + that the additional data can fit. + The is only one stick-table per backend. At the moment of writing this doc, it does not seem useful to have multiple tables per backend. If this happens to be required, simply create a dummy backend with a stick-table in it and diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index f26e002a9..01cd391ff 100644 --- a/include/proto/stick_table.h +++ b/include/proto/stick_table.h @@ -3,6 +3,7 @@ * Functions for stick tables management. * * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun + * Copyright (C) 2010 Willy Tarreau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,6 +37,23 @@ struct stktable_key *stktable_fetch_key(struct proxy *px, struct session *l4, void *l7, int dir, struct pattern_expr *expr, unsigned long table_type); int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_type); +int stktable_get_data_type(char *name); +/* reserve some space for data type . Return non-0 if OK, or 0 if already + * allocated (or impossible type). + */ +static inline int stktable_alloc_data_type(struct stktable *t, int type) +{ + if (type >= STKTABLE_DATA_TYPES) + return 0; + + if (t->data_ofs[type]) + /* already allocated */ + return 0; + + t->data_size += stktable_data_types[type].data_length; + t->data_ofs[type] = -t->data_size; + return 1; +} #endif /* _PROTO_STICK_TABLE_H */ diff --git a/include/types/stick_table.h b/include/types/stick_table.h index de23610e7..dda9edbc0 100644 --- a/include/types/stick_table.h +++ b/include/types/stick_table.h @@ -3,6 +3,7 @@ * Macros, variables and structures for stick tables management. * * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun + * Copyright (C) 2010 Willy Tarreau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +39,24 @@ enum { STKTABLE_TYPES /* Number of types, must always be last */ }; +/* The types of extra data we can store in a stick table */ +enum { + STKTABLE_DATA_TYPES /* Number of data types, must always be last */ +}; + +/* stick_table extra data. This is mainly used for casting or size computation */ +union stktable_data { +}; + +#define stktable_data_size(type) (sizeof(((union stktable_data*)0)->type)) +#define stktable_data_cast(ptr, type) ((union stktable_data*)(ptr))->type + +/* known data types */ +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) */ +}; + /* stick table key type flags */ #define STK_F_CUSTOM_KEYSIZE 0x00000001 /* this table's key size is configurable */ @@ -75,9 +94,10 @@ struct stktable { int exp_next; /* next expiration date (ticks) */ 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 */ }; -/*** The definitions below should probably be better placed in pattern.h ***/ +struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES]; /* stick table key data */ union stktable_key_data { diff --git a/src/cfgparse.c b/src/cfgparse.c index d2f79f220..f53427085 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2274,6 +2274,24 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } /* myidx already points to next arg */ } + else if (strcmp(args[myidx], "store") == 0) { + int type; + + myidx++; + type = stktable_get_data_type(args[myidx]); + if (type < 0) { + Alert("parsing [%s:%d] : %s: unknown store option '%s'.\n", + file, linenum, args[0], args[myidx]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + if (!stktable_alloc_data_type(&curproxy->table, type)) { + Warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n", + file, linenum, args[0], args[myidx]); + err_code |= ERR_WARN; + } + myidx++; + } else { Alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n", file, linenum, args[myidx]); diff --git a/src/stick_table.c b/src/stick_table.c index fa4692555..158056e1c 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -2,6 +2,7 @@ * Stick tables management functions. * * Copyright 2009-2010 EXCELIANCE, Emeric Brun + * Copyright (C) 2010 Willy Tarreau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -474,3 +475,22 @@ int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_t return 1; } +/* Extra data types processing */ +struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = { +}; + +/* + * Returns the data type number for the stktable_data_type whose name is , + * or <0 if not found. + */ +int stktable_get_data_type(char *name) +{ + int type; + + for (type = 0; type < STKTABLE_DATA_TYPES; type++) { + if (strcmp(name, stktable_data_types[type].name) == 0) + return type; + } + return -1; +} +