MEDIUM: vars: move the session variables to the session, not the stream

It's important that the session-wide variables are in the session and not
in the stream.
This commit is contained in:
Willy Tarreau 2015-06-19 11:59:02 +02:00
parent 7233098da1
commit ebcd4844e8
5 changed files with 46 additions and 15 deletions

View 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);

View 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 */

View 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);
}

View 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);

View 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: