MINOR: checks: Add support to set-var and unset-var rules in tcp-checks
Evaluate the registered action_ptr associated with each CHK_ACTION_KW rules from
a ruleset. Currently only the 'set-var' and 'unset-var' are parsed by the
tcp-check parser. Thus it is now possible to set or unset variables. It is
possible to use such rules before the first connect of the ruleset.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 09f4b66..40585b8 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -2759,6 +2759,8 @@
tcp-check expect - - X X
tcp-check send - - X X
tcp-check send-binary - - X X
+tcp-check set-var - - X X
+tcp-check unset-var - - X X
tcp-request connection - X X -
tcp-request content - X X X
tcp-request inspect-delay - X X X
@@ -7986,6 +7988,10 @@
in debug mode. It is useful to make user-friendly error reporting.
The "comment" is of course optional.
+ During the execution of a health check, a variable scope is made available
+ to store data samples, using the "tcp-check set-var" operation. Freeing
+ those variable is possible using "tcp-check unset-var".
+
Examples :
# perform a POP check (analyze only server's banner)
@@ -9805,6 +9811,9 @@
the ruleset with a 'connect' rule. Purpose is to ensure admin know what they
do.
+ When a connect must start the ruleset, if may still be preceded by set-var,
+ unset-var or comment rules.
+
Parameters :
They are optional and can be used to describe how HAProxy should open and
use the TCP connection.
@@ -9991,6 +10000,50 @@
"tcp-check send", tune.chksize
+tcp-check set-var(<var-name>) <expr>
+
+ This operation sets the content of a variable. The variable is declared inline.
+
+ May be used in sections: defaults | frontend | listen | backend
+ no | no | yes | yes
+
+ Arguments:
+ <var-name> The name of the variable starts with an indication about its
+ scope. The scopes allowed for tcp-check are:
+ "proc" : the variable is shared with the whole process.
+ "sess" : the variable is shared with the tcp-check session.
+ "check": the variable is declared for the lifetime of the tcp-check.
+ This prefix is followed by a name. The separator is a '.'.
+ The name may only contain characters 'a-z', 'A-Z', '0-9', '.',
+ and '-'.
+
+ <expr> Is a sample-fetch expression potentially followed by converters.
+
+ Example:
+ tcp-check set-var(check.port) int(1234)
+
+
+tcp-check unset-var(<var-name>)
+
+ Free a reference to a variable within its scope.
+
+ May be used in sections: defaults | frontend | listen | backend
+ no | no | yes | yes
+
+ Arguments:
+ <var-name> The name of the variable starts with an indication about its
+ scope. The scopes allowed for tcp-check are:
+ "proc" : the variable is shared with the whole process.
+ "sess" : the variable is shared with the tcp-check session.
+ "check": the variable is declared for the lifetime of the tcp-check.
+ This prefix is followed by a name. The separator is a '.'.
+ The name may only contain characters 'a-z', 'A-Z', '0-9', '.',
+ and '-'.
+
+ Example:
+ tcp-check unset-var(check.port)
+
+
tcp-request connection <action> [{if | unless} <condition>]
Perform an action on an incoming connection depending on a layer 4 condition
May be used in sections : defaults | frontend | listen | backend
diff --git a/src/checks.c b/src/checks.c
index 5e147b8..b9fb4d5 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -3042,8 +3042,7 @@
}
/* Evaluate a TCPCHK_ACT_EXPECT rule. It returns 1 to evaluate the next rule, 0
- * to wait and -1 to stop the check. <rule> is updated to point on the last
- * evaluated TCPCHK_ACT_EXPECT rule.
+ * to wait and -1 to stop the check.
*/
static enum tcpcheck_eval_ret tcpcheck_eval_expect(struct check *check, struct tcpcheck_rule *rule, int last_read)
{
@@ -3167,6 +3166,27 @@
return ret;
}
+/* Evaluate a TCPCHK_ACT_ACTION_KW rule. It returns 1 to evaluate the next rule, 0
+ * to wait and -1 to stop the check.
+ */
+static enum tcpcheck_eval_ret tcpcheck_eval_action_kw(struct check *check, struct tcpcheck_rule *rule)
+{
+ enum tcpcheck_eval_ret ret = TCPCHK_EVAL_CONTINUE;
+ struct act_rule *act_rule;
+ enum act_return act_ret;
+
+ act_rule =rule->action_kw.rule;
+ act_ret = act_rule->action_ptr(act_rule, check->proxy, check->sess, NULL, 0);
+ if (act_ret != ACT_RET_CONT) {
+ chunk_printf(&trash, "TCPCHK ACTION unexpected result at step %d\n",
+ tcpcheck_get_step_id(check, rule));
+ set_server_check_status(check, HCHK_STATUS_L7RSP, trash.area);
+ ret = TCPCHK_EVAL_STOP;
+ }
+
+ return ret;
+}
+
/* proceed with next steps for the TCP checks <check>. Note that this is called
* both from the connection's wake() callback and from the check scheduling task.
* It returns 0 on normal cases, or <0 if a close() has happened on an existing
@@ -3308,12 +3328,17 @@
}
must_read = 0;
}
+
eval_ret = tcpcheck_eval_expect(check, rule, last_read);
if (eval_ret == TCPCHK_EVAL_WAIT) {
check->current_step = rule->expect.head;
conn->mux->subscribe(cs, SUB_RETRY_RECV, &check->wait_list);
}
break;
+ case TCPCHK_ACT_ACTION_KW:
+ /* Don't update the current step */
+ eval_ret = tcpcheck_eval_action_kw(check, rule);
+ break;
default:
/* Otherwise, just go to the next one and don't update
* the current step
@@ -3588,7 +3613,7 @@
tcpcheck->expect.head = prev_check;
continue;
}
- if (prev_check->action != TCPCHK_ACT_COMMENT)
+ if (prev_check->action != TCPCHK_ACT_COMMENT && prev_check->action != TCPCHK_ACT_ACTION_KW)
break;
}
LIST_ADDQ(list, &tcpcheck->list);
@@ -4368,7 +4393,7 @@
chk->expect.head = prev_check;
continue;
}
- if (prev_check->action != TCPCHK_ACT_COMMENT)
+ if (prev_check->action != TCPCHK_ACT_COMMENT && prev_check->action != TCPCHK_ACT_ACTION_KW)
break;
}
return chk;
diff --git a/src/vars.c b/src/vars.c
index 7f3d2d0..0fa3397 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -671,6 +671,7 @@
case ACT_F_TCP_RES_CNT: dir = SMP_OPT_DIR_RES; break;
case ACT_F_HTTP_REQ: dir = SMP_OPT_DIR_REQ; break;
case ACT_F_HTTP_RES: dir = SMP_OPT_DIR_RES; break;
+ case ACT_F_TCP_CHK: dir = SMP_OPT_DIR_REQ; break;
default:
send_log(px, LOG_ERR, "Vars: internal error while execute action store.");
if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))