]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: sock: make sure to never miss early connection failures
authorWilly Tarreau <w@1wt.eu>
Tue, 6 Jul 2021 06:29:20 +0000 (08:29 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 6 Jul 2021 08:52:19 +0000 (10:52 +0200)
As shown in issue #1251, it is possible for a connect() to report an
error directly via the poller without ever reporting send readiness,
but currentlt sock_conn_check() manages to ignore that situation,
leading to high CPU usage as poll() wakes up on these FDs.

The bug was apparently introduced in 1.5-dev22 with commit fd803bb4d
("MEDIUM: connection: add check for readiness in I/O handlers"), but
was likely only woken up by recent changes to conn_fd_handler() that
made use of wakeups instead of direct calls between 1.8 and 1.9,
voiding any chance to catch such errors in the early recv() callback.

The exact sequence that leads to this situation remains obscure though
because the poller does not report send readiness nor does it report an
error. Only HUP and IN are reported on the FD. It is also possible that
some recent kernel updates made this condition appear while it never
used to previously.

This needs to be backported to all stable branches, at least as far
as 2.0. Before 2.2 the code was in tcp_connect_probe() in proto_tcp.c.

src/sock.c

index 14b15a39e4e4854e0cff216f07e0ad1ed2c54979..a1e545f9b684ab35f7b7d77211e0288acf05fe04 100644 (file)
@@ -667,7 +667,7 @@ int sock_conn_check(struct connection *conn)
        if (!(conn->flags & CO_FL_WAIT_L4_CONN))
                return 1; /* strange we were called while ready */
 
-       if (!fd_send_ready(fd))
+       if (!fd_send_ready(fd) && !(fdtab[fd].state & (FD_POLL_ERR|FD_POLL_HUP)))
                return 0;
 
        /* Here we have 2 cases :