From 08d5f98294f689691d69c7ef377603fbd616843d Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 6 Jun 2010 13:34:54 +0200 Subject: [PATCH] [MEDIUM] stick_table: add room for extra data types The stick_tables will now be able to store extra data for a same key. A limited set of extra data types will be defined and for each of them an offset in the sticky session will be assigned at startup time. All of this information will be stored in the stick table. The extra data types will have to be specified after the new "store" keyword of the "stick-table" directive, which will reserve some space for them. --- doc/configuration.txt | 8 +++++++- include/proto/stick_table.h | 18 ++++++++++++++++++ include/types/stick_table.h | 22 +++++++++++++++++++++- src/cfgparse.c | 18 ++++++++++++++++++ src/stick_table.c | 20 ++++++++++++++++++++ 5 files changed, 84 insertions(+), 2 deletions(-) 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; +} +