[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.
This commit is contained in:
Willy Tarreau 2010-06-06 13:34:54 +02:00
parent f0b38bfc33
commit 08d5f98294
5 changed files with 84 additions and 2 deletions

View File

@ -4995,7 +4995,7 @@ stick store-request <pattern> [table <table>] [{if | unless} <condition>]
stick-table type {ip | integer | string [len <length>] } size <size>
[expire <expire>] [nopurge]
[expire <expire>] [nopurge] [store <data_type>]*
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 <length>] } size <size>
be removed once full. Be sure not to use the "nopurge" parameter
if not expiration delay is specified.
<data_type> 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

View File

@ -3,6 +3,7 @@
* Functions for stick tables management.
*
* Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
* Copyright (C) 2010 Willy Tarreau <w@1wt.eu>
*
* 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 <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 */

View File

@ -3,6 +3,7 @@
* Macros, variables and structures for stick tables management.
*
* Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
* Copyright (C) 2010 Willy Tarreau <w@1wt.eu>
*
* 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 {

View File

@ -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]);

View File

@ -2,6 +2,7 @@
* Stick tables management functions.
*
* Copyright 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
* Copyright (C) 2010 Willy Tarreau <w@1wt.eu>
*
* 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 <name>,
* 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;
}