[MEDIUM] add a turn-around state of one second after a connection failure

Several users have complained that when haproxy gets a connection
failure due to an active reject from a server, it immediately
retries, often leading to the same situation being repeated until
the retry counter reaches zero.

Now if a connection error shows up, a turn-around state of 1 second
is applied before retrying. This is performed by faking a connection
timeout in order not to touch much code. However, a cleaner method
would involve an extra state.
diff --git a/src/proto_http.c b/src/proto_http.c
index 9d7041f..d69d8e2 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2488,18 +2488,38 @@
 			/* timeout, asynchronous connect error or first write error */
 			//fprintf(stderr,"2: c=%d, s=%d\n", c, s);
 
-			fd_delete(t->srv_fd);
-			if (t->srv)
-				t->srv->cur_sess--;
+			if (t->flags & SN_CONN_TAR) {
+				/* We are doing a turn-around waiting for a new connection attempt. */
+				if (!tv_isle(&req->cex, &now))
+					return 0;
+				t->flags &= ~SN_CONN_TAR;
+			}
+			else {
+				fd_delete(t->srv_fd);
+				if (t->srv)
+					t->srv->cur_sess--;
 
-			if (!(req->flags & BF_WRITE_STATUS))
-				conn_err = SN_ERR_SRVTO; // it was a connect timeout.
-			else
-				conn_err = SN_ERR_SRVCL; // it was an asynchronous connect error.
+				if (!(req->flags & BF_WRITE_STATUS))
+					conn_err = SN_ERR_SRVTO; // it was a connect timeout.
+				else
+					conn_err = SN_ERR_SRVCL; // it was an asynchronous connect error.
+
+				/* ensure that we have enough retries left */
+				if (srv_count_retry_down(t, conn_err))
+					return 1;
 
-			/* ensure that we have enough retries left */
-			if (srv_count_retry_down(t, conn_err))
-				return 1;
+				if (req->flags & BF_WRITE_ERROR) {
+					/* we encountered an immediate connection error, and we
+					 * will have to retry connecting to the same server, most
+					 * likely leading to the same result. To avoid this, we
+					 * fake a connection timeout to retry after a turn-around
+					 * time of 1 second. We will wait in the previous if block.
+					 */
+					t->flags |= SN_CONN_TAR;
+					tv_ms_add(&req->cex, &now, 1000);
+					return 0;
+				}
+			}
 
 			if (t->srv && t->conn_retries == 0 && t->be->options & PR_O_REDISP) {
 				/* We're on our last chance, and the REDISP option was specified.