MEDIUM: unix: avoid a double connect probe when no data are sent

Plain "tcp" health checks sent to a unix socket cause two connect()
calls to be made, one to connect, and a second one to verify that the
connection properly established. But with unix sockets, we get
immediate notification of success, so we can avoid this second
attempt. However we need to ensure that we'll visit the connection
handler even if there's no remaining handshake pending, so for this
we claim we have some data to send in order to enable polling for
writes if there's no more handshake.
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index f2621fa..f83d34e 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -381,7 +381,7 @@
 	struct server *srv;
 	struct proxy *be;
 
-	conn->flags = CO_FL_WAIT_L4_CONN; /* connection in progress */
+	conn->flags = 0;
 
 	switch (obj_type(conn->target)) {
 	case OBJ_TYPE_PROXY:
@@ -457,9 +457,14 @@
 	if (global.tune.server_rcvbuf)
                 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
 
-	if ((connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) == -1) &&
-	    (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
-		if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
+	if (connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) == -1) {
+		if (errno == EALREADY || errno == EISCONN) {
+			conn->flags &= ~CO_FL_WAIT_L4_CONN;
+		}
+		else if (errno == EINPROGRESS) {
+			conn->flags |= CO_FL_WAIT_L4_CONN;
+		}
+		else if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
 			char *msg;
 			if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
 				msg = "no free ports";
@@ -489,6 +494,16 @@
 			return SN_ERR_SRVCL;
 		}
 	}
+	else {
+		/* connect() already succeeded, which is quite usual for unix
+		 * sockets. Let's avoid a second connect() probe to complete it,
+		 * but we need to ensure we'll wake up if there's no more handshake
+		 * pending (eg: for health checks).
+		 */
+		conn->flags &= ~CO_FL_WAIT_L4_CONN;
+		if (!(conn->flags & CO_FL_HANDSHAKE))
+			data = 1;
+	}
 
 	conn->flags |= CO_FL_ADDR_TO_SET;
 
@@ -497,8 +512,9 @@
 		conn->flags |= CO_FL_SEND_PROXY;
 
 	conn_ctrl_init(conn);       /* registers the FD */
-	fdtab[fd].linger_risk = 1;  /* close hard if needed */
-	conn_sock_want_send(conn);  /* for connect status */
+	fdtab[fd].linger_risk = 0;  /* no need to disable lingering */
+	if (conn->flags & CO_FL_HANDSHAKE)
+		conn_sock_want_send(conn);  /* for connect status or proxy protocol */
 
 	if (conn_xprt_init(conn) < 0) {
 		conn_force_close(conn);