MEDIUM: connection: extract the send_proxy callback from proto_tcp

This handshake handler must be independant, so move it away from
proto_tcp. It has a dedicated connection flag. It is tested before
I/O handlers and automatically removes the CO_FL_WAIT_L4_CONN flag
upon success.

It also sets the BF_WRITE_NULL flag on the stream interface and
stops the SI timeout. However it does not perform the task_wakeup(),
and relies on the data handler to do so for now. The SI wakeup will
have to be moved elsewhere anyway.
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 87ac849..86ef47b 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -41,7 +41,7 @@
 #include <proto/arg.h>
 #include <proto/buffers.h>
 #include <proto/connection.h>
-#include <proto/frontend.h>
+//#include <proto/frontend.h>
 #include <proto/log.h>
 #include <proto/port_range.h>
 #include <proto/protocols.h>
@@ -470,18 +470,20 @@
 	fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
 	si->conn.flags  = CO_FL_WAIT_L4_CONN; /* connection in progress */
 
-	/* If we have nothing to send, we want to confirm that the TCP
+	/* Prepare to send a few handshakes related to the on-wire protocol.
+	 * If we have nothing to send, we want to confirm that the TCP
 	 * connection is established before doing so, so we use our own write
 	 * callback then switch to the sock layer.
 	 */
-	if ((si->ob->flags & BF_OUT_EMPTY) || si->send_proxy_ofs) {
+	fdtab[fd].cb[DIR_RD].f = NULL;
+	fdtab[fd].cb[DIR_WR].f = NULL;
+
+	if (si->send_proxy_ofs)
+		si->conn.flags |= CO_FL_SI_SEND_PROXY;
+	else if (si->ob->flags & BF_OUT_EMPTY) {
 		fdtab[fd].cb[DIR_RD].f = tcp_connect_read;
 		fdtab[fd].cb[DIR_WR].f = tcp_connect_write;
 	}
-	else {
-		fdtab[fd].cb[DIR_RD].f = NULL;
-		fdtab[fd].cb[DIR_WR].f = NULL;
-	}
 
 	fdtab[fd].iocb = conn_fd_handler;
 	fd_insert(fd);
@@ -551,64 +553,23 @@
 	if (b->flags & BF_SHUTW)
 		goto out_wakeup;
 
-	/* 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().
+	/* We have no data to send to check the connection, and
+	 * getsockopt() will not inform us whether the connection
+	 * is still pending. So we'll reuse connect() to check the
+	 * state of the socket. This has the advantage of giving us
+	 * the following info :
+	 *  - error
+	 *  - connecting (EALREADY, EINPROGRESS)
+	 *  - connected (EISCONN, 0)
 	 */
-	if (si->send_proxy_ofs) {
-		int ret;
-
-		/* The target server expects a PROXY line to be sent first.
-		 * If the send_proxy_ofs is negative, it corresponds to the
-		 * offset to start sending from then end of the proxy string
-		 * (which is recomputed every time since it's constant). If
-		 * it is positive, it means we have to send from the start.
-		 */
-		ret = make_proxy_line(trash, trashlen, &b->prod->addr.from, &b->prod->addr.to);
-		if (!ret)
-			goto out_error;
-
-		if (si->send_proxy_ofs > 0)
-			si->send_proxy_ofs = -ret; /* first call */
-
-		/* we have to send trash from (ret+sp for -sp bytes) */
-		ret = send(fd, trash + ret + si->send_proxy_ofs, -si->send_proxy_ofs,
-			   (b->flags & BF_OUT_EMPTY) ? 0 : MSG_MORE);
-
-		if (ret == 0)
+	if ((connect(fd, conn->peeraddr, conn->peerlen) < 0)) {
+		if (errno == EALREADY || errno == EINPROGRESS)
 			goto out_ignore;
 
-		if (ret < 0) {
-			if (errno == EAGAIN)
-				goto out_ignore;
+		if (errno && errno != EISCONN)
 			goto out_error;
-		}
-
-		si->send_proxy_ofs += ret; /* becomes zero once complete */
-		if (si->send_proxy_ofs != 0)
-			goto out_ignore;
-
-		/* OK we've sent the whole line, we're connected */
-	}
-	else {
-		/* We have no data to send to check the connection, and
-		 * getsockopt() will not inform us whether the connection
-		 * is still pending. So we'll reuse connect() to check the
-		 * state of the socket. This has the advantage of giving us
-		 * the following info :
-		 *  - error
-		 *  - connecting (EALREADY, EINPROGRESS)
-		 *  - connected (EISCONN, 0)
-		 */
-		if ((connect(fd, conn->peeraddr, conn->peerlen) < 0)) {
-			if (errno == EALREADY || errno == EINPROGRESS)
-				goto out_ignore;
 
-			if (errno && errno != EISCONN)
-				goto out_error;
-
-			/* otherwise we're connected */
-		}
+		/* otherwise we're connected */
 	}
 
 	/* OK we just need to indicate that we got a connection
@@ -629,7 +590,6 @@
 	task_wakeup(si->owner, TASK_WOKEN_IO);
 
  out_ignore:
-	fdtab[fd].ev &= ~FD_POLL_OUT;
 	return retval;
 
  out_error: