From f93828f229dbd60792e00452aaaf83fcb049a1ed Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 17 Jul 2024 15:57:55 +0200 Subject: [PATCH] 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. --- include/haproxy/vars-t.h | 3 +++ src/vars.c | 54 ++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/include/haproxy/vars-t.h b/include/haproxy/vars-t.h index e239b1c8c..320c7d683 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 2978e542f..d312bf79b 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);