]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: connections: Always call shutdown, with no linger.
authorOlivier Houchard <ohouchard@haproxy.com>
Tue, 2 Jul 2019 14:35:18 +0000 (16:35 +0200)
committerOlivier Houchard <cognet@ci0.org>
Tue, 2 Jul 2019 14:40:55 +0000 (16:40 +0200)
Revert commit fe4abe62c7c5206dff1802f42d17014e198b9141.
The goal was to make sure for health-checks, we would not get sockets in
TIME_WAIT. To do so, we would not call shutdown() if linger_risk is set.
However that is wrong, and that means shutw would never be forwarded to
the server, and thus we could get connection that are never properly closed.
Instead, to fix the original problem as described here :
https://www.mail-archive.com/haproxy@formilux.org/msg34080.html
Just make sure the checks code call cs_shutr() before calling cs_shutw().
If shutr has been called, conn_sock_shutw() will make no attempt to call
shutdown(), as it knows close() will be called.
We should really review and revamp the shutr/shutw code, as described in
github issue #142.

This should be backported to 1.9 and 2.0.

include/proto/connection.h
src/checks.c

index 1e5fc9c9e641a28c70fed3896483efd387e5ec8d..115e7aaa3bc9a03b993b23d8363bc51d6a246387 100644 (file)
@@ -352,8 +352,7 @@ static inline void conn_sock_shutw(struct connection *c, int clean)
        /* don't perform a clean shutdown if we're going to reset or
         * if the shutr was already received.
         */
-       if (conn_ctrl_ready(c) && !(c->flags & CO_FL_SOCK_RD_SH) && clean &&
-           !fdtab[c->handle.fd].linger_risk)
+       if (conn_ctrl_ready(c) && !(c->flags & CO_FL_SOCK_RD_SH) && clean)
                shutdown(c->handle.fd, SHUT_WR);
 }
 
index e31eb1735935d3eaf7c5af95b3efe93b22435b91..68da2a3766f641d7e35ad564f20155bad802d236 100644 (file)
@@ -1382,6 +1382,11 @@ static void __event_srv_chk_r(struct conn_stream *cs)
         * range quickly.  To avoid sending RSTs all the time, we first try to
         * drain pending data.
         */
+       /* Call cs_shutr() first, to add the CO_FL_SOCK_RD_SH flag on the
+        * connection, to make sure cs_shutw() will not lead to a shutdown()
+        * that would provoke TIME_WAITs.
+        */
+       cs_shutr(cs, CS_SHR_DRAIN);
        cs_shutw(cs, CS_SHW_NORMAL);
 
        /* OK, let's not stay here forever */