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

Signed-off-by: Simon Horman <ho...@verge.net.au>

---

v7
* Use connect_chk() as the name of the new function
* Manual rebase
  - Add SN_ERR_UP return value to connect_chk()
    to handle the case where the task should be returned
    by process_chk() without further processing

Notes by Willy on v6:
    I'd rather call it connect_chk() since we already use the verb
    "connect" at other places for the same purpose

v4
* Use check->type in establish_conn_chk()

  Use check->type instead of s->proxy->options2 & PR_O2_CHK_ANY
  as the former is specific to the check being processed whereas
  the latter relates only to the primary check of a server.

v2 - v3
* No change
---
 src/checks.c | 185 ++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 101 insertions(+), 84 deletions(-)

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 @@ static struct task *server_warmup(struct task *t)
 }
 
 /*
+ * 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 @@ static struct task *process_chk(struct task *t)
        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 @@ static struct task *process_chk(struct task *t)
                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
-- 
2.0.0.rc2


Reply via email to