From: Willy Tarreau Date: Thu, 23 Jan 2020 17:17:55 +0000 (+0100) Subject: MINOR: raw-sock: always check for CO_FL_SOCK_WR_SH before sending X-Git-Tag: v2.2-dev2~87 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a8c7e8e3a8994770ceeea239b62ca3d7bf7aa641;p=thirdparty%2Fhaproxy.git MINOR: raw-sock: always check for CO_FL_SOCK_WR_SH before sending 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. --- diff --git a/src/raw_sock.c b/src/raw_sock.c index 5a1e943d7e..af9a911829 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -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,