]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: vars: Add vars_set_by_name_ifexist function
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 31 Oct 2016 10:05:37 +0000 (11:05 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 9 Nov 2016 21:57:00 +0000 (22:57 +0100)
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..

include/proto/vars.h
src/vars.c

index de0987d6d9d03e0cbcd37fbe5edacb4c214e1632..8414baac12d6f06282e846b64d18fc2a7b12c34b 100644 (file)
@@ -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);
index e37ff74f9cf6fbb8b4d297796995facffb3dc0c5..8322982512d15e1b1673bc883bdb8a26db9bf96f 100644 (file)
@@ -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;