MEDIUM: connection: add check for readiness in I/O handlers

The recv/send callbacks must check for readiness themselves instead of
having their callers do it. This will strengthen the test and will also
ensure we never refrain from calling a handshake handler because a
direction is being polled while the other one is ready.
diff --git a/src/connection.c b/src/connection.c
index 2538cc5..876d71a 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -120,7 +120,7 @@
 	if (unlikely(conn->flags & (CO_FL_HANDSHAKE | CO_FL_ERROR)))
 		goto process_handshake;
 
-	if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && fd_send_ready(conn->t.sock.fd)) {
+	if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN)) {
 		/* still waiting for a connection to establish and nothing was
 		 * attempted yet to probe the connection. Then let's retry the
 		 * connect().
@@ -255,6 +255,9 @@
 	if (!(conn->flags & CO_FL_CTRL_READY))
 		goto fail;
 
+	if (!fd_recv_ready(conn->t.sock.fd))
+		return 0;
+
 	do {
 		trash.len = recv(conn->t.sock.fd, trash.str, trash.size, MSG_PEEK);
 		if (trash.len < 0) {
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index cb10661..79c7baf 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -632,6 +632,9 @@
 	if (!(conn->flags & CO_FL_WAIT_L4_CONN))
 		return 1; /* strange we were called while ready */
 
+	if (!fd_send_ready(fd))
+		return 0;
+
 	/* we might be the first witness of FD_POLL_ERR. Note that FD_POLL_HUP
 	 * without FD_POLL_IN also indicates a hangup without input data meaning
 	 * there was no connection.
diff --git a/src/raw_sock.c b/src/raw_sock.c
index 3d42781..a67a8d9 100644
--- a/src/raw_sock.c
+++ b/src/raw_sock.c
@@ -75,9 +75,12 @@
 	int retval = 0;
 
 
-	if (!(conn->flags & CO_FL_CTRL_READY))
+	if (!conn_ctrl_ready(conn))
 		return 0;
 
+	if (!fd_recv_ready(conn->t.sock.fd))
+		return 0;
+
 	errno = 0;
 
 	/* Under Linux, if FD_POLL_HUP is set, we have reached the end.
@@ -193,7 +196,10 @@
 {
 	int ret, done;
 
+	if (!conn_ctrl_ready(conn))
+		return 0;
+
-	if (!(conn->flags & CO_FL_CTRL_READY))
+	if (!fd_send_ready(conn->t.sock.fd))
 		return 0;
 
 	done = 0;
@@ -240,9 +246,12 @@
 	int ret, done = 0;
 	int try;
 
-	if (!(conn->flags & CO_FL_CTRL_READY))
+	if (!conn_ctrl_ready(conn))
 		return 0;
 
+	if (!fd_recv_ready(conn->t.sock.fd))
+		return 0;
+
 	errno = 0;
 
 	if (unlikely(!(fdtab[conn->t.sock.fd].ev & FD_POLL_IN))) {
@@ -342,7 +351,10 @@
 {
 	int ret, try, done, send_flag;
 
-	if (!(conn->flags & CO_FL_CTRL_READY))
+	if (!conn_ctrl_ready(conn))
+		return 0;
+
+	if (!fd_send_ready(conn->t.sock.fd))
 		return 0;
 
 	done = 0;
diff --git a/src/stream_interface.c b/src/stream_interface.c
index 6096dd7..abbbcb1 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -400,6 +400,9 @@
 	if (!conn_ctrl_ready(conn))
 		goto out_error;
 
+	if (!fd_send_ready(conn->t.sock.fd))
+		goto out_wait;
+
 	/* If we have a PROXY line to send, we'll use this to validate the
 	 * connection, in which case the connection is validated only once
 	 * we've sent the whole proxy line. Otherwise we use connect().