From: Willy Tarreau Date: Tue, 5 Nov 2024 16:57:43 +0000 (+0100) Subject: MINOR: rawsock: set connection error codes when returning from recv/send/splice X-Git-Tag: v3.1-dev12~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=822d82caf4165f0f6da681737c7e3db17d01f599;p=thirdparty%2Fhaproxy.git MINOR: rawsock: set connection error codes when returning from recv/send/splice For a long time the errno values returned by recv/send/splice() were not translated to connection error codes. There are not that many eligible and having them would help a lot when debugging some complex issues where logs disagree with network traces. Let's add them now. --- diff --git a/src/raw_sock.c b/src/raw_sock.c index 1287dc5e2e..9da2647c47 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -78,6 +78,7 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe, /* report error on POLL_ERR before connection establishment */ if ((fdtab[conn->handle.fd].state & FD_POLL_ERR) && (conn->flags & CO_FL_WAIT_L4_CONN)) { conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH; + conn_set_errcode(conn, CO_ER_POLLERR); errno = 0; /* let the caller do a getsockopt() if it wants it */ goto leave; } @@ -127,6 +128,7 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe, } /* here we have another error */ conn->flags |= CO_FL_ERROR; + conn_set_errno(conn, errno); break; } /* ret <= 0 */ @@ -176,6 +178,7 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip /* it's already closed */ conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH; errno = EPIPE; + conn_set_errno(conn, errno); return 0; } @@ -197,6 +200,7 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip /* here we have another error */ conn->flags |= CO_FL_ERROR; + conn_set_errno(conn, errno); break; } @@ -248,6 +252,7 @@ static size_t raw_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu /* report error on POLL_ERR before connection establishment */ if ((fdtab[conn->handle.fd].state & FD_POLL_ERR) && (conn->flags & CO_FL_WAIT_L4_CONN)) { conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH; + conn_set_errcode(conn, CO_ER_POLLERR); goto leave; } } @@ -306,6 +311,7 @@ static size_t raw_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu } else if (errno != EINTR) { conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH; + conn_set_errno(conn, errno); break; } } @@ -327,8 +333,10 @@ static size_t raw_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu * of recv()'s return value 0, so we have no way to tell there was * an error without checking. */ - if (unlikely(!done && fdtab[conn->handle.fd].state & FD_POLL_ERR)) + if (unlikely(!done && fdtab[conn->handle.fd].state & FD_POLL_ERR)) { conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH; + conn_set_errcode(conn, CO_ER_POLLERR); + } goto leave; } @@ -361,6 +369,7 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s if (unlikely(fdtab[conn->handle.fd].state & FD_POLL_ERR)) { /* an error was reported on the FD, we can't send anymore */ conn->flags |= CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_SOCK_RD_SH; + conn_set_errcode(conn, CO_ER_POLLERR); errno = EPIPE; return 0; } @@ -369,6 +378,7 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s /* it's already closed */ conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH; errno = EPIPE; + conn_set_errno(conn, errno); return 0; } @@ -407,6 +417,7 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s } else if (errno != EINTR) { conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH; + conn_set_errno(conn, errno); break; } }