From: Christopher Faulet Date: Wed, 17 Jul 2024 14:38:13 +0000 (+0200) Subject: MINOR: vars: Use a description to set/unset a variable instead of its hash and scope X-Git-Tag: v3.1-dev4~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d430edcda3d80b4a9fb9b49d8d275663841d81c1;p=thirdparty%2Fhaproxy.git MINOR: vars: Use a description to set/unset a variable instead of its hash and scope Now a variable description is retrieved when a variable is parsed, we can use it to set or unset the variable value. It is mandatory to be able to know the parent stream, if any, must be used, instead of the current one. --- diff --git a/include/haproxy/vars.h b/include/haproxy/vars.h index 9fa351c297..b66a5d4412 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 d252c237ee..315e7e72c2 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 c9b9eb07c2..2978e542f5 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