BUG/MEDIUM: mux-h2: Be able to detect connection error during handshake

When a backend H2 connection is waiting the connection is fully established,
nothing is sent. However, it remains useful to detect connection error at
this stage. It is especially important to release H2 connection on connect
error. Be able to set H2_CF_ERR_PENDiNG or H2_CF_ERROR flags when the
underlying connection is not fully established will exclude the H2C to be
inserted in a idle list in h2_detach().

Without this fix, an H2C in PREFACE state and relying on a connection in
error can be inserted in the safe list. Of course, it will be purged if not
reused. But in the mean time, it can be reused. When this happens, the
connection remains in error and nothing happens. At the end a connection
error is returned to the client. On low traffic, we can imagine a scenario
where this dead connection is the only idle connection. If it is always
reused before being purged, no connection to the server is possible.

In addition, h2c_is_dead() is updated to declare as dead any H2 connection
with a pending error if its state is PREFACE or SETTINGS1 (thus if no
SETTINGS frame was received yet).

This patch should fix the issue #2092. It must be backported as far as 2.6.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 8697799..a76293e 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -654,6 +654,7 @@
 {
 	if (eb_is_empty(&h2c->streams_by_id) &&     /* don't close if streams exist */
 	    ((h2c->flags & H2_CF_ERROR) ||          /* errors close immediately */
+	     (h2c->flags & H2_CF_ERR_PENDING && h2c->st0 < H2_CS_FRAME_H) || /* early error during connect */
 	     (h2c->st0 >= H2_CS_ERROR && !h2c->task) || /* a timeout stroke earlier */
 	     (!(h2c->conn->owner)) || /* Nobody's left to take care of the connection, drop it now */
 	     (!br_data(h2c->mbuf) &&  /* mux buffer empty, also process clean events below */
@@ -3772,11 +3773,6 @@
 		return 1;
 	}
 
-	if (conn->flags & CO_FL_WAIT_XPRT) {
-		/* a handshake was requested */
-		goto schedule;
-	}
-
 	/* This loop is quite simple : it tries to fill as much as it can from
 	 * pending streams into the existing buffer until it's reportedly full
 	 * or the end of send requests is reached. Then it tries to send this
@@ -3797,7 +3793,7 @@
 	 */
 
 	done = 0;
-	while (!done) {
+	while (!(conn->flags & CO_FL_WAIT_XPRT) && !done) {
 		unsigned int flags = 0;
 		unsigned int released = 0;
 		struct buffer *buf;
@@ -3880,11 +3876,11 @@
 		h2_resume_each_sending_h2s(h2c, &h2c->send_list);
 
 	/* We're done, no more to send */
-	if (!br_data(h2c->mbuf)) {
+	if (!(conn->flags & CO_FL_WAIT_XPRT) && !br_data(h2c->mbuf)) {
 		TRACE_DEVEL("leaving with everything sent", H2_EV_H2C_SEND, h2c->conn);
 		goto end;
 	}
-schedule:
+
 	if (!(conn->flags & CO_FL_ERROR) && !(h2c->wait_event.events & SUB_RETRY_SEND)) {
 		TRACE_STATE("more data to send, subscribing", H2_EV_H2C_SEND, h2c->conn);
 		conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_SEND, &h2c->wait_event);