MEDIUM: checks: Implement agent check using tcp-check rules
A shared tcp-check ruleset is now created to support agent checks. The following
sequence is used :
tcp-check send "%[var(check.agent_string)] log-format
tcp-check expect custom
The custom function to evaluate the expect rule does the same that it was done
to handle agent response when a custom check was used.
diff --git a/include/proto/checks.h b/include/proto/checks.h
index 669c620..4dba34a 100644
--- a/include/proto/checks.h
+++ b/include/proto/checks.h
@@ -84,6 +84,8 @@
int proxy_parse_spop_check_opt(char **args, int cur_arg, struct proxy *curpx, struct proxy *defpx,
const char *file, int line);
+int set_srv_agent_send(struct server *srv, const char *send);
+
#endif /* _PROTO_CHECKS_H */
/*
diff --git a/include/types/checks.h b/include/types/checks.h
index d3da5f2..d828331 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -180,8 +180,6 @@
* rise to rise+fall-1 = good */
int rise, fall; /* time in iterations */
int type; /* Check type, one of PR_O2_*_CHK */
- int send_string_len; /* length of agent command string */
- char *send_string; /* optionally send a string when connecting to the agent */
struct server *server; /* back-pointer to server */
struct proxy *proxy; /* proxy to be used */
char **argv; /* the arguments to use if running a process-based check */
@@ -318,6 +316,7 @@
#define TCPCHK_RULES_MYSQL_CHK 0x00000050
#define TCPCHK_RULES_LDAP_CHK 0x00000060
#define TCPCHK_RULES_SSL3_CHK 0x00000070
+#define TCPCHK_RULES_AGENT_CHK 0x00000080
#define TCPCHK_RULES_SPOP_CHK 0x00000090
/* A list of tcp-check vars, to be registered before executing a ruleset */
diff --git a/include/types/proxy.h b/include/types/proxy.h
index e13c63c..f9fe7c5 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -171,8 +171,7 @@
#define PR_O2_CHK_NONE 0x00000000 /* no L7 health checks configured (TCP by default) */
/* unused: 0x10000000..0x30000000 */
#define PR_O2_HTTP_CHK 0x40000000 /* use HTTP 'OPTIONS' method to check server health */
-/* unused 0x50000000..0x70000000 */
-#define PR_O2_LB_AGENT_CHK 0x80000000 /* use a TCP connection to obtain a metric of server health */
+/* unused 0x50000000..0x80000000 */
#define PR_O2_TCPCHK_CHK 0x90000000 /* use TCPCHK check for server health */
#define PR_O2_EXT_CHK 0xA0000000 /* use external command for server health */
/* unused: 0xB0000000 to 0xF000000, reserved for health checks */
diff --git a/src/checks.c b/src/checks.c
index 94454bb..2ffa194 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -948,213 +948,6 @@
}
break;
- case PR_O2_LB_AGENT_CHK: {
- int status = HCHK_STATUS_CHECKED;
- const char *hs = NULL; /* health status */
- const char *as = NULL; /* admin status */
- const char *ps = NULL; /* performance status */
- const char *cs = NULL; /* maxconn */
- const char *err = NULL; /* first error to report */
- const char *wrn = NULL; /* first warning to report */
- char *cmd, *p;
-
- /* We're getting an agent check response. The agent could
- * have been disabled in the mean time with a long check
- * still pending. It is important that we ignore the whole
- * response.
- */
- if (!(check->server->agent.state & CHK_ST_ENABLED))
- break;
-
- /* The agent supports strings made of a single line ended by the
- * first CR ('\r') or LF ('\n'). This line is composed of words
- * delimited by spaces (' '), tabs ('\t'), or commas (','). The
- * line may optionally contained a description of a state change
- * after a sharp ('#'), which is only considered if a health state
- * is announced.
- *
- * Words may be composed of :
- * - a numeric weight suffixed by the percent character ('%').
- * - a health status among "up", "down", "stopped", and "fail".
- * - an admin status among "ready", "drain", "maint".
- *
- * These words may appear in any order. If multiple words of the
- * same category appear, the last one wins.
- */
-
- p = b_head(&check->bi);
- while (*p && *p != '\n' && *p != '\r')
- p++;
-
- if (!*p) {
- if (!done)
- goto wait_more_data;
-
- /* at least inform the admin that the agent is mis-behaving */
- set_server_check_status(check, check->status, "Ignoring incomplete line from agent");
- break;
- }
-
- *p = 0;
- cmd = b_head(&check->bi);
-
- while (*cmd) {
- /* look for next word */
- if (*cmd == ' ' || *cmd == '\t' || *cmd == ',') {
- cmd++;
- continue;
- }
-
- if (*cmd == '#') {
- /* this is the beginning of a health status description,
- * skip the sharp and blanks.
- */
- cmd++;
- while (*cmd == '\t' || *cmd == ' ')
- cmd++;
- break;
- }
-
- /* find the end of the word so that we have a null-terminated
- * word between <cmd> and <p>.
- */
- p = cmd + 1;
- while (*p && *p != '\t' && *p != ' ' && *p != '\n' && *p != ',')
- p++;
- if (*p)
- *p++ = 0;
-
- /* first, health statuses */
- if (strcasecmp(cmd, "up") == 0) {
- check->health = check->rise + check->fall - 1;
- status = HCHK_STATUS_L7OKD;
- hs = cmd;
- }
- else if (strcasecmp(cmd, "down") == 0) {
- check->health = 0;
- status = HCHK_STATUS_L7STS;
- hs = cmd;
- }
- else if (strcasecmp(cmd, "stopped") == 0) {
- check->health = 0;
- status = HCHK_STATUS_L7STS;
- hs = cmd;
- }
- else if (strcasecmp(cmd, "fail") == 0) {
- check->health = 0;
- status = HCHK_STATUS_L7STS;
- hs = cmd;
- }
- /* admin statuses */
- else if (strcasecmp(cmd, "ready") == 0) {
- as = cmd;
- }
- else if (strcasecmp(cmd, "drain") == 0) {
- as = cmd;
- }
- else if (strcasecmp(cmd, "maint") == 0) {
- as = cmd;
- }
- /* try to parse a weight here and keep the last one */
- else if (isdigit((unsigned char)*cmd) && strchr(cmd, '%') != NULL) {
- ps = cmd;
- }
- /* try to parse a maxconn here */
- else if (strncasecmp(cmd, "maxconn:", strlen("maxconn:")) == 0) {
- cs = cmd;
- }
- else {
- /* keep a copy of the first error */
- if (!err)
- err = cmd;
- }
- /* skip to next word */
- cmd = p;
- }
- /* here, cmd points either to \0 or to the beginning of a
- * description. Skip possible leading spaces.
- */
- while (*cmd == ' ' || *cmd == '\n')
- cmd++;
-
- /* First, update the admin status so that we avoid sending other
- * possibly useless warnings and can also update the health if
- * present after going back up.
- */
- if (as) {
- if (strcasecmp(as, "drain") == 0)
- srv_adm_set_drain(check->server);
- else if (strcasecmp(as, "maint") == 0)
- srv_adm_set_maint(check->server);
- else
- srv_adm_set_ready(check->server);
- }
-
- /* now change weights */
- if (ps) {
- const char *msg;
-
- msg = server_parse_weight_change_request(s, ps);
- if (!wrn || !*wrn)
- wrn = msg;
- }
-
- if (cs) {
- const char *msg;
-
- cs += strlen("maxconn:");
-
- msg = server_parse_maxconn_change_request(s, cs);
- if (!wrn || !*wrn)
- wrn = msg;
- }
-
- /* and finally health status */
- if (hs) {
- /* We'll report some of the warnings and errors we have
- * here. Down reports are critical, we leave them untouched.
- * Lack of report, or report of 'UP' leaves the room for
- * ERR first, then WARN.
- */
- const char *msg = cmd;
- struct buffer *t;
-
- if (!*msg || status == HCHK_STATUS_L7OKD) {
- if (err && *err)
- msg = err;
- else if (wrn && *wrn)
- msg = wrn;
- }
-
- t = get_trash_chunk();
- chunk_printf(t, "via agent : %s%s%s%s",
- hs, *msg ? " (" : "",
- msg, *msg ? ")" : "");
-
- set_server_check_status(check, status, t->area);
- }
- else if (err && *err) {
- /* No status change but we'd like to report something odd.
- * Just report the current state and copy the message.
- */
- chunk_printf(&trash, "agent reports an error : %s", err);
- set_server_check_status(check, status/*check->status*/,
- trash.area);
-
- }
- else if (wrn && *wrn) {
- /* No status change but we'd like to report something odd.
- * Just report the current state and copy the message.
- */
- chunk_printf(&trash, "agent warns : %s", wrn);
- set_server_check_status(check, status/*check->status*/,
- trash.area);
- }
- else
- set_server_check_status(check, status, NULL);
- break;
- }
-
default:
/* good connection is enough for pure TCP check */
if (!(conn->flags & CO_FL_WAIT_XPRT) && !check->type) {
@@ -1421,10 +1214,6 @@
}
}
- if ((check->type & PR_O2_LB_AGENT_CHK) && check->send_string_len) {
- b_putblk(&check->bo, check->send_string, check->send_string_len);
- }
-
/* for tcp-checks, the initial connection setup is handled separately as
* it may be sent to a specific port and not to the server's.
*/
@@ -2798,6 +2587,217 @@
tcpcheck_onerror_message(msg, check, rule, 0, desc);
set_server_check_status(check, status, (msg ? b_head(msg) : NULL));
goto out;
+
+ wait_more_data:
+ ret = TCPCHK_EVAL_WAIT;
+ goto out;
+}
+
+static enum tcpcheck_eval_ret tcpcheck_agent_expect_reply(struct check *check, struct tcpcheck_rule *rule, int last_read)
+{
+ enum tcpcheck_eval_ret ret = TCPCHK_EVAL_STOP;
+ enum healthcheck_status status = HCHK_STATUS_CHECKED;
+ const char *hs = NULL; /* health status */
+ const char *as = NULL; /* admin status */
+ const char *ps = NULL; /* performance status */
+ const char *cs = NULL; /* maxconn */
+ const char *err = NULL; /* first error to report */
+ const char *wrn = NULL; /* first warning to report */
+ char *cmd, *p;
+
+ /* We're getting an agent check response. The agent could
+ * have been disabled in the mean time with a long check
+ * still pending. It is important that we ignore the whole
+ * response.
+ */
+ if (!(check->state & CHK_ST_ENABLED))
+ goto out;
+
+ /* The agent supports strings made of a single line ended by the
+ * first CR ('\r') or LF ('\n'). This line is composed of words
+ * delimited by spaces (' '), tabs ('\t'), or commas (','). The
+ * line may optionally contained a description of a state change
+ * after a sharp ('#'), which is only considered if a health state
+ * is announced.
+ *
+ * Words may be composed of :
+ * - a numeric weight suffixed by the percent character ('%').
+ * - a health status among "up", "down", "stopped", and "fail".
+ * - an admin status among "ready", "drain", "maint".
+ *
+ * These words may appear in any order. If multiple words of the
+ * same category appear, the last one wins.
+ */
+
+ p = b_head(&check->bi);
+ while (*p && *p != '\n' && *p != '\r')
+ p++;
+
+ if (!*p) {
+ if (!last_read)
+ goto wait_more_data;
+
+ /* at least inform the admin that the agent is mis-behaving */
+ set_server_check_status(check, check->status, "Ignoring incomplete line from agent");
+ goto out;
+ }
+
+ *p = 0;
+ cmd = b_head(&check->bi);
+
+ while (*cmd) {
+ /* look for next word */
+ if (*cmd == ' ' || *cmd == '\t' || *cmd == ',') {
+ cmd++;
+ continue;
+ }
+
+ if (*cmd == '#') {
+ /* this is the beginning of a health status description,
+ * skip the sharp and blanks.
+ */
+ cmd++;
+ while (*cmd == '\t' || *cmd == ' ')
+ cmd++;
+ break;
+ }
+
+ /* find the end of the word so that we have a null-terminated
+ * word between <cmd> and <p>.
+ */
+ p = cmd + 1;
+ while (*p && *p != '\t' && *p != ' ' && *p != '\n' && *p != ',')
+ p++;
+ if (*p)
+ *p++ = 0;
+
+ /* first, health statuses */
+ if (strcasecmp(cmd, "up") == 0) {
+ check->server->check.health = check->server->check.rise + check->server->check.fall - 1;
+ status = HCHK_STATUS_L7OKD;
+ hs = cmd;
+ }
+ else if (strcasecmp(cmd, "down") == 0) {
+ check->server->check.health = 0;
+ status = HCHK_STATUS_L7STS;
+ hs = cmd;
+ }
+ else if (strcasecmp(cmd, "stopped") == 0) {
+ check->server->check.health = 0;
+ status = HCHK_STATUS_L7STS;
+ hs = cmd;
+ }
+ else if (strcasecmp(cmd, "fail") == 0) {
+ check->server->check.health = 0;
+ status = HCHK_STATUS_L7STS;
+ hs = cmd;
+ }
+ /* admin statuses */
+ else if (strcasecmp(cmd, "ready") == 0) {
+ as = cmd;
+ }
+ else if (strcasecmp(cmd, "drain") == 0) {
+ as = cmd;
+ }
+ else if (strcasecmp(cmd, "maint") == 0) {
+ as = cmd;
+ }
+ /* try to parse a weight here and keep the last one */
+ else if (isdigit((unsigned char)*cmd) && strchr(cmd, '%') != NULL) {
+ ps = cmd;
+ }
+ /* try to parse a maxconn here */
+ else if (strncasecmp(cmd, "maxconn:", strlen("maxconn:")) == 0) {
+ cs = cmd;
+ }
+ else {
+ /* keep a copy of the first error */
+ if (!err)
+ err = cmd;
+ }
+ /* skip to next word */
+ cmd = p;
+ }
+ /* here, cmd points either to \0 or to the beginning of a
+ * description. Skip possible leading spaces.
+ */
+ while (*cmd == ' ' || *cmd == '\n')
+ cmd++;
+
+ /* First, update the admin status so that we avoid sending other
+ * possibly useless warnings and can also update the health if
+ * present after going back up.
+ */
+ if (as) {
+ if (strcasecmp(as, "drain") == 0)
+ srv_adm_set_drain(check->server);
+ else if (strcasecmp(as, "maint") == 0)
+ srv_adm_set_maint(check->server);
+ else
+ srv_adm_set_ready(check->server);
+ }
+
+ /* now change weights */
+ if (ps) {
+ const char *msg;
+
+ msg = server_parse_weight_change_request(check->server, ps);
+ if (!wrn || !*wrn)
+ wrn = msg;
+ }
+
+ if (cs) {
+ const char *msg;
+
+ cs += strlen("maxconn:");
+
+ msg = server_parse_maxconn_change_request(check->server, cs);
+ if (!wrn || !*wrn)
+ wrn = msg;
+ }
+
+ /* and finally health status */
+ if (hs) {
+ /* We'll report some of the warnings and errors we have
+ * here. Down reports are critical, we leave them untouched.
+ * Lack of report, or report of 'UP' leaves the room for
+ * ERR first, then WARN.
+ */
+ const char *msg = cmd;
+ struct buffer *t;
+
+ if (!*msg || status == HCHK_STATUS_L7OKD) {
+ if (err && *err)
+ msg = err;
+ else if (wrn && *wrn)
+ msg = wrn;
+ }
+
+ t = get_trash_chunk();
+ chunk_printf(t, "via agent : %s%s%s%s",
+ hs, *msg ? " (" : "",
+ msg, *msg ? ")" : "");
+ set_server_check_status(check, status, t->area);
+ }
+ else if (err && *err) {
+ /* No status change but we'd like to report something odd.
+ * Just report the current state and copy the message.
+ */
+ chunk_printf(&trash, "agent reports an error : %s", err);
+ set_server_check_status(check, status/*check->status*/, trash.area);
+ }
+ else if (wrn && *wrn) {
+ /* No status change but we'd like to report something odd.
+ * Just report the current state and copy the message.
+ */
+ chunk_printf(&trash, "agent warns : %s", wrn);
+ set_server_check_status(check, status/*check->status*/, trash.area);
+ }
+ else
+ set_server_check_status(check, status, NULL);
+
+ out:
+ return ret;
wait_more_data:
ret = TCPCHK_EVAL_WAIT;
@@ -4143,13 +4143,33 @@
static int init_srv_agent_check(struct server *srv)
{
+ struct tcpcheck_rule *chk;
const char *err;
int ret = 0;
if (!srv->do_agent)
goto out;
- err = init_check(&srv->agent, PR_O2_LB_AGENT_CHK);
+ /* If there is no connect rule preceeding all send / expect rules, an
+ * implicit one is inserted before all others.
+ */
+ chk = get_first_tcpcheck_rule(srv->agent.tcpcheck_rules);
+ if (!chk || chk->action != TCPCHK_ACT_CONNECT) {
+ chk = calloc(1, sizeof(*chk));
+ if (!chk) {
+ ha_alert("config : %s '%s': unable to add implicit tcp-check connect rule"
+ " to agent-check for server '%s' (out of memory).\n",
+ proxy_type_str(srv->proxy), srv->proxy->id, srv->id);
+ ret |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ chk->action = TCPCHK_ACT_CONNECT;
+ chk->connect.options = (TCPCHK_OPT_DEFAULT_CONNECT|TCPCHK_OPT_IMPLICIT);
+ LIST_ADD(srv->agent.tcpcheck_rules->list, &chk->list);
+ }
+
+
+ err = init_check(&srv->agent, PR_O2_TCPCHK_CHK);
if (err) {
ha_alert("config: %s '%s': unable to init agent-check for server '%s' (%s).\n",
proxy_type_str(srv->proxy), srv->proxy->id, srv->id, err);
@@ -4197,9 +4217,17 @@
static void deinit_srv_agent_check(struct server *srv)
{
- if (srv->do_agent)
+ if (srv->agent.tcpcheck_rules) {
+ free_tcpcheck_vars(&srv->agent.tcpcheck_rules->preset_vars);
+ free(srv->agent.tcpcheck_rules);
+ srv->agent.tcpcheck_rules = NULL;
+ }
+
+ if (srv->agent.state & CHK_ST_CONFIGURED)
free_check(&srv->agent);
- free(srv->agent.send_string);
+
+ srv->agent.state &= ~CHK_ST_CONFIGURED & ~CHK_ST_ENABLED & ~CHK_ST_AGENT;
+ srv->do_agent = 0;
}
static void deinit_tcpchecks()
@@ -6045,8 +6073,70 @@
static int srv_parse_agent_check(char **args, int *cur_arg, struct proxy *curpx, struct server *srv,
char **errmsg)
{
+ struct tcpcheck_ruleset *rs = NULL;
+ struct tcpcheck_rules *rules = srv->agent.tcpcheck_rules;
+ struct tcpcheck_rule *chk;
+ int err_code = 0;
+
+ if (srv->do_agent)
+ goto out;
+
+ if (!rules) {
+ rules = calloc(1, sizeof(*rules));
+ if (!rules) {
+ memprintf(errmsg, "out of memory.");
+ goto error;
+ }
+ LIST_INIT(&rules->preset_vars);
+ srv->agent.tcpcheck_rules = rules;
+ }
+ rules->list = NULL;
+ rules->flags = 0;
+
+ rs = tcpcheck_ruleset_lookup("*agent-check");
+ if (rs)
+ goto ruleset_found;
+
+ rs = tcpcheck_ruleset_create("*agent-check");
+ if (rs == NULL) {
+ memprintf(errmsg, "out of memory.");
+ goto error;
+ }
+
+ chk = parse_tcpcheck_send((char *[]){"tcp-check", "send", "%[var(check.agent_string)]", "log-format", ""},
+ 1, curpx, &rs->rules, srv->conf.file, srv->conf.line, errmsg);
+ if (!chk) {
+ memprintf(errmsg, "'%s': %s", args[*cur_arg], *errmsg);
+ goto error;
+ }
+ chk->index = 0;
+ LIST_ADDQ(&rs->rules, &chk->list);
+
+ chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "custom", ""},
+ 1, curpx, &rs->rules, srv->conf.file, srv->conf.line, errmsg);
+ if (!chk) {
+ memprintf(errmsg, "'%s': %s", args[*cur_arg], *errmsg);
+ goto error;
+ }
+ chk->expect.custom = tcpcheck_agent_expect_reply;
+ chk->index = 1;
+ LIST_ADDQ(&rs->rules, &chk->list);
+
+ LIST_ADDQ(&tcpchecks_list, &rs->list);
+
+ ruleset_found:
+ rules->list = &rs->rules;
+ rules->flags |= (TCPCHK_RULES_SHARED|TCPCHK_RULES_AGENT_CHK);
srv->do_agent = 1;
+
+ out:
return 0;
+
+ error:
+ deinit_srv_agent_check(srv);
+ tcpcheck_ruleset_release(rs);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
}
/* Parse the "agent-inter" server keyword */
@@ -6115,11 +6205,38 @@
goto out;
}
+int set_srv_agent_send(struct server *srv, const char *send)
+{
+ struct tcpcheck_rules *rules = srv->agent.tcpcheck_rules;
+ struct tcpcheck_var *var = NULL;
+ char *str;
+
+ str = strdup(send);
+ var = tcpcheck_var_create("check.agent_string");
+ if (str == NULL || var == NULL)
+ goto error;
+
+ free_tcpcheck_vars(&rules->preset_vars);
+
+ var->data.type = SMP_T_STR;
+ var->data.u.str.area = str;
+ var->data.u.str.data = strlen(str);
+ LIST_INIT(&var->list);
+ LIST_ADDQ(&rules->preset_vars, &var->list);
+
+ return 1;
+
+ error:
+ free(str);
+ free(var);
+ return 0;
+}
/* Parse the "agent-send" server keyword */
static int srv_parse_agent_send(char **args, int *cur_arg, struct proxy *curpx, struct server *srv,
char **errmsg)
{
+ struct tcpcheck_rules *rules = srv->agent.tcpcheck_rules;
int err_code = 0;
if (!*(args[*cur_arg+1])) {
@@ -6127,10 +6244,17 @@
goto error;
}
- free(srv->agent.send_string);
- srv->agent.send_string_len = strlen(args[*cur_arg+1]);
- srv->agent.send_string = strdup(args[*cur_arg+1]);
- if (srv->agent.send_string == NULL) {
+ if (!rules) {
+ rules = calloc(1, sizeof(*rules));
+ if (!rules) {
+ memprintf(errmsg, "out of memory.");
+ goto error;
+ }
+ LIST_INIT(&rules->preset_vars);
+ srv->agent.tcpcheck_rules = rules;
+ }
+
+ if (!set_srv_agent_send(srv, args[*cur_arg+1])) {
memprintf(errmsg, "out of memory.");
goto error;
}
@@ -6139,6 +6263,7 @@
return err_code;
error:
+ deinit_srv_agent_check(srv);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
@@ -6147,11 +6272,7 @@
static int srv_parse_no_agent_check(char **args, int *cur_arg, struct proxy *curpx, struct server *srv,
char **errmsg)
{
- free_check(&srv->agent);
- srv->agent.inter = 0;
- srv->agent.port = 0;
- srv->agent.state &= ~CHK_ST_CONFIGURED & ~CHK_ST_ENABLED & ~CHK_ST_AGENT;
- srv->do_agent = 0;
+ deinit_srv_agent_check(srv);
return 0;
}
diff --git a/src/server.c b/src/server.c
index b369000..e3a7449 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1665,9 +1665,18 @@
srv->check.downinter = src->check.downinter;
srv->agent.use_ssl = src->agent.use_ssl;
srv->agent.port = src->agent.port;
- if (src->agent.send_string != NULL)
- srv->agent.send_string = strdup(src->agent.send_string);
- srv->agent.send_string_len = src->agent.send_string_len;
+
+ if (src->agent.tcpcheck_rules) {
+ srv->agent.tcpcheck_rules = calloc(1, sizeof(*srv->agent.tcpcheck_rules));
+ if (srv->agent.tcpcheck_rules) {
+ srv->agent.tcpcheck_rules->flags = src->agent.tcpcheck_rules->flags;
+ srv->agent.tcpcheck_rules->list = src->agent.tcpcheck_rules->list;
+ LIST_INIT(&srv->agent.tcpcheck_rules->preset_vars);
+ dup_tcpcheck_vars(&srv->agent.tcpcheck_rules->preset_vars,
+ &src->agent.tcpcheck_rules->preset_vars);
+ }
+ }
+
srv->agent.inter = src->agent.inter;
srv->agent.fastinter = src->agent.fastinter;
srv->agent.downinter = src->agent.downinter;
@@ -4300,14 +4309,8 @@
if (!(sv->agent.state & CHK_ST_ENABLED))
cli_err(appctx, "agent checks are not enabled on this server.\n");
else {
- char *nss = strdup(args[4]);
- if (!nss)
+ if (!set_srv_agent_send(sv, args[4]))
cli_err(appctx, "cannot allocate memory for new string.\n");
- else {
- free(sv->agent.send_string);
- sv->agent.send_string = nss;
- sv->agent.send_string_len = strlen(args[4]);
- }
}
}
else if (strcmp(args[3], "check-port") == 0) {