diff --git a/include/haproxy/vars.h b/include/haproxy/vars.h index 9fa351c29..b66a5d441 100644 --- a/include/haproxy/vars.h +++ b/include/haproxy/vars.h @@ -37,8 +37,8 @@ void var_accounting_diff(struct vars *vars, struct session *sess, struct stream unsigned int var_clear(struct var *var, int force); void vars_prune(struct vars *vars, struct session *sess, struct stream *strm); void vars_prune_per_sess(struct vars *vars); -int var_set(uint64_t name_hash, enum vars_scope scope, struct sample *smp, uint flags); -int var_unset(uint64_t name_hash, enum vars_scope scope, struct sample *smp); +int var_set(const struct var_desc *desc, struct sample *smp, uint flags); +int var_unset(const struct var_desc *desc, struct sample *smp); int vars_get_by_name(const char *name, size_t len, struct sample *smp, const struct buffer *def); int vars_set_by_name_ifexist(const char *name, size_t len, struct sample *smp); int vars_set_by_name(const char *name, size_t len, struct sample *smp); diff --git a/src/ssl_sample.c b/src/ssl_sample.c index d252c237e..315e7e72c 100644 --- a/src/ssl_sample.c +++ b/src/ssl_sample.c @@ -394,7 +394,7 @@ static int sample_conv_aes_gcm(const struct arg *arg_p, struct sample *smp, void aead_tag.data.u.str.data = ret; aead_tag.data.type = SMP_T_STR; - if (!var_set(arg_p[3].data.var.name_hash, arg_p[3].data.var.scope, &aead_tag, + if (!var_set(&arg_p[3].data.var, &aead_tag, (arg_p[3].data.var.scope == SCOPE_PROC) ? VF_COND_IFEXISTS : 0)) { goto err; } diff --git a/src/vars.c b/src/vars.c index c9b9eb07c..2978e542f 100644 --- a/src/vars.c +++ b/src/vars.c @@ -368,21 +368,24 @@ static inline void var_clear_buffer(struct sample *smp, struct vars *vars, struc * * It returns 0 on failure, non-zero on success. */ -int var_set(uint64_t name_hash, enum vars_scope scope, struct sample *smp, uint flags) +int var_set(const struct var_desc *desc, struct sample *smp, uint flags) { struct vars *vars; struct var *var; int ret = 0; int previous_type = SMP_T_ANY; - vars = get_vars(smp->sess, smp->strm, scope); - if (!vars || vars->scope != scope) + if (!desc) + return 0; + + vars = get_vars(smp->sess, smp->strm, desc->scope); + if (!vars || vars->scope != desc->scope) return 0; vars_wrlock(vars); /* Look for existing variable name. */ - var = var_get(vars, name_hash); + var = var_get(vars, desc->name_hash); if (var) { if (flags & VF_CREATEONLY) { @@ -405,7 +408,7 @@ int var_set(uint64_t name_hash, enum vars_scope scope, struct sample *smp, uint if (!var) goto unlock; LIST_APPEND(&vars->head, &var->l); - var->name_hash = name_hash; + var->name_hash = desc->name_hash; var->flags = flags & VF_PERMANENT; var->data.type = SMP_T_ANY; } @@ -520,19 +523,22 @@ int var_set(uint64_t name_hash, enum vars_scope scope, struct sample *smp, uint * session and stream found in . Note that stream may be null for * SCOPE_SESS. Returns 0 if the scope was not found otherwise 1. */ -int var_unset(uint64_t name_hash, enum vars_scope scope, struct sample *smp) +int var_unset(const struct var_desc *desc, struct sample *smp) { struct vars *vars; struct var *var; unsigned int size = 0; - vars = get_vars(smp->sess, smp->strm, scope); - if (!vars || vars->scope != scope) + if (!desc) + return 0; + + vars = get_vars(smp->sess, smp->strm, desc->scope); + if (!vars || vars->scope != desc->scope) return 0; /* Look for existing variable name. */ vars_wrlock(vars); - var = var_get(vars, name_hash); + var = var_get(vars, desc->name_hash); if (var) { size = var_clear(var, 0); var_accounting_diff(vars, smp->sess, smp->strm, -size); @@ -578,13 +584,13 @@ static int smp_conv_store(const struct arg *args, struct sample *smp, void *priv break; } - return var_set(args[0].data.var.name_hash, args[0].data.var.scope, smp, conditions); + return var_set(&args[0].data.var, smp, conditions); } /* Returns 0 if fails, else returns 1. */ static int smp_conv_clear(const struct arg *args, struct sample *smp, void *private) { - return var_unset(args[0].data.var.name_hash, args[0].data.var.scope, smp); + return var_unset(&args[0].data.var, smp); } /* This functions check an argument entry and fill it with a variable @@ -606,7 +612,7 @@ int vars_check_arg(struct arg *arg, char **err) if (!vars_fill_desc(arg->data.str.area, arg->data.str.data, &desc, err)) return 0; - if (desc.scope == SCOPE_PROC && !var_set(desc.name_hash, desc.scope, &empty_smp, VF_CREATEONLY|VF_PERMANENT)) + if (desc.scope == SCOPE_PROC && !var_set(&desc, &empty_smp, VF_CREATEONLY|VF_PERMANENT)) return 0; /* properly destroy the chunk */ @@ -632,7 +638,7 @@ int vars_set_by_name_ifexist(const char *name, size_t len, struct sample *smp) return 0; /* Variable creation is allowed for all scopes apart from the PROC one. */ - return var_set(desc.name_hash, desc.scope, smp, (desc.scope == SCOPE_PROC) ? VF_COND_IFEXISTS : 0); + return var_set(&desc, smp, (desc.scope == SCOPE_PROC) ? VF_COND_IFEXISTS : 0); } @@ -647,7 +653,7 @@ int vars_set_by_name(const char *name, size_t len, struct sample *smp) if (!vars_fill_desc(name, len, &desc, NULL)) return 0; - return var_set(desc.name_hash, desc.scope, smp, 0); + return var_set(&desc, smp, 0); } /* This function unsets a variable if it was already defined. @@ -661,7 +667,7 @@ int vars_unset_by_name_ifexist(const char *name, size_t len, struct sample *smp) if (!vars_fill_desc(name, len, &desc, NULL)) return 0; - return var_unset(desc.name_hash, desc.scope, smp); + return var_unset(&desc, smp); } @@ -806,7 +812,7 @@ static enum act_return action_store(struct act_rule *rule, struct proxy *px, smp_set_owner(&smp, px, sess, s, 0); smp.data.type = SMP_T_STR; smp.data.u.str = *fmtstr; - var_set(rule->arg.vars.desc.name_hash, rule->arg.vars.desc.scope, &smp, rule->arg.vars.conditions); + var_set(&rule->arg.vars.desc, &smp, rule->arg.vars.conditions); } else { /* an expression is used */ @@ -816,7 +822,7 @@ static enum act_return action_store(struct act_rule *rule, struct proxy *px, } /* Store the sample, and ignore errors. */ - var_set(rule->arg.vars.desc.name_hash, rule->arg.vars.desc.scope, &smp, rule->arg.vars.conditions); + var_set(&rule->arg.vars.desc, &smp, rule->arg.vars.conditions); free_trash_chunk(fmtstr); return ACT_RET_CONT; } @@ -831,7 +837,7 @@ static enum act_return action_clear(struct act_rule *rule, struct proxy *px, smp_set_owner(&smp, px, sess, s, SMP_OPT_FINAL); /* Clear the variable using the sample context, and ignore errors. */ - var_unset(rule->arg.vars.desc.name_hash, rule->arg.vars.desc.scope, &smp); + var_unset(&rule->arg.vars.desc, &smp); return ACT_RET_CONT; } @@ -946,7 +952,7 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy return ACT_RET_PRS_ERR; if (rule->arg.vars.desc.scope == SCOPE_PROC && - !var_set(rule->arg.vars.desc.name_hash, rule->arg.vars.desc.scope, &empty_smp, VF_CREATEONLY|VF_PERMANENT)) + !var_set(&rule->arg.vars.desc, &empty_smp, VF_CREATEONLY|VF_PERMANENT)) return 0; /* There is no fetch method when variable is unset. Just set the right