From 569769fca32d46fed13ae65319300282f50dc10f Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 21 Oct 2021 21:31:42 +0200 Subject: [PATCH] MINOR: connection: add a new CO_FL_WANT_DRAIN flag to force drain on close Sometimes we'd like to do our best to drain pending data before closing in order to save the peer from risking to receive an RST on close. This adds a new connection flag CO_FL_WANT_DRAIN that is used to trigger a call to conn_ctrl_drain() from conn_ctrl_close(), and the sock_drain() function ignores fd_recv_ready() if this flag is set, in order to catch latest data. It's not used for now. (cherry picked from commit 20b622e04b27e76f7b4be0c09b435e8799143d75) [Cf: On previous versions, conn_sock_drain() must be used instead of conn_ctrl_drain()] Signed-off-by: Christopher Faulet (cherry picked from commit b17952cec409252817d09b95a1a97ffaff895fe9) [Cf: As expected, conn_sock_drain() was used instead of conn_ctrl_drain(). Because sock_drain() does not exist on the 2.3, conn_sock_drain() was updated to do nothing when CO_FL_WANT_DRAIN flag is not set] Signed-off-by: Christopher Faulet --- include/haproxy/connection-t.h | 2 +- include/haproxy/connection.h | 2 ++ src/connection.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 401d756..f0810de 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -127,7 +127,7 @@ enum { CO_FL_CTRL_READY = 0x00000100, /* FD was registered, fd_delete() needed */ CO_FL_XPRT_READY = 0x00000200, /* xprt_init() done, xprt_close() needed */ - /* unused : 0x00000400 */ + CO_FL_WANT_DRAIN = 0x00000400, /* try to drain pending data when closing */ /* This flag is used by data layers to indicate they had to stop * receiving data because a buffer was full. The connection handler diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index be41362..3a154a8 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -144,6 +144,8 @@ static inline void conn_ctrl_init(struct connection *conn) static inline void conn_ctrl_close(struct connection *conn) { if ((conn->flags & (CO_FL_XPRT_READY|CO_FL_CTRL_READY)) == CO_FL_CTRL_READY) { + if ((conn->flags & (CO_FL_WANT_DRAIN | CO_FL_SOCK_RD_SH)) == CO_FL_WANT_DRAIN) + conn_sock_drain(conn); fd_delete(conn->handle.fd); conn->handle.fd = DEAD_FD_MAGIC; conn->flags &= ~CO_FL_CTRL_READY; diff --git a/src/connection.c b/src/connection.c index d64e941..4361bfc 100644 --- a/src/connection.c +++ b/src/connection.c @@ -417,7 +417,7 @@ int conn_sock_drain(struct connection *conn) if (fdtab[conn->handle.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) goto shut; - if (!fd_recv_ready(conn->handle.fd)) + if (!(conn->flags & CO_FL_WANT_DRAIN) && !fd_recv_ready(conn->handle.fd)) return 0; /* no drain function defined, use the generic one */ -- 1.7.10.4