MINOR: connection: make conn_sock_drain() work for all socket families

This patch improves the previous fix by implementing the socket draining
code directly in conn_sock_drain() so that it always applies regardless
of the protocol's family. Thus it gets rid of tcp_drain().
diff --git a/include/proto/proto_tcp.h b/include/proto/proto_tcp.h
index 5241e7c..d4e09c7 100644
--- a/include/proto/proto_tcp.h
+++ b/include/proto/proto_tcp.h
@@ -33,7 +33,6 @@
 int tcp_connect_probe(struct connection *conn);
 int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
-int tcp_drain(int fd);
 
 /* Export some samples. */
 int smp_fetch_src(const struct arg *args, struct sample *smp, const char *kw, void *private);
diff --git a/src/connection.c b/src/connection.c
index b3ef56e..ab32567 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -359,29 +359,61 @@
  */
 int conn_sock_drain(struct connection *conn)
 {
+	int turns = 2;
+	int len;
+
 	if (!conn_ctrl_ready(conn))
 		return 1;
 
 	if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH))
 		return 1;
 
-	if (fdtab[conn->handle.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) {
-		fdtab[conn->handle.fd].linger_risk = 0;
-	}
-	else {
-		if (!fd_recv_ready(conn->handle.fd))
-			return 0;
+	if (fdtab[conn->handle.fd].ev & (FD_POLL_ERR|FD_POLL_HUP))
+		goto shut;
 
-		/* disable draining if we were called and have no drain function */
-		if (!conn->ctrl->drain) {
-			__conn_xprt_stop_recv(conn);
-			return 0;
-		}
+	if (!fd_recv_ready(conn->handle.fd))
+		return 0;
 
+	if (conn->ctrl->drain) {
 		if (conn->ctrl->drain(conn->handle.fd) <= 0)
 			return 0;
+		goto shut;
+	}
+
+	/* no drain function defined, use the generic one */
+
+	while (turns) {
+#ifdef MSG_TRUNC_CLEARS_INPUT
+		len = recv(conn->handle.fd, NULL, INT_MAX, MSG_DONTWAIT | MSG_NOSIGNAL | MSG_TRUNC);
+		if (len == -1 && errno == EFAULT)
+#endif
+			len = recv(conn->handle.fd, trash.area, trash.size,
+				   MSG_DONTWAIT | MSG_NOSIGNAL);
+
+		if (len == 0)
+			goto shut;
+
+		if (len < 0) {
+			if (errno == EAGAIN) {
+				/* connection not closed yet */
+				fd_cant_recv(conn->handle.fd);
+				break;
+			}
+			if (errno == EINTR)  /* oops, try again */
+				continue;
+			/* other errors indicate a dead connection, fine. */
+			goto shut;
+		}
+		/* OK we read some data, let's try again once */
+		turns--;
 	}
 
+	/* some data are still present, give up */
+	return 0;
+
+ shut:
+	/* we're certain the connection was shut down */
+	fdtab[conn->handle.fd].linger_risk = 0;
 	conn->flags |= CO_FL_SOCK_RD_SH;
 	return 1;
 }
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index d49ecf4..c000602 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -83,7 +83,6 @@
 	.enable_all = enable_all_listeners,
 	.get_src = tcp_get_src,
 	.get_dst = tcp_get_dst,
-	.drain = tcp_drain,
 	.pause = tcp_pause_listener,
 	.add = tcpv4_add_listener,
 	.listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
@@ -107,7 +106,6 @@
 	.enable_all = enable_all_listeners,
 	.get_src = tcp_get_src,
 	.get_dst = tcp_get_dst,
-	.drain = tcp_drain,
 	.pause = tcp_pause_listener,
 	.add = tcpv6_add_listener,
 	.listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
@@ -616,49 +614,6 @@
 	}
 }
 
-/* Tries to drain any pending incoming data from the socket to reach the
- * receive shutdown. Returns positive if the shutdown was found, negative
- * if EAGAIN was hit, otherwise zero. This is useful to decide whether we
- * can close a connection cleanly are we must kill it hard.
- */
-int tcp_drain(int fd)
-{
-	int turns = 2;
-	int len;
-
-	while (turns) {
-#ifdef MSG_TRUNC_CLEARS_INPUT
-		len = recv(fd, NULL, INT_MAX, MSG_DONTWAIT | MSG_NOSIGNAL | MSG_TRUNC);
-		if (len == -1 && errno == EFAULT)
-#endif
-			len = recv(fd, trash.area, trash.size,
-				   MSG_DONTWAIT | MSG_NOSIGNAL);
-
-		if (len == 0) {
-			/* cool, shutdown received */
-			fdtab[fd].linger_risk = 0;
-			return 1;
-		}
-
-		if (len < 0) {
-			if (errno == EAGAIN) {
-				/* connection not closed yet */
-				fd_cant_recv(fd);
-				return -1;
-			}
-			if (errno == EINTR)  /* oops, try again */
-				continue;
-			/* other errors indicate a dead connection, fine. */
-			fdtab[fd].linger_risk = 0;
-			return 1;
-		}
-		/* OK we read some data, let's try again once */
-		turns--;
-	}
-	/* some data are still present, give up */
-	return 0;
-}
-
 /* This is the callback which is set when a connection establishment is pending
  * and we have nothing to send. It updates the FD polling status. It returns 0
  * if it fails in a fatal way or needs to poll to go further, otherwise it
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 9c04d60..ab788bd 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -42,7 +42,6 @@
 #include <proto/listener.h>
 #include <proto/log.h>
 #include <proto/protocol.h>
-#include <proto/proto_tcp.h>
 #include <proto/task.h>
 
 static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
@@ -72,7 +71,6 @@
 	.disable_all = disable_all_listeners,
 	.get_src = uxst_get_src,
 	.get_dst = uxst_get_dst,
-	.drain = tcp_drain,
 	.pause = uxst_pause_listener,
 	.add = uxst_add_listener,
 	.listeners = LIST_HEAD_INIT(proto_unix.listeners),