]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] stream_sock: always shutdown(SHUT_WR) before closing
authorWilly Tarreau <w@1wt.eu>
Tue, 14 Jul 2009 17:21:50 +0000 (19:21 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 14 Jul 2009 17:21:50 +0000 (19:21 +0200)
When we close a socket with unread data in the buffer, or when the
nolinger option is set, we regularly lose the last fragment, which
often contains the error message. This typically occurs when sending
too large a request. Only the RST is seen due to the close() (since
not all data were read) and the output message never reaches the
network.

Doing a shutdown() before the close() solves this annoying issue
because the data are really pushed before the system sends the RST.

src/stream_sock.c

index 438ff0a5e82a9ca6ce5a1e22b8f80504af5356e6..afcebb62cfd9b4763a717fd8ecb971f048fdcb9e 100644 (file)
@@ -834,17 +834,16 @@ void stream_sock_shutw(struct stream_interface *si)
 
        switch (si->state) {
        case SI_ST_EST:
-               if (!(si->ib->flags & BF_SHUTR)) {
-                       EV_FD_CLR(si->fd, DIR_WR);
-                       shutdown(si->fd, SHUT_WR);
+               /* we have to shut before closing, otherwise some short messages
+                * may never leave the system, especially when there are remaining
+                * unread data in the socket input buffer, or when nolinger is set.
+                */
+               EV_FD_CLR(si->fd, DIR_WR);
+               shutdown(si->fd, SHUT_WR);
+
+               if (!(si->ib->flags & BF_SHUTR))
                        return;
-               }
 
-               if (fdtab[si->fd].flags & FD_FL_TCP_NOLING) {
-                       /* we have to shut before closing if we disable lingering */
-                       EV_FD_CLR(si->fd, DIR_WR);
-                       shutdown(si->fd, SHUT_WR);
-               }
                /* fall through */
        case SI_ST_CON:
                /* we may have to close a pending connection, and mark the