From: Christopher Faulet Date: Wed, 17 Jul 2024 13:57:55 +0000 (+0200) Subject: MEDIUM: vars: Be able to parse parent scopes for variables X-Git-Tag: v3.1-dev4~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f93828f229dbd60792e00452aaaf83fcb049a1ed;p=thirdparty%2Fhaproxy.git MEDIUM: vars: Be able to parse parent scopes for variables Add session/stream scopes related to the parent. To do so, "psess", "ptxn", "preq" or "pres" must be used instead of tranditionnal scopes (without the first "p"). the "proc" scope is not concerned by this change because it is not linked to a stream. When such scopes are used, a specific flags is added on the variable description during the variable parsing. For now, theses scopes are parsed and the variable description is updated accordingly. But at the end, any operation on the variable value fails. --- diff --git a/include/haproxy/vars-t.h b/include/haproxy/vars-t.h index e239b1c8cc..320c7d6831 100644 --- a/include/haproxy/vars-t.h +++ b/include/haproxy/vars-t.h @@ -54,10 +54,13 @@ struct vars { __decl_thread(HA_RWLOCK_T rwlock); }; +#define VDF_PARENT_CTX 0x00000001 // Set if the variable is related to the parent stream + /* This struct describes a variable as found in an arg_data */ struct var_desc { uint64_t name_hash; enum vars_scope scope; + uint flags; /*VDF_* */ }; struct var { diff --git a/src/vars.c b/src/vars.c index 2978e542f5..d312bf79bc 100644 --- a/src/vars.c +++ b/src/vars.c @@ -250,40 +250,66 @@ static int vars_fill_desc(const char *name, int len, struct var_desc *desc, char return 0; } - /* Check scope. */ - if (len > 5 && strncmp(name, "proc.", 5) == 0) { + desc->flags = 0; + + /* Check scope including those related to the parent stream (prefixed by ('p'). */ + if (len > 6 && strncmp(name, "psess.", 6) == 0) { + name += 6; + len -= 6; + desc->scope = SCOPE_SESS; + desc->flags |= VDF_PARENT_CTX; + } + else if (len > 5 && strncmp(name, "ptxn.", 5) == 0) { name += 5; len -= 5; - *scope = SCOPE_PROC; + desc->scope = SCOPE_TXN; + desc->flags |= VDF_PARENT_CTX; + } + else if (len > 5 && strncmp(name, "preq.", 5) == 0) { + name += 5; + len -= 5; + desc->scope = SCOPE_REQ; + desc->flags |= VDF_PARENT_CTX; + } + else if (len > 5 && strncmp(name, "pres.", 5) == 0) { + name += 5; + len -= 5; + desc->scope = SCOPE_RES; + desc->flags |= VDF_PARENT_CTX; + } + else if (len > 5 && strncmp(name, "proc.", 5) == 0) { + name += 5; + len -= 5; + desc->scope = SCOPE_PROC; } else if (len > 5 && strncmp(name, "sess.", 5) == 0) { name += 5; len -= 5; - *scope = SCOPE_SESS; + desc->scope = SCOPE_SESS; } else if (len > 4 && strncmp(name, "txn.", 4) == 0) { name += 4; len -= 4; - *scope = SCOPE_TXN; + desc->scope = SCOPE_TXN; } else if (len > 4 && strncmp(name, "req.", 4) == 0) { name += 4; len -= 4; - *scope = SCOPE_REQ; + desc->scope = SCOPE_REQ; } else if (len > 4 && strncmp(name, "res.", 4) == 0) { name += 4; len -= 4; - *scope = SCOPE_RES; + desc->scope = SCOPE_RES; } else if (len > 6 && strncmp(name, "check.", 6) == 0) { name += 6; len -= 6; - *scope = SCOPE_CHECK; + desc->scope = SCOPE_CHECK; } else { memprintf(err, "invalid variable name '%.*s'. A variable name must be start by its scope. " - "The scope can be 'proc', 'sess', 'txn', 'req', 'res' or 'check'", len, name); + "The scope can be 'proc', '(p)sess', '(p)txn', '(p)req', '(p)res' or 'check'", len, name); return 0; } @@ -375,7 +401,7 @@ int var_set(const struct var_desc *desc, struct sample *smp, uint flags) int ret = 0; int previous_type = SMP_T_ANY; - if (!desc) + if (!desc || (desc->flags & VDF_PARENT_CTX)) return 0; vars = get_vars(smp->sess, smp->strm, desc->scope); @@ -529,7 +555,7 @@ int var_unset(const struct var_desc *desc, struct sample *smp) struct var *var; unsigned int size = 0; - if (!desc) + if (!desc || (desc->flags & VDF_PARENT_CTX)) return 0; vars = get_vars(smp->sess, smp->strm, desc->scope); @@ -729,6 +755,9 @@ int vars_get_by_name(const char *name, size_t len, struct sample *smp, const str if (!vars_fill_desc(name, len, &desc, NULL)) return 0; + if (desc.flags & VDF_PARENT_CTX) + return 0; + /* Select "vars" pool according with the scope. */ vars = get_vars(smp->sess, smp->strm, desc.scope); if (!vars || vars->scope != desc.scope) @@ -754,6 +783,9 @@ int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp, const { struct vars *vars; + if (var_desc->flags & VDF_PARENT_CTX) + return 0; + /* Select "vars" pool according with the scope. */ vars = get_vars(smp->sess, smp->strm, var_desc->scope);