mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
MEDIUM: checks: Add a list of vars to set before executing a tpc-check ruleset
A list of variables is now associated to each tcp-check ruleset. It is more a less a list of set-var expressions. This list may be filled during the configuration parsing. The listed variables will then be set during each execution of the tcp-check healthcheck, at the begining, before execution of the the first tcp-check rule. This patch is mandatory to convert all protocol checks to tcp-checks. It is a way to customize shared tcp-check rulesets.
This commit is contained in:
parent
bb591a1a11
commit
7a1e2e1823
@ -63,6 +63,8 @@ static inline void tcp_check_keywords_register(struct action_kw_list *kw_list)
|
||||
}
|
||||
|
||||
void deinit_proxy_tcpcheck(struct proxy *px);
|
||||
int dup_tcpcheck_vars(struct list *dst, struct list *src);
|
||||
|
||||
/* Declared here, but the definitions are in flt_spoe.c */
|
||||
int spoe_prepare_healthcheck_request(char **req, int *len);
|
||||
int spoe_handle_healthcheck_response(char *frame, size_t size, char *err, int errlen);
|
||||
|
@ -302,10 +302,18 @@ struct tcpcheck_rule {
|
||||
#define TCPCHK_RULES_SHARED 0x00000001 /* Set for shared list of tcp-check rules */
|
||||
#define TCPCHK_RULES_DEF 0x00000002 /* Ruleset inherited from the default section */
|
||||
|
||||
/* A list of tcp-check vars, to be registered before executing a ruleset */
|
||||
struct tcpcheck_var {
|
||||
struct ist name; /* the variable name with the scope */
|
||||
struct sample_data data; /* the data associated to the variable */
|
||||
struct list list; /* element to chain tcp-check vars */
|
||||
};
|
||||
|
||||
/* a list of tcp-check rules */
|
||||
struct tcpcheck_rules {
|
||||
unsigned int flags; /* flags applied to the rules */
|
||||
struct list *list; /* the list of tcpcheck_rules */
|
||||
unsigned int flags; /* flags applied to the rules */
|
||||
struct list *list; /* the list of tcpcheck_rules */
|
||||
struct list preset_vars; /* The list of variable to preset before executing the ruleset */
|
||||
};
|
||||
|
||||
/* A list of tcp-check rules with a name */
|
||||
|
@ -305,6 +305,15 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
|
||||
curproxy->tcpcheck_rules.flags = (defproxy.tcpcheck_rules.flags | TCPCHK_RULES_DEF);
|
||||
curproxy->tcpcheck_rules.list = defproxy.tcpcheck_rules.list;
|
||||
if (!LIST_ISEMPTY(&defproxy.tcpcheck_rules.preset_vars)) {
|
||||
if (!dup_tcpcheck_vars(&curproxy->tcpcheck_rules.preset_vars,
|
||||
&defproxy.tcpcheck_rules.preset_vars)) {
|
||||
ha_alert("parsing [%s:%d] : failed to duplicate tcpcheck preset-vars\n",
|
||||
file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (defproxy.expect_str) {
|
||||
curproxy->expect_str = strdup(defproxy.expect_str);
|
||||
|
89
src/checks.c
89
src/checks.c
@ -3279,6 +3279,8 @@ static int tcpcheck_main(struct check *check)
|
||||
rule = check->current_step;
|
||||
}
|
||||
else {
|
||||
struct tcpcheck_var *var;
|
||||
|
||||
/* First evaluation, create a session */
|
||||
check->sess = session_new(&checks_fe, NULL, (check->server ? &check->server->obj_type : NULL));
|
||||
if (!check->sess) {
|
||||
@ -3288,6 +3290,16 @@ static int tcpcheck_main(struct check *check)
|
||||
}
|
||||
vars_init(&check->vars, SCOPE_CHECK);
|
||||
rule = LIST_NEXT(check->tcpcheck_rules->list, typeof(rule), list);
|
||||
|
||||
/* Preset tcp-check variables */
|
||||
list_for_each_entry(var, &check->tcpcheck_rules->preset_vars, list) {
|
||||
struct sample smp;
|
||||
|
||||
memset(&smp, 0, sizeof(smp));
|
||||
smp_set_owner(&smp, check->proxy, check->sess, NULL, SMP_OPT_FINAL);
|
||||
smp.data = var->data;
|
||||
vars_set_by_name_ifexist(var->name.ptr, var->name.len, &smp);
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry_from(rule, check->tcpcheck_rules->list, list) {
|
||||
@ -3538,6 +3550,80 @@ static void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool)
|
||||
free(rule);
|
||||
}
|
||||
|
||||
|
||||
static __maybe_unused struct tcpcheck_var *tcpcheck_var_create(const char *name)
|
||||
{
|
||||
struct tcpcheck_var *var = NULL;
|
||||
|
||||
var = calloc(1, sizeof(*var));
|
||||
if (var == NULL)
|
||||
return NULL;
|
||||
|
||||
var->name = ist2(strdup(name), strlen(name));
|
||||
if (var->name.ptr == NULL) {
|
||||
free(var);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIST_INIT(&var->list);
|
||||
return var;
|
||||
}
|
||||
|
||||
static void tcpcheck_var_release(struct tcpcheck_var *var)
|
||||
{
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
free(var->name.ptr);
|
||||
if (var->data.type == SMP_T_STR || var->data.type == SMP_T_BIN)
|
||||
free(var->data.u.str.area);
|
||||
else if (var->data.type == SMP_T_METH && var->data.u.meth.meth == HTTP_METH_OTHER)
|
||||
free(var->data.u.meth.str.area);
|
||||
free(var);
|
||||
}
|
||||
|
||||
int dup_tcpcheck_vars(struct list *dst, struct list *src)
|
||||
{
|
||||
struct tcpcheck_var *var, *new = NULL;
|
||||
|
||||
list_for_each_entry(var, src, list) {
|
||||
new = tcpcheck_var_create(var->name.ptr);
|
||||
if (!new)
|
||||
goto error;
|
||||
new->data.type = var->data.type;
|
||||
if (var->data.type == SMP_T_STR || var->data.type == SMP_T_BIN) {
|
||||
if (chunk_dup(&new->data.u.str, &var->data.u.str) == NULL)
|
||||
goto error;
|
||||
if (var->data.type == SMP_T_STR)
|
||||
new->data.u.str.area[new->data.u.str.data] = 0;
|
||||
}
|
||||
else if (var->data.type == SMP_T_METH && var->data.u.meth.meth == HTTP_METH_OTHER) {
|
||||
if (chunk_dup(&new->data.u.str, &var->data.u.str) == NULL)
|
||||
goto error;
|
||||
new->data.u.str.area[new->data.u.str.data] = 0;
|
||||
new->data.u.meth.meth = var->data.u.meth.meth;
|
||||
}
|
||||
else
|
||||
new->data.u = var->data.u;
|
||||
LIST_ADDQ(dst, &new->list);
|
||||
}
|
||||
return 1;
|
||||
|
||||
error:
|
||||
free(new);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_tcpcheck_vars(struct list *vars)
|
||||
{
|
||||
struct tcpcheck_var *var, *back;
|
||||
|
||||
list_for_each_entry_safe(var, back, vars, list) {
|
||||
LIST_DEL(&var->list);
|
||||
tcpcheck_var_release(var);
|
||||
}
|
||||
}
|
||||
|
||||
void email_alert_free(struct email_alert *alert)
|
||||
{
|
||||
struct tcpcheck_rule *rule, *back;
|
||||
@ -3550,6 +3636,7 @@ void email_alert_free(struct email_alert *alert)
|
||||
LIST_DEL(&rule->list);
|
||||
free_tcpcheck(rule, 1);
|
||||
}
|
||||
free_tcpcheck_vars(&alert->rules.preset_vars);
|
||||
free(alert->rules.list);
|
||||
alert->rules.list = NULL;
|
||||
}
|
||||
@ -3757,6 +3844,7 @@ static int enqueue_one_email_alert(struct proxy *p, struct server *s,
|
||||
if (!alert->rules.list)
|
||||
goto error;
|
||||
LIST_INIT(alert->rules.list);
|
||||
LIST_INIT(&alert->rules.preset_vars); /* unused for email alerts */
|
||||
alert->srv = s;
|
||||
|
||||
if ((tcpcheck = pool_alloc(pool_head_tcpcheck_rule)) == NULL)
|
||||
@ -4122,6 +4210,7 @@ void deinit_proxy_tcpcheck(struct proxy *px)
|
||||
LIST_DEL(&chk->list);
|
||||
free_tcpcheck(chk, 0);
|
||||
}
|
||||
free_tcpcheck_vars(&px->tcpcheck_rules.preset_vars);
|
||||
free(px->tcpcheck_rules.list);
|
||||
|
||||
end:
|
||||
|
@ -877,6 +877,7 @@ void init_new_proxy(struct proxy *p)
|
||||
LIST_INIT(&p->conf.errors);
|
||||
LIST_INIT(&p->conf.args.list);
|
||||
LIST_INIT(&p->filter_configs);
|
||||
LIST_INIT(&p->tcpcheck_rules.preset_vars);
|
||||
|
||||
/* Timeouts are defined as -1 */
|
||||
proxy_reset_timeouts(p);
|
||||
|
Loading…
Reference in New Issue
Block a user