From: Willy Tarreau Date: Tue, 6 Aug 2019 14:26:31 +0000 (+0200) Subject: BUG/MEDIUM: checks: make sure to close nicely when we're the last to speak X-Git-Tag: v2.1-dev2~227 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5488a62bfbcadd33fca1255ca50f953d1f508a61;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/checks.c b/src/checks.c index d91e23922d..ff39b4f643 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