From: Willy Tarreau Date: Sun, 6 Jun 2010 10:11:37 +0000 (+0200) Subject: [MINOR] stick_table: add support for variable-sized data X-Git-Tag: v1.5-dev8~569 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=393379c3e0a39aacc3d87065ae7cb7cbcc52cc7e;p=thirdparty%2Fhaproxy.git [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. --- diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index 1cc4624efd..ed44cc0c75 100644 --- a/include/proto/stick_table.h +++ b/include/proto/stick_table.h @@ -25,7 +25,7 @@ #include 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); diff --git a/include/types/stick_table.h b/include/types/stick_table.h index b63b790e7a..bbb9d0d0f6 100644 --- a/include/types/stick_table.h +++ b/include/types/stick_table.h @@ -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 ***/ diff --git a/src/session.c b/src/session.c index ba8cec132e..137bbd330d 100644 --- a/src/session.c +++ b/src/session.c @@ -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]))) { diff --git a/src/stick_table.c b/src/stick_table.c index bc75f67f8a..19cef35ecd 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -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 present in table * from the value present in . */ -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 of table using . + * Init sticky session of table . The data parts are cleared and + * 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 ) {