MINOR: checks: Don't use a static tcp rule list head

To allow reusing these blocks without consuming more memory, their list
should be static and share-able accross uses. The head of the list will
be shared as well.

It is thus necessary to extract the head of the rule list from the proxy
itself. Transform it into a pointer instead, that can be easily set to
an external dynamically allocated head.
This commit is contained in:
Gaetan Rivet 2020-02-07 15:37:17 +01:00 committed by Christopher Faulet
parent 9dcb09fc98
commit 04578dbf37
6 changed files with 45 additions and 16 deletions

View File

@ -422,7 +422,7 @@ struct proxy {
struct stktable *table; /* table for storing sticking streams */
struct task *task; /* the associated task, mandatory to manage rate limiting, stopping and resource shortage, NULL if disabled */
struct list tcpcheck_rules; /* tcp-check send / expect rules */
struct list *tcpcheck_rules; /* tcp-check send / expect rules */
int grace; /* grace time after stop request */
int check_len; /* Length of the HTTP or SSL3 request */
char *check_req; /* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */

View File

@ -352,6 +352,16 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
}
curproxy->check_body_len = defproxy.check_body_len;
if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_TCPCHK_CHK) {
curproxy->tcpcheck_rules = calloc(1, sizeof(*curproxy->tcpcheck_rules));
if (!curproxy->tcpcheck_rules) {
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
LIST_INIT(curproxy->tcpcheck_rules);
}
if (defproxy.expect_str) {
curproxy->expect_str = strdup(defproxy.expect_str);
if (defproxy.expect_regex) {
@ -2712,6 +2722,16 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
err_code |= ERR_WARN;
if ((curproxy != &defproxy) && !curproxy->tcpcheck_rules) {
curproxy->tcpcheck_rules = calloc(1, sizeof(*curproxy->tcpcheck_rules));
if (!curproxy->tcpcheck_rules) {
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
LIST_INIT(curproxy->tcpcheck_rules);
}
free(curproxy->check_req);
curproxy->check_req = NULL;
curproxy->options2 &= ~PR_O2_CHK_ANY;
@ -3075,6 +3095,16 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
goto out;
}
if (curproxy->tcpcheck_rules == NULL) {
curproxy->tcpcheck_rules = calloc(1, sizeof(*curproxy->tcpcheck_rules));
if (curproxy->tcpcheck_rules == NULL) {
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
LIST_INIT(curproxy->tcpcheck_rules);
}
if (strcmp(args[1], "comment") == 0) {
int cur_arg;
struct tcpcheck_rule *tcpcheck;
@ -3092,7 +3122,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
tcpcheck->comment = strdup(args[cur_arg + 1]);
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
LIST_ADDQ(curproxy->tcpcheck_rules, &tcpcheck->list);
if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
goto out;
}
@ -3102,13 +3132,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
struct tcpcheck_rule *tcpcheck;
/* check if first rule is also a 'connect' action */
tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
tcpcheck = LIST_NEXT(curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
while (&tcpcheck->list != curproxy->tcpcheck_rules &&
tcpcheck->action == TCPCHK_ACT_COMMENT) {
tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
}
if (&tcpcheck->list != &curproxy->tcpcheck_rules
if (&tcpcheck->list != curproxy->tcpcheck_rules
&& tcpcheck->action != TCPCHK_ACT_CONNECT) {
ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
file, linenum);
@ -3174,7 +3204,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
}
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
LIST_ADDQ(curproxy->tcpcheck_rules, &tcpcheck->list);
}
else if (strcmp(args[1], "send") == 0) {
if (! *(args[2]) ) {
@ -3203,7 +3233,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
tcpcheck->comment = strdup(args[4]);
}
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
LIST_ADDQ(curproxy->tcpcheck_rules, &tcpcheck->list);
}
}
else if (strcmp(args[1], "send-binary") == 0) {
@ -3238,7 +3268,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
tcpcheck->comment = strdup(args[4]);
}
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
LIST_ADDQ(curproxy->tcpcheck_rules, &tcpcheck->list);
}
}
else if (strcmp(args[1], "expect") == 0) {
@ -3389,7 +3419,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
* in a chain of one or more expect rule, potentially itself.
*/
tcpcheck->expect.head = tcpcheck;
list_for_each_entry_rev(prev_check, &curproxy->tcpcheck_rules, list) {
list_for_each_entry_rev(prev_check, curproxy->tcpcheck_rules, list) {
if (prev_check->action == TCPCHK_ACT_EXPECT) {
if (prev_check->expect.inverse)
tcpcheck->expect.head = prev_check;
@ -3398,7 +3428,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
if (prev_check->action != TCPCHK_ACT_COMMENT)
break;
}
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
LIST_ADDQ(curproxy->tcpcheck_rules, &tcpcheck->list);
}
else {
ha_alert("parsing [%s:%d] : '%s' only supports 'comment', 'connect', 'send' or 'expect'.\n", file, linenum, args[0]);

View File

@ -3133,7 +3133,7 @@ int check_config_validity()
memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
}
if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
if (curproxy->tcpcheck_rules != NULL &&
(curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
proxy_type_str(curproxy), curproxy->id);

View File

@ -3804,7 +3804,7 @@ static int init_srv_check(struct server *srv)
(!is_inet_addr(&srv->check.addr) && (is_addr(&srv->check.addr) || !is_inet_addr(&srv->addr))))
goto init;
if (!LIST_ISEMPTY(&srv->proxy->tcpcheck_rules)) {
if (!srv->proxy->tcpcheck_rules || LIST_ISEMPTY(srv->proxy->tcpcheck_rules)) {
ha_alert("config: %s '%s': server '%s' has neither service port nor check port.\n",
proxy_type_str(srv->proxy), srv->proxy->id, srv->id);
ret |= ERR_ALERT | ERR_ABORT;
@ -3812,7 +3812,7 @@ static int init_srv_check(struct server *srv)
}
/* search the first action (connect / send / expect) in the list */
r = get_first_tcpcheck_rule(&srv->proxy->tcpcheck_rules);
r = get_first_tcpcheck_rule(srv->proxy->tcpcheck_rules);
if (!r || (r->action != TCPCHK_ACT_CONNECT) || !r->port) {
ha_alert("config: %s '%s': server '%s' has neither service port nor check port "
"nor tcp_check rule 'connect' with port information.\n",
@ -3822,7 +3822,7 @@ static int init_srv_check(struct server *srv)
}
/* scan the tcp-check ruleset to ensure a port has been configured */
list_for_each_entry(r, &srv->proxy->tcpcheck_rules, list) {
list_for_each_entry(r, srv->proxy->tcpcheck_rules, list) {
if ((r->action == TCPCHK_ACT_CONNECT) && (!r->port)) {
ha_alert("config: %s '%s': server '%s' has neither service port nor check port, "
"and a tcp_check rule 'connect' with no port information.\n",

View File

@ -876,7 +876,6 @@ void init_new_proxy(struct proxy *p)
LIST_INIT(&p->conf.listeners);
LIST_INIT(&p->conf.errors);
LIST_INIT(&p->conf.args.list);
LIST_INIT(&p->tcpcheck_rules);
LIST_INIT(&p->filter_configs);
/* Timeouts are defined as -1 */

View File

@ -1867,7 +1867,7 @@ struct server *new_server(struct proxy *proxy)
srv->check.status = HCHK_STATUS_INI;
srv->check.server = srv;
srv->check.proxy = proxy;
srv->check.tcpcheck_rules = &proxy->tcpcheck_rules;
srv->check.tcpcheck_rules = proxy->tcpcheck_rules;
srv->agent.status = HCHK_STATUS_INI;
srv->agent.server = srv;