From: Willy Tarreau Date: Thu, 4 Oct 2012 18:38:49 +0000 (+0200) Subject: MEDIUM: raw_sock: improve connection error reporting X-Git-Tag: v1.5-dev13~222 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f5d141149e632f3bdcd09f4ba80dd9a09d1f22c;p=thirdparty%2Fhaproxy.git MEDIUM: raw_sock: improve connection error reporting When a connection setup is pending and we receive an error without a POLL_IN flag, we're certain there will be nothing to read from it and we can safely report an error without attempting a recv() call. This will be significantly better for health checks which will avoid a useless recv() on all failed checks. --- diff --git a/src/raw_sock.c b/src/raw_sock.c index c417d5a7d3..1330fadd70 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -70,8 +70,17 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co * Since older splice() implementations were buggy and returned * EAGAIN on end of read, let's bypass the call to splice() now. */ - if ((fdtab[conn->t.sock.fd].ev & (FD_POLL_IN|FD_POLL_ERR|FD_POLL_HUP)) == FD_POLL_HUP) - goto out_read0; + if (unlikely(!(fdtab[conn->t.sock.fd].ev & FD_POLL_IN))) { + /* stop here if we reached the end of data */ + if ((fdtab[conn->t.sock.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) == FD_POLL_HUP) + goto out_read0; + + /* report error on POLL_ERR before connection establishment */ + if ((fdtab[conn->t.sock.fd].ev & FD_POLL_ERR) && (conn->flags & CO_FL_WAIT_L4_CONN)) { + conn->flags |= CO_FL_ERROR; + return retval; + } + } while (count) { if (count > MAX_SPLICE_AT_ONCE) @@ -201,9 +210,17 @@ static int raw_sock_to_buf(struct connection *conn, struct buffer *buf, int coun int ret, done = 0; int try = count; - /* stop here if we reached the end of data */ - if ((fdtab[conn->t.sock.fd].ev & (FD_POLL_IN|FD_POLL_ERR|FD_POLL_HUP)) == FD_POLL_HUP) - goto read0; + if (unlikely(!(fdtab[conn->t.sock.fd].ev & FD_POLL_IN))) { + /* stop here if we reached the end of data */ + if ((fdtab[conn->t.sock.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) == FD_POLL_HUP) + goto read0; + + /* report error on POLL_ERR before connection establishment */ + if ((fdtab[conn->t.sock.fd].ev & FD_POLL_ERR) && (conn->flags & CO_FL_WAIT_L4_CONN)) { + conn->flags |= CO_FL_ERROR; + return done; + } + } /* compute the maximum block size we can read at once. */ if (buffer_empty(buf)) {