]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: checks: make sure to close nicely when we're the last to speak
authorWilly Tarreau <w@1wt.eu>
Tue, 6 Aug 2019 14:26:31 +0000 (16:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 6 Aug 2019 14:35:55 +0000 (16:35 +0200)
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

index d91e23922deb7967c3d8b36f48258d5027c149f7..ff39b4f6433ab764224fb5f676aabbc5099e8976 100644 (file)
@@ -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