]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] stick_table: add support for variable-sized data
authorWilly Tarreau <w@1wt.eu>
Sun, 6 Jun 2010 10:11:37 +0000 (12:11 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 14 Jun 2010 13:10:23 +0000 (15:10 +0200)
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.

include/proto/stick_table.h
include/types/stick_table.h
src/session.c
src/stick_table.c

index 1cc4624efd4bab6f3744802d2378119306512635..ed44cc0c751d98749a5c2d0189b6003f91365df7 100644 (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);
index b63b790e7a48d7bd6ceaceb6b9d1653ab7c310a6..bbb9d0d0f6c95680cfcdd14c13ec31ecd745a029 100644 (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 ***/
index ba8cec132e38b3a751ee125480456c0135b3073c..137bbd330d161a18c6940ee5a2b2c8931b0cb9ad 100644 (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]))) {
index bc75f67f8ace062b685bc577532d0e72ff5e7d21..19cef35ecd202328f59aa55b139726b320753dd8 100644 (file)
 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 ) {