From: Krzysztof Oledzki Date: Thu, 11 Oct 2007 16:41:08 +0000 (+0200) Subject: [MINOR] prevent the system from sending an RST when closing health-checks X-Git-Tag: v1.3.13~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6b3f8b4b8f40441a39fca196ccb1052d4cba27e0;p=thirdparty%2Fhaproxy.git [MINOR] prevent the system from sending an RST when closing health-checks On Sat, 22 Sep 2007, Willy Tarreau wrote: > On Sun, Sep 23, 2007 at 03:23:38AM +0200, Krzysztof Oledzki wrote: > > I noticed that with httpchk, haproxy generates TCP RST at end of a check. > > IMHO, it would be more polite to send FIN to a server, especially that > > each TCP RST found by a tcpdump makes me concerned that something is > > wrong, as it is hard to distinguish between a RST from a httpchk and from > > a normal request, forwarded for a client. > > I have also noticed it very recently. In fact, it's never the > application (here haproxy) which decides to send an RST, it's the > system. It does so because the server returns data on a terminated > socket. I guess it's because the health-check code does not read much > of the response. In fact, we just need to read enough to process common > responses. If people are dumb enough to check with something like "GET > /image.iso", they should expect to get an RST after a few kbytes > instead of reading the whole file! Right, that was easy. Attached patch changed what you described. Now haproxy finishes http checks with FIN. --- diff --git a/src/checks.c b/src/checks.c index 2c581ef1c8..62f0c2c711 100644 --- a/src/checks.c +++ b/src/checks.c @@ -210,7 +210,6 @@ static int event_srv_chk_w(int fd) static int event_srv_chk_r(int fd) { __label__ out_wakeup; - char reply[64]; int len, result; struct task *t = fdtab[fd].owner; struct server *s = t->context; @@ -230,13 +229,13 @@ static int event_srv_chk_r(int fd) } #ifndef MSG_NOSIGNAL - len = recv(fd, reply, sizeof(reply), 0); + len = recv(fd, trash, sizeof(trash), 0); #else /* Warning! Linux returns EAGAIN on SO_ERROR if data are still available * but the connection was closed on the remote end. Fortunately, recv still * works correctly and we don't need to do the getsockopt() on linux. */ - len = recv(fd, reply, sizeof(reply), MSG_NOSIGNAL); + len = recv(fd, trash, sizeof(trash), MSG_NOSIGNAL); #endif if (unlikely(len < 0 && errno == EAGAIN)) { /* we want some polling to happen first */ @@ -245,17 +244,17 @@ static int event_srv_chk_r(int fd) } if ((s->proxy->options & PR_O_HTTP_CHK) && (len >= sizeof("HTTP/1.0 000")) && - (memcmp(reply, "HTTP/1.", 7) == 0) && (reply[9] == '2' || reply[9] == '3')) { + (memcmp(trash, "HTTP/1.", 7) == 0) && (trash[9] == '2' || trash[9] == '3')) { /* HTTP/1.X 2xx or 3xx */ result = 1; } else if ((s->proxy->options & PR_O_SSL3_CHK) && (len >= 5) && - (reply[0] == 0x15 || reply[0] == 0x16)) { + (trash[0] == 0x15 || trash[0] == 0x16)) { /* SSLv3 alert or handshake */ result = 1; } else if ((s->proxy->options & PR_O_SMTP_CHK) && (len >= 3) && - (reply[0] == '2')) /* 2xx (should be 250) */ { + (trash[0] == '2')) /* 2xx (should be 250) */ { result = 1; }