]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: raw-sock: always check for CO_FL_SOCK_WR_SH before sending
authorWilly Tarreau <w@1wt.eu>
Thu, 23 Jan 2020 17:17:55 +0000 (18:17 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 23 Jan 2020 18:01:37 +0000 (19:01 +0100)
The test was added before splice() and send() to make sure we never
accidently send after a shutdown, because upper layers do not all
check and it's not their job to do it. In such a case we also set
errno to EPIPE so that the error can be accurately reported, e.g.,
in health checks.

src/raw_sock.c

index 5a1e943d7e142140922145f6b22d54b644437f5f..af9a91182939300621bb529eb7688fd70d05e8e5 100644 (file)
@@ -185,6 +185,13 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip
        if (!fd_send_ready(conn->handle.fd))
                return 0;
 
+       if (conn->flags & CO_FL_SOCK_WR_SH) {
+               /* it's already closed */
+               conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH;
+               errno = EPIPE;
+               return 0;
+       }
+
        done = 0;
        while (pipe->data) {
                ret = splice(pipe->cons, NULL, conn->handle.fd, NULL, pipe->data,
@@ -351,6 +358,13 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s
        if (!fd_send_ready(conn->handle.fd))
                return 0;
 
+       if (conn->flags & CO_FL_SOCK_WR_SH) {
+               /* it's already closed */
+               conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH;
+               errno = EPIPE;
+               return 0;
+       }
+
        done = 0;
        /* send the largest possible block. For this we perform only one call
         * to send() unless the buffer wraps and we exactly fill the first hunk,