From 5488a62bfbcadd33fca1255ca50f953d1f508a61 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 6 Aug 2019 16:26:31 +0200 Subject: [PATCH] BUG/MEDIUM: checks: make sure to close nicely when we're the last to speak In SMTP, MySQL and PgSQL checks, we're supposed to finish with a message to politely quit the server, otherwise some of them will log some errors. This is the case with Postfix as reported in GH issue #187. Since commit fe4abe6 ("BUG/MEDIUM: connections: Don't call shutdown() if we want to disable linger.") we are a bit more aggressive on outgoing connection closure and checks were not prepared for this. This patch makes the 3 checks above disable the linger_risk for these checks so that we close cleanly, with the side effect that it will leave some TIME_WAIT connections behind (hence why it should not be generalized to all checks). It's worth noting that in issue #187 it's mentioned that this patch doesn't seem to be sufficient for Postfix, however based only on local network activity this looks OK, so maybe this will need to be improved later. Given that the patch above was backported to 2.0 and 1.9, this one should as well. --- src/checks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/checks.c b/src/checks.c index d91e23922..ff39b4f64 100644 --- a/src/checks.c +++ b/src/checks.c @@ -941,6 +941,10 @@ static void __event_srv_chk_r(struct conn_stream *cs) if (!done && b_data(&check->bi) < strlen("000\r")) goto wait_more_data; + /* do not reset when closing, servers don't like this */ + if (conn_ctrl_ready(cs->conn)) + fdtab[cs->conn->handle.fd].linger_risk = 0; + /* Check if the server speaks SMTP */ if ((b_data(&check->bi) < strlen("000\r")) || (*(b_head(&check->bi) + 3) != ' ' && *(b_head(&check->bi) + 3) != '\r') || @@ -1174,6 +1178,10 @@ static void __event_srv_chk_r(struct conn_stream *cs) if (!done && b_data(&check->bi) < 9) goto wait_more_data; + /* do not reset when closing, servers don't like this */ + if (conn_ctrl_ready(cs->conn)) + fdtab[cs->conn->handle.fd].linger_risk = 0; + if (b_head(&check->bi)[0] == 'R') { set_server_check_status(check, HCHK_STATUS_L7OKD, "PostgreSQL server is ok"); } @@ -1203,6 +1211,10 @@ static void __event_srv_chk_r(struct conn_stream *cs) if (!done && b_data(&check->bi) < 5) goto wait_more_data; + /* do not reset when closing, servers don't like this */ + if (conn_ctrl_ready(cs->conn)) + fdtab[cs->conn->handle.fd].linger_risk = 0; + if (s->proxy->check_len == 0) { // old mode if (*(b_head(&check->bi) + 4) != '\xff') { /* We set the MySQL Version in description for information purpose