From: Willy Tarreau Date: Tue, 6 Jul 2021 06:29:20 +0000 (+0200) Subject: BUG/MEDIUM: sock: make sure to never miss early connection failures X-Git-Tag: v2.5-dev2~42 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=5a9c637bf3f9daf595d5a5cd0e98961d6fdc4b1b;p=haproxy-2.5.git BUG/MEDIUM: sock: make sure to never miss early connection failures 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. --- diff --git a/src/sock.c b/src/sock.c index 14b15a3..a1e545f 100644 --- a/src/sock.c +++ b/src/sock.c @@ -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 :