MEDIUM: Break out check establishment into connect_chk()

This is in preparation for adding a new type of check that
uses a process rather than a socket.

Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/src/checks.c b/src/checks.c
index e54e46a..6b501de 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1351,6 +1351,104 @@
 }
 
 /*
+ * establish a server health-check.
+ *
+ * It can return one of :
+ *  - SN_ERR_NONE if everything's OK and tcpcheck_main() was not called
+ *  - SN_ERR_UP if if everything's OK and tcpcheck_main() was called
+ *  - SN_ERR_SRVTO if there are no more servers
+ *  - SN_ERR_SRVCL if the connection was refused by the server
+ *  - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
+ *  - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
+ *  - SN_ERR_INTERNAL for any other purely internal errors
+ * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
+ * Note that we try to prevent the network stack from sending the ACK during the
+ * connect() when a pure TCP check is used (without PROXY protocol).
+ */
+static int connect_chk(struct task *t)
+{
+	struct check *check = t->context;
+	struct server *s = check->server;
+	struct connection *conn = check->conn;
+	struct protocol *proto;
+	int ret;
+
+	/* tcpcheck send/expect initialisation */
+	if (check->type == PR_O2_TCPCHK_CHK)
+		check->current_step = NULL;
+
+	/* prepare the check buffer.
+	 * This should not be used if check is the secondary agent check
+	 * of a server as s->proxy->check_req will relate to the
+	 * configuration of the primary check. Similarly, tcp-check uses
+	 * its own strings.
+	 */
+	if (check->type && check->type != PR_O2_TCPCHK_CHK && !(check->state & CHK_ST_AGENT)) {
+		bo_putblk(check->bo, s->proxy->check_req, s->proxy->check_len);
+
+		/* we want to check if this host replies to HTTP or SSLv3 requests
+		 * so we'll send the request, and won't wake the checker up now.
+		 */
+		if ((check->type) == PR_O2_SSL3_CHK) {
+			/* SSL requires that we put Unix time in the request */
+			int gmt_time = htonl(date.tv_sec);
+			memcpy(check->bo->data + 11, &gmt_time, 4);
+		}
+		else if ((check->type) == PR_O2_HTTP_CHK) {
+			if (s->proxy->options2 & PR_O2_CHK_SNDST)
+				bo_putblk(check->bo, trash.str, httpchk_build_status_header(s, trash.str, trash.size));
+			bo_putstr(check->bo, "\r\n");
+			*check->bo->p = '\0'; /* to make gdb output easier to read */
+		}
+	}
+
+	/* prepare a new connection */
+	conn_init(conn);
+	conn_prepare(conn, s->check_common.proto, s->check_common.xprt);
+	conn_attach(conn, check, &check_conn_cb);
+	conn->target = &s->obj_type;
+
+	/* no client address */
+	clear_addr(&conn->addr.from);
+
+	if (is_addr(&s->check_common.addr)) {
+
+		/* we'll connect to the check addr specified on the server */
+		conn->addr.to = s->check_common.addr;
+		proto = s->check_common.proto;
+	}
+	else {
+		/* we'll connect to the addr on the server */
+		conn->addr.to = s->addr;
+		proto = s->proto;
+	}
+
+	if (check->port) {
+		set_host_port(&conn->addr.to, check->port);
+	}
+
+	if (check->type == PR_O2_TCPCHK_CHK) {
+		struct tcpcheck_rule *r = (struct tcpcheck_rule *) s->proxy->tcpcheck_rules.n;
+		/* if first step is a 'connect', then tcpcheck_main must run it */
+		if (r->action == TCPCHK_ACT_CONNECT) {
+			tcpcheck_main(conn);
+			return SN_ERR_UP;
+		}
+	}
+
+	ret = SN_ERR_INTERNAL;
+	if (proto->connect)
+		ret = proto->connect(conn, check->type, (check->type) ? 0 : 2);
+	conn->flags |= CO_FL_WAKE_DATA;
+	if (s->check.send_proxy) {
+		conn->send_proxy_ofs = 1;
+		conn->flags |= CO_FL_SEND_PROXY;
+	}
+
+	return ret;
+}
+
+/*
  * manages a server health-check. Returns
  * the time the task accepts to wait, or TIME_ETERNITY for infinity.
  */
@@ -1359,7 +1457,6 @@
 	struct check *check = t->context;
 	struct server *s = check->server;
 	struct connection *conn = check->conn;
-	struct protocol *proto;
 	int rv;
 	int ret;
 	int expired = tick_is_expired(t->expire, now_ms);
@@ -1386,90 +1483,10 @@
 		check->bo->p = check->bo->data;
 		check->bo->o = 0;
 
-		/* tcpcheck send/expect initialisation */
-		if (check->type == PR_O2_TCPCHK_CHK)
-			check->current_step = NULL;
-
-		/* prepare the check buffer.
-		 * This should not be used if check is the secondary agent check
-		 * of a server as s->proxy->check_req will relate to the
-		 * configuration of the primary check. Similarly, tcp-check uses
-		 * its own strings.
-		 */
-		if (check->type && check->type != PR_O2_TCPCHK_CHK && !(check->state & CHK_ST_AGENT)) {
-			bo_putblk(check->bo, s->proxy->check_req, s->proxy->check_len);
-
-			/* we want to check if this host replies to HTTP or SSLv3 requests
-			 * so we'll send the request, and won't wake the checker up now.
-			 */
-			if ((check->type) == PR_O2_SSL3_CHK) {
-				/* SSL requires that we put Unix time in the request */
-				int gmt_time = htonl(date.tv_sec);
-				memcpy(check->bo->data + 11, &gmt_time, 4);
-			}
-			else if ((check->type) == PR_O2_HTTP_CHK) {
-				if (s->proxy->options2 & PR_O2_CHK_SNDST)
-					bo_putblk(check->bo, trash.str, httpchk_build_status_header(s, trash.str, trash.size));
-				bo_putstr(check->bo, "\r\n");
-				*check->bo->p = '\0'; /* to make gdb output easier to read */
-			}
-		}
-
-		/* prepare a new connection */
-		conn_init(conn);
-		conn_prepare(conn, s->check_common.proto, s->check_common.xprt);
-		conn_attach(conn, check, &check_conn_cb);
-		conn->target = &s->obj_type;
-
-		/* no client address */
-		clear_addr(&conn->addr.from);
-
-		if (is_addr(&s->check_common.addr)) {
-			/* we'll connect to the check addr specified on the server */
-			conn->addr.to = s->check_common.addr;
-			proto = s->check_common.proto;
-		}
-		else {
-			/* we'll connect to the addr on the server */
-			conn->addr.to = s->addr;
-			proto = s->proto;
-		}
-
-		if (check->port) {
-			set_host_port(&conn->addr.to, check->port);
-		}
-
-		if (check->type == PR_O2_TCPCHK_CHK) {
-			struct tcpcheck_rule *r = (struct tcpcheck_rule *) s->proxy->tcpcheck_rules.n;
-			/* if first step is a 'connect', then tcpcheck_main must run it */
-			if (r->action == TCPCHK_ACT_CONNECT) {
-				tcpcheck_main(conn);
-				return t;
-			}
-		}
-
-
-		/* It can return one of :
-		 *  - SN_ERR_NONE if everything's OK
-		 *  - SN_ERR_SRVTO if there are no more servers
-		 *  - SN_ERR_SRVCL if the connection was refused by the server
-		 *  - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
-		 *  - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
-		 *  - SN_ERR_INTERNAL for any other purely internal errors
-		 * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
-		 * Note that we try to prevent the network stack from sending the ACK during the
-		 * connect() when a pure TCP check is used (without PROXY protocol).
-		 */
-		ret = SN_ERR_INTERNAL;
-		if (proto->connect)
-			ret = proto->connect(conn, check->type, (check->type) ? 0 : 2);
-		conn->flags |= CO_FL_WAKE_DATA;
-		if (s->check.send_proxy) {
-			conn->send_proxy_ofs = 1;
-			conn->flags |= CO_FL_SEND_PROXY;
-		}
-
+		ret = connect_chk(t);
 		switch (ret) {
+		case SN_ERR_UP:
+			return t;
 		case SN_ERR_NONE:
 			/* we allow up to min(inter, timeout.connect) for a connection
 			 * to establish but only when timeout.check is set