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 c417d5a..1330fad 100644
--- a/src/raw_sock.c
+++ b/src/raw_sock.c
@@ -70,8 +70,17 @@
* 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 @@
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)) {