[MINOR] stick_table: add support for variable-sized data

Right now we're only able to store a server ID in a sticky session.
The goal is to be able to store anything whose size is known at startup
time. For this, we store the extra data before the stksess pointer,
using a negative offset. It will then be easy to cumulate multiple
data provided they each have their own offset.
This commit is contained in:
Willy Tarreau 2010-06-06 12:11:37 +02:00
parent f8f33284bd
commit 393379c3e0
4 changed files with 19 additions and 13 deletions

View File

@ -25,7 +25,7 @@
#include <types/stick_table.h>
struct stksess *stksess_new(struct stktable *t, struct stktable_key *key);
void stksess_key(struct stktable *t, struct stksess *ts, struct stktable_key *key);
void stksess_setkey(struct stktable *t, struct stksess *ts, struct stktable_key *key);
void stksess_free(struct stktable *t, struct stksess *ts);
int stktable_init(struct stktable *t);

View File

@ -48,7 +48,11 @@ struct stktable_type {
size_t default_size; /* default key size */
};
/* sticky session */
/* Sticky session.
* Any additional data related to the stuck session is installed *before*
* stksess (with negative offsets). This allows us to run variable-sized
* keys and variable-sized data without making use of intermediate pointers.
*/
struct stksess {
int sid; /* id of server to use for this session */
unsigned int expire; /* session expiration date */
@ -70,6 +74,7 @@ struct stktable {
int nopurge; /* if non-zero, don't purge sticky sessions when full */
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 */
};
/*** The definitions below should probably be better placed in pattern.h ***/

View File

@ -1032,7 +1032,7 @@ int process_store_rules(struct session *s, struct buffer *rep, int an_bit)
continue;
if (storereqidx != -1) {
stksess_key(s->store[storereqidx].table, s->store[storereqidx].ts, key);
stksess_setkey(s->store[storereqidx].table, s->store[storereqidx].ts, key);
s->store[storereqidx].flags = 1;
}
else if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {

View File

@ -35,14 +35,14 @@
void stksess_free(struct stktable *t, struct stksess *ts)
{
t->current--;
pool_free2(t->pool, ts);
pool_free2(t->pool, (void *)ts - t->data_size);
}
/*
* Initialize or update the key in the sticky session <ts> present in table <t>
* from the value present in <key>.
*/
void stksess_key(struct stktable *t, struct stksess *ts, struct stktable_key *key)
void stksess_setkey(struct stktable *t, struct stksess *ts, struct stktable_key *key)
{
if (t->type != STKTABLE_TYPE_STRING)
memcpy(ts->keys.key, key->key, t->key_size);
@ -54,15 +54,15 @@ void stksess_key(struct stktable *t, struct stksess *ts, struct stktable_key *ke
/*
* Init sticky session <ts> of table <t> using <key>.
* Init sticky session <ts> of table <t>. The data parts are cleared and <ts>
* is returned.
*/
struct stksess *stksess_init(struct stktable *t, struct stksess * ts, struct stktable_key *key)
static struct stksess *stksess_init(struct stktable *t, struct stksess * ts)
{
memset((void *)ts - t->data_size, 0, t->data_size);
ts->sid = 0;
ts->keys.node.leaf_p = NULL;
ts->exps.node.leaf_p = NULL;
ts->sid = 0;
stksess_key(t, ts, key);
return ts;
}
@ -138,10 +138,11 @@ struct stksess *stksess_new(struct stktable *t, struct stktable_key *key)
return NULL;
}
ts = pool_alloc2(t->pool);
ts = pool_alloc2(t->pool) + t->data_size;
if (ts) {
t->current++;
stksess_init(t, ts, key);
stksess_init(t, ts);
stksess_setkey(t, ts, key);
}
return ts;
@ -281,7 +282,7 @@ int stktable_init(struct stktable *t)
memset(&t->keys, 0, sizeof(t->keys));
memset(&t->exps, 0, sizeof(t->exps));
t->pool = create_pool("sticktables", sizeof(struct stksess) + t->key_size, MEM_F_SHARED);
t->pool = create_pool("sticktables", sizeof(struct stksess) + t->data_size + t->key_size, MEM_F_SHARED);
t->exp_next = TICK_ETERNITY;
if ( t->expire ) {