From: Christopher Faulet Date: Mon, 31 Oct 2016 10:05:37 +0000 (+0100) Subject: MINOR: vars: Add vars_set_by_name_ifexist function X-Git-Tag: v1.7-dev6~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09c9df286b0343cd665328c95241a3f2d9b14f2f;p=thirdparty%2Fhaproxy.git MINOR: vars: Add vars_set_by_name_ifexist function This function, unsurprisingly, sets a variable value only if it already exists. In other words, this function will succeed only if the variable was found somewhere in the configuration during HAProxy startup. It will be used by SPOE filter. So an agent will be able to set a value only for existing variables. This prevents an agent to create a very large number of unused variables to flood HAProxy and exhaust the memory reserved to variables.. --- diff --git a/include/proto/vars.h b/include/proto/vars.h index de0987d6d9..8414baac12 100644 --- a/include/proto/vars.h +++ b/include/proto/vars.h @@ -7,6 +7,7 @@ void vars_init(struct vars *vars, enum vars_scope scope); void vars_prune(struct vars *vars, struct session *sess, struct stream *strm); void vars_prune_per_sess(struct vars *vars); int vars_get_by_name(const char *name, size_t len, struct sample *smp); +void vars_set_by_name_ifexist(const char *name, size_t len, struct sample *smp); void vars_set_by_name(const char *name, size_t len, struct sample *smp); int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp); int vars_check_arg(struct arg *arg, char **err); diff --git a/src/vars.c b/src/vars.c index e37ff74f9c..8322982512 100644 --- a/src/vars.c +++ b/src/vars.c @@ -148,7 +148,8 @@ void vars_init(struct vars *vars, enum vars_scope scope) * left inconsistent. Otherwise, it returns the pointer on the global * name. */ -static char *register_name(const char *name, int len, enum vars_scope *scope, char **err) +static char *register_name(const char *name, int len, enum vars_scope *scope, + int alloc, char **err) { int i; char **var_names2; @@ -192,6 +193,9 @@ static char *register_name(const char *name, int len, enum vars_scope *scope, ch if (strncmp(var_names[i], name, len) == 0) return var_names[i]; + if (!alloc) + return NULL; + /* Store variable name. If realloc fails, var_names remains valid */ var_names2 = realloc(var_names, (var_names_nb + 1) * sizeof(*var_names)); if (!var_names2) { @@ -398,7 +402,7 @@ int vars_check_arg(struct arg *arg, char **err) } /* Register new variable name. */ - name = register_name(arg->data.str.str, arg->data.str.len, &scope, err); + name = register_name(arg->data.str.str, arg->data.str.len, &scope, 1, err); if (!name) return 0; @@ -409,6 +413,22 @@ int vars_check_arg(struct arg *arg, char **err) return 1; } +/* This function store a sample in a variable if it was already defined. + * In error case, it fails silently. + */ +void vars_set_by_name_ifexist(const char *name, size_t len, struct sample *smp) +{ + enum vars_scope scope; + + /* Resolve name and scope. */ + name = register_name(name, len, &scope, 0, NULL); + if (!name) + return; + + sample_store_stream(name, scope, smp); +} + + /* This function store a sample in a variable. * In error case, it fails silently. */ @@ -417,7 +437,7 @@ void vars_set_by_name(const char *name, size_t len, struct sample *smp) enum vars_scope scope; /* Resolve name and scope. */ - name = register_name(name, len, &scope, NULL); + name = register_name(name, len, &scope, 1, NULL); if (!name) return; @@ -435,7 +455,7 @@ int vars_get_by_name(const char *name, size_t len, struct sample *smp) enum vars_scope scope; /* Resolve name and scope. */ - name = register_name(name, len, &scope, NULL); + name = register_name(name, len, &scope, 1, NULL); if (!name) return 0; @@ -576,7 +596,7 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy return ACT_RET_PRS_ERR; } - rule->arg.vars.name = register_name(var_name, var_len, &rule->arg.vars.scope, err); + rule->arg.vars.name = register_name(var_name, var_len, &rule->arg.vars.scope, 1, err); if (!rule->arg.vars.name) return ACT_RET_PRS_ERR;