#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);
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 */
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 ***/
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);
/*
- * 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;
}
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;
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 ) {