]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: checks: Don't use a static tcp rule list head
authorGaetan Rivet <grive@u256.net>
Fri, 7 Feb 2020 14:37:17 +0000 (15:37 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Apr 2020 07:39:37 +0000 (09:39 +0200)
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.

include/types/proxy.h
src/cfgparse-listen.c
src/cfgparse.c
src/checks.c
src/proxy.c
src/server.c

index 9666909e56bfc3388ef8fb2e333c092d31baddd5..36eb515cca3a68e74b9963f315da041d3b163eb5 100644 (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 */
index 06ed3e449e2dc18e189815a21c49bf0cf29315c7..e922c09baf519ef98abb30cbaa048432ad3afa5a 100644 (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 @@ stats_error_parsing:
                        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 @@ stats_error_parsing:
                        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 @@ stats_error_parsing:
 
                        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 @@ stats_error_parsing:
                        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 @@ stats_error_parsing:
 
                        }
 
-                       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 @@ stats_error_parsing:
                                        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 @@ stats_error_parsing:
                                        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 @@ stats_error_parsing:
                         * 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 @@ stats_error_parsing:
                                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]);
index d049899b34d9b0226095a602727fc6ccfb27b1b6..139103399b91f8e62f91edcf5f7831e8ed47f48e 100644 (file)
@@ -3133,7 +3133,7 @@ out_uri_auth_compat:
                        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);
index b2fb34d0ff5f53d8a8e5b12d50b7edb153df8e9c..bb1a5041c4b92f3200eb969eca0575c564d759f2 100644 (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",
index 046b1b555a2342a3947df20c5c76e1e8447ffd5a..d2d6a43d607cd1fe9e27a1c1debfe8460f27be94 100644 (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 */
index 8307ae2ca21b3a7054695049381ed5dd72c042e1..e5652f26b0affff73d3a29c7ca4fecd9edf9d316 100644 (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;