]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: check: Set SOCKERR by default when a connection error is reported
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 16 Jun 2025 14:33:04 +0000 (16:33 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 16 Jun 2025 15:47:35 +0000 (17:47 +0200)
When a connection error is reported, we try to collect as much information
as possible on the connection status and the server status is adjusted
accordingly. However, the function does nothing if there is no connection
error and if the healthcheck is not expired yet. It is a problem when an
internal error occurred. It may happen at many places and it is hard to be
sure an error is reported on the connection. And in fact, it is already a
problem when the multiplexer allocation fails. In that case, the healthcheck
is not interrupted as it should be. Concretely, it could only happen when a
connection is established.

It is hard to predict the effects of this bug. It may be unimportant. But it
could probably lead to a crash. To avoid any issue, a SOCKERR status is now
set by default when a connection error is reported. There is no reason to
report a connection error for nothing. So a healthcheck failure must be
reported. There is no "internal error" status. So a socket error is
reported.

This patch must be backport to all stable versions.

src/check.c

index fa2e68f1341079f143ea1c8a9f418f85bbe94dd0..f202131675c59ef15b7bf9465dacdb3c922d9f08 100644 (file)
@@ -825,9 +825,6 @@ void chk_report_conn_err(struct check *check, int errno_bck, int expired)
        if (conn && errno)
                retrieve_errno_from_socket(conn);
 
-       if (conn && !(conn->flags & CO_FL_ERROR) && !sc_ep_test(sc, SE_FL_ERROR) && !expired)
-               return;
-
        TRACE_ENTER(CHK_EV_HCHK_END|CHK_EV_HCHK_ERR, check, 0, 0, (size_t[]){expired});
 
        /* we'll try to build a meaningful error message depending on the
@@ -980,6 +977,11 @@ void chk_report_conn_err(struct check *check, int errno_bck, int expired)
                set_server_check_status(check, tout, err_msg);
        }
 
+       if (check->result == CHK_RES_UNKNOWN) {
+               /* No other reason found, report a socket error (may be an internal or a ressournce error) */
+               set_server_check_status(check, HCHK_STATUS_SOCKERR, err_msg);
+       }
+
        TRACE_LEAVE(CHK_EV_HCHK_END|CHK_EV_HCHK_ERR, check);
        return;
 }