]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: checks: Subscribe to I/O events on an unfinished connect
authorChristopher Faulet <cfaulet@haproxy.com>
Sat, 9 May 2020 12:46:43 +0000 (14:46 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 12 May 2020 08:06:47 +0000 (10:06 +0200)
In tcp-check based health check, when a new connection is opened, we must wait
it is really established before moving to the next rule. But at this stage, we
must also be sure to subscribe to I/O events. Otherwise, depending on the
timing, the health check may remains sleepy till the timeout.

No backport needed. This patch should fix the issue #622.

(cherry picked from commit b2a4c0d473e3c5dcb87f7d16f2ca410bafc62f64)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
src/checks.c

index 0fefdc531614dfcbb1afc31ab8fc77fc7e702c6f..2e6ffc0b7e03d6b1f07fb6f8a7d96e69c3dd8581 100644 (file)
@@ -1679,6 +1679,7 @@ static enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct
        struct connection *conn = NULL;
        struct protocol *proto;
        struct xprt_ops *xprt;
+       struct tcpcheck_rule *next;
        int status, port;
 
        /* For a connect action we'll create a new connection. We may also have
@@ -1772,14 +1773,12 @@ static enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct
        cs_attach(cs, check, &check_conn_cb);
 
        status = SF_ERR_INTERNAL;
+       next = get_next_tcpcheck_rule(check->tcpcheck_rules, rule);
        if (proto && proto->connect) {
-               struct tcpcheck_rule *next;
                int flags = 0;
 
                if (check->tcpcheck_rules->flags & TCPCHK_RULES_PROTO_CHK)
                        flags |= CONNECT_HAS_DATA;
-
-               next = get_next_tcpcheck_rule(check->tcpcheck_rules, rule);
                if (!next || next->action != TCPCHK_ACT_EXPECT)
                        flags |= CONNECT_DELACK_ALWAYS;
                status = proto->connect(conn, flags);
@@ -1892,6 +1891,10 @@ static enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct
 
        /* don't do anything until the connection is established */
        if (conn->flags & CO_FL_WAIT_XPRT) {
+               if (next && next->action == TCPCHK_ACT_SEND)
+                       conn->mux->subscribe(cs, SUB_RETRY_SEND, &check->wait_list);
+               else
+                       conn->mux->subscribe(cs, SUB_RETRY_RECV, &check->wait_list);
                ret = TCPCHK_EVAL_WAIT;
                goto out;
        }