From: Willy Tarreau Date: Fri, 23 Nov 2012 07:51:32 +0000 (+0100) Subject: BUG/MEDIUM: checks: mark the check as stopped after a connect error X-Git-Tag: v1.5-dev14~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b0a8505035a8df7587c7867b75c0bd4a55eae1f;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: checks: mark the check as stopped after a connect error Health checks currently still use the connection's fd to know whether a check is running (this needs to change). When a health check immediately fails during connect() because of a lack of local resource (eg: port), we failed to unset the fd, so each time the process_chk woken up after such an error, it believed a check was still running and used to close the fd again instead of starting a new check. This could result in other connections being closed because they were assigned the same fd value. The bug is only marked medium because when this happens, the system is already in a bad state. A comment was added above tcp_connect_server() to clarify that the fd is *not* valid on error. --- diff --git a/src/checks.c b/src/checks.c index f13273ed44..7f8311a2b6 100644 --- a/src/checks.c +++ b/src/checks.c @@ -1359,6 +1359,8 @@ static struct task *process_chk(struct task *t) } /* here, we have seen a failure */ + + conn->t.sock.fd = -1; /* report that no check is running anymore */ if (s->health > s->rise) { s->health--; /* still good */ s->counters.failed_checks++; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index e744c76759..c8f4768e01 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -233,6 +233,9 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so * - 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. + * + * The connection's fd is inserted only when SN_ERR_NONE is returned, otherwise + * it's invalid and the caller has nothing to do. */ int tcp_connect_server(struct connection *conn, int data)