]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: vars: move the session variables to the session, not the stream
authorWilly Tarreau <w@1wt.eu>
Fri, 19 Jun 2015 09:59:02 +0000 (11:59 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 19 Jun 2015 09:59:02 +0000 (11:59 +0200)
It's important that the session-wide variables are in the session and not
in the stream.

include/proto/vars.h
include/types/session.h
src/session.c
src/stream.c
src/vars.c

index e1092c75aa4777046d2e0aec908280c8629112d5..4c8582565f2ec6ede1eef8563e2dac5b9708510d 100644 (file)
@@ -5,6 +5,7 @@
 
 void vars_init(struct vars *vars, enum vars_scope scope);
 void vars_prune(struct vars *vars, struct stream *strm);
+void vars_prune_per_sess(struct vars *vars);
 int vars_get_by_name(const char *name, size_t len, struct stream *strm, struct sample *smp);
 void vars_set_by_name(const char *name, size_t len, struct stream *strm, struct sample *smp);
 int vars_check_arg(struct arg *arg, char **err);
index d02e57fef2ffae0691935b6d680d8482f4ed63ae..62c3a95fe084624f59e4fe069db210b91c498358 100644 (file)
@@ -35,6 +35,7 @@
 #include <types/proxy.h>
 #include <types/stick_table.h>
 #include <types/task.h>
+#include <types/vars.h>
 
 struct session {
        struct proxy *fe;               /* the proxy this session depends on for the client side */
@@ -43,6 +44,7 @@ struct session {
        struct timeval accept_date;     /* date of the session's accept() in user date */
        struct timeval tv_accept;       /* date of the session's accept() in internal date (monotonic) */
        struct stkctr stkctr[MAX_SESS_STKCTR];  /* stick counters for tcp-connection */
+       struct vars vars;               /* list of variables for the session scope. */
 };
 
 #endif /* _TYPES_SESSION_H */
index 7189fbeebc82d627d517c24fbe780f737cc5ef12..44fccbf1d881ae50685e776145b88ba5d46fea49 100644 (file)
@@ -27,6 +27,7 @@
 #include <proto/raw_sock.h>
 #include <proto/session.h>
 #include <proto/stream.h>
+#include <proto/vars.h>
 
 struct pool_head *pool2_session;
 
@@ -59,6 +60,7 @@ struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type
                sess->accept_date = date; /* user-visible date for logging */
                sess->tv_accept   = now;  /* corrected date for internal use */
                memset(sess->stkctr, 0, sizeof(sess->stkctr));
+               vars_init(&sess->vars, SCOPE_SESS);
        }
        return sess;
 }
@@ -66,6 +68,7 @@ struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type
 void session_free(struct session *sess)
 {
        session_store_counters(sess);
+       vars_prune_per_sess(&sess->vars);
        pool_free2(pool2_session, sess);
 }
 
index 0a38f2e994976adf15e6f450fb525c555a078ed6..10038268dd6c4fa8b615a8c8262a78b733e3c12a 100644 (file)
@@ -137,10 +137,9 @@ struct stream *stream_new(struct session *sess, struct task *t, enum obj_type *o
        s->req_cap = NULL;
        s->res_cap = NULL;
 
-       /* Initialise alle the variable context even if will not use.
-        * This permits to prune these context without errors.
+       /* Initialise all the variables contexts even if not used.
+        * This permits to prune these contexts without errors.
         */
-       vars_init(&s->vars_sess,   SCOPE_SESS);
        vars_init(&s->vars_txn,    SCOPE_TXN);
        vars_init(&s->vars_reqres, SCOPE_REQ);
 
@@ -302,7 +301,6 @@ static void stream_free(struct stream *s)
        }
 
        /* Cleanup all variable contexts. */
-       vars_prune(&s->vars_sess, s);
        vars_prune(&s->vars_txn, s);
        vars_prune(&s->vars_reqres, s);
 
index 9662abe3157328ec6b4af3561bc354716d699ae6..fa521f35e1879a6ab17c568467be0e0207522bb2 100644 (file)
@@ -10,6 +10,7 @@
 #include <proto/proto_tcp.h>
 #include <proto/sample.h>
 #include <proto/stream.h>
+#include <proto/vars.h>
 
 /* This contains a pool of struct vars */
 static struct pool_head *var_pool = NULL;
@@ -93,7 +94,33 @@ void vars_prune(struct vars *vars, struct stream *strm)
                pool_free2(var_pool, var);
                size += sizeof(struct var);
        }
-       var_accounting_diff(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, -size);
+       var_accounting_diff(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, -size);
+}
+
+/* This function frees all the memory used by all the session variables in the
+ * list starting at <vars>.
+ */
+void vars_prune_per_sess(struct vars *vars)
+{
+       struct var *var, *tmp;
+       unsigned int size = 0;
+
+       list_for_each_entry_safe(var, tmp, &vars->head, l) {
+               if (var->data.type == SMP_T_STR ||
+                   var->data.type == SMP_T_BIN) {
+                       free(var->data.data.str.str);
+                       size += var->data.data.str.len;
+               }
+               else if (var->data.type == SMP_T_METH) {
+                       free(var->data.data.meth.str.str);
+                       size += var->data.data.meth.str.len;
+               }
+               LIST_DEL(&var->l);
+               pool_free2(var_pool, var);
+               size += sizeof(struct var);
+       }
+       vars->size      -= size;
+       var_global_size -= size;
 }
 
 /* This function init a list of variabes. */
@@ -207,7 +234,7 @@ static int smp_fetch_var(const struct arg *args, struct sample *smp, const char
 
        /* Check the availibity of the variable. */
        switch (var_desc->scope) {
-       case SCOPE_SESS: vars = &smp->strm->vars_sess;   break;
+       case SCOPE_SESS: vars = &smp->strm->sess->vars;  break;
        case SCOPE_TXN:  vars = &smp->strm->vars_txn;    break;
        case SCOPE_REQ:
        case SCOPE_RES:
@@ -245,16 +272,16 @@ static int sample_store(struct vars *vars, const char *name, struct stream *strm
                if (var->data.type == SMP_T_STR ||
                    var->data.type == SMP_T_BIN) {
                        free(var->data.data.str.str);
-                       var_accounting_diff(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, -var->data.data.str.len);
+                       var_accounting_diff(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, -var->data.data.str.len);
                }
                else if (var->data.type == SMP_T_METH) {
                        free(var->data.data.meth.str.str);
-                       var_accounting_diff(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, -var->data.data.meth.str.len);
+                       var_accounting_diff(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, -var->data.data.meth.str.len);
                }
        } else {
 
                /* Check memory avalaible. */
-               if (!var_accounting_add(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, sizeof(struct var)))
+               if (!var_accounting_add(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, sizeof(struct var)))
                        return 0;
 
                /* Create new entry. */
@@ -283,13 +310,13 @@ static int sample_store(struct vars *vars, const char *name, struct stream *strm
                break;
        case SMP_T_STR:
        case SMP_T_BIN:
-               if (!var_accounting_add(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, smp->data.str.len)) {
+               if (!var_accounting_add(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, smp->data.str.len)) {
                        var->data.type = SMP_T_BOOL; /* This type doesn't use additional memory. */
                        return 0;
                }
                var->data.data.str.str = malloc(smp->data.str.len);
                if (!var->data.data.str.str) {
-                       var_accounting_diff(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, -smp->data.str.len);
+                       var_accounting_diff(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, -smp->data.str.len);
                        var->data.type = SMP_T_BOOL; /* This type doesn't use additional memory. */
                        return 0;
                }
@@ -297,13 +324,13 @@ static int sample_store(struct vars *vars, const char *name, struct stream *strm
                memcpy(var->data.data.str.str, smp->data.str.str, var->data.data.str.len);
                break;
        case SMP_T_METH:
-               if (!var_accounting_add(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, smp->data.meth.str.len)) {
+               if (!var_accounting_add(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, smp->data.meth.str.len)) {
                        var->data.type = SMP_T_BOOL; /* This type doesn't use additional memory. */
                        return 0;
                }
                var->data.data.meth.str.str = malloc(smp->data.meth.str.len);
                if (!var->data.data.meth.str.str) {
-                       var_accounting_diff(vars, &strm->vars_sess, &strm->vars_txn, &strm->vars_reqres, -smp->data.meth.str.len);
+                       var_accounting_diff(vars, &strm->sess->vars, &strm->vars_txn, &strm->vars_reqres, -smp->data.meth.str.len);
                        var->data.type = SMP_T_BOOL; /* This type doesn't use additional memory. */
                        return 0;
                }
@@ -323,7 +350,7 @@ static inline int sample_store_stream(const char *name, enum vars_scope scope,
        struct vars *vars;
 
        switch (scope) {
-       case SCOPE_SESS: vars = &strm->vars_sess;   break;
+       case SCOPE_SESS: vars = &strm->sess->vars;  break;
        case SCOPE_TXN:  vars = &strm->vars_txn;    break;
        case SCOPE_REQ:
        case SCOPE_RES:
@@ -399,7 +426,7 @@ int vars_get_by_name(const char *name, size_t len, struct stream *strm, struct s
 
        /* Select "vars" pool according with the scope. */
        switch (scope) {
-       case SCOPE_SESS: vars = &strm->vars_sess;   break;
+       case SCOPE_SESS: vars = &strm->sess->vars;  break;
        case SCOPE_TXN:  vars = &strm->vars_txn;    break;
        case SCOPE_REQ:
        case SCOPE_RES: