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.
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 9666909..36eb515 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -422,7 +422,7 @@
 	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 */
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index 06ed3e4..e922c09 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -352,6 +352,16 @@
 			}
 			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 @@
 			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 @@
 			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 @@
 
 			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 @@
 			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 @@
 
 			}
 
-			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 @@
 					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 @@
 					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 @@
 			 * 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 @@
 				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]);
diff --git a/src/cfgparse.c b/src/cfgparse.c
index d049899..1391033 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3133,7 +3133,7 @@
 			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);
diff --git a/src/checks.c b/src/checks.c
index b2fb34d..bb1a504 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -3804,7 +3804,7 @@
 	    (!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 @@
 	}
 
 	/* 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 @@
 	}
 
 	/* 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",
diff --git a/src/proxy.c b/src/proxy.c
index 046b1b5..d2d6a43 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -876,7 +876,6 @@
 	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 */
diff --git a/src/server.c b/src/server.c
index 8307ae2..e5652f2 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1867,7 +1867,7 @@
 	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;