MINOR: mux-h1: Add embryonic and attached states on the H1 connection

Be prepared to have a H1 connection in one of the following states :

 * A H1 connection waiting for a new message with no H1 stream.
   H1C_F_CS_IDLE flag is set.

 * A H1 connection processing a new message with a H1 stream but no
   conn-stream attached. H1C_F_CS_EMBRYONIC flag is set

 * A H1 connection with a H1 stream and a conn-stream attached.
   H1C_F_CS_ATTACHED flag is set.

 * A H1 connection with no H1 stream, waiting to be released. No flag is set.

These flags are mutually exclusives. When none is set, it means the
connection will be released ASAP, just remaining outgoing data must be sent
before. For now, the second state (H1C_F_CS_EMBRYONIC) is transient.
diff --git a/src/mux_h1.c b/src/mux_h1.c
index 904572e..1be50f5 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -60,6 +60,10 @@
 #define H1C_F_WAIT_OPPOSITE  0x00100000 /* Don't read more data for now, waiting sync with opposite side */
 #define H1C_F_WANT_SPLICE    0x00200000 /* Don't read into a bufffer because we want to use or we are using splicing */
 #define H1C_F_IS_BACK        0x00400000 /* Set on outgoing connection */
+
+#define H1C_F_CS_EMBRYONIC   0x01000000 /* Set when a H1 stream with no conn-stream is attached to the connection */
+#define H1C_F_CS_ATTACHED    0x02000000 /* Set when a H1 stream with a conn-stream is attached to the connection */
+#define H1C_F_CS_ALIVE       (H1C_F_CS_IDLE|H1C_F_CS_EMBRYONIC|H1C_F_CS_ATTACHED)
 /*
  * H1 Stream flags (32 bits)
  */
@@ -534,6 +538,7 @@
 
 	if (h1s->flags & H1S_F_NOT_FIRST)
 		cs->flags |= CS_FL_NOT_FIRST;
+	h1s->h1c->flags = (h1s->h1c->flags & ~H1C_F_CS_EMBRYONIC) | H1C_F_CS_ATTACHED;
 
 	if (global.tune.options & GTUNE_USE_SPLICE) {
 		TRACE_STATE("notify the mux can use splicing", H1_EV_STRM_NEW, h1s->h1c->conn, h1s);
@@ -583,7 +588,7 @@
 
 	if (h1c->flags & H1C_F_WAIT_NEXT_REQ)
 		h1s->flags |= H1S_F_NOT_FIRST;
-	h1c->flags &= ~(H1C_F_CS_IDLE|H1C_F_WAIT_NEXT_REQ);
+	h1c->flags = (h1c->flags & ~(H1C_F_CS_IDLE|H1C_F_WAIT_NEXT_REQ)) | H1C_F_CS_EMBRYONIC;
 
 	TRACE_LEAVE(H1_EV_H1S_NEW, h1c->conn, h1s);
 	return h1s;
@@ -637,6 +642,7 @@
 	h1s->sess = sess;
 	cs->ctx = h1s;
 
+	h1c->flags = (h1c->flags & ~H1C_F_CS_EMBRYONIC) | H1C_F_CS_ATTACHED;
 
 	if (h1c->px->options2 & PR_O2_RSPBUG_OK)
 		h1s->res.err_pos = -1;
@@ -662,7 +668,7 @@
 
 		h1_release_buf(h1c, &h1s->rxbuf);
 
-		h1c->flags &= ~H1C_F_WAIT_OPPOSITE;
+		h1c->flags &= ~(H1C_F_WAIT_OPPOSITE|H1C_F_CS_EMBRYONIC|H1C_F_CS_ATTACHED);
 		if (h1s->flags & H1S_F_ERROR) {
 			h1c->flags |= H1C_F_CS_ERROR;
 			TRACE_STATE("h1s on error, set error on h1c", H1_EV_H1C_ERR, h1c->conn, h1s);
@@ -1116,7 +1122,7 @@
 	struct proxy *other_end;
 	union error_snapshot_ctx ctx;
 
-	if (h1s->cs && h1s->cs->data) {
+	if ((h1c->flags & H1C_F_CS_ATTACHED) && h1s->cs->data) {
 		if (sess == NULL)
 			sess = si_strm(h1s->cs->data)->sess;
 		if (!(h1m->flags & H1_MF_RESP))
@@ -2066,7 +2072,7 @@
 	if (ret > 0) {
 		TRACE_DATA("data received", H1_EV_H1C_RECV, h1c->conn, 0, 0, (size_t[]){ret});
 		rcvd = 1;
-		if (h1s && h1s->cs)
+		if (h1c->flags & H1C_F_CS_ATTACHED)
 			h1s->cs->flags |= (CS_FL_READ_PARTIAL|CS_FL_RCV_MORE);
 	}
 
@@ -2206,7 +2212,7 @@
 		TRACE_STATE("read0 on connection", H1_EV_H1C_RECV, conn, h1s);
 	}
 
-	if (!h1s_data_pending(h1s) && h1s && h1s->cs && h1s->cs->data_cb->wake &&
+	if (!h1s_data_pending(h1s) && h1s && (h1c->flags & H1C_F_CS_ATTACHED) && h1s->cs->data_cb->wake &&
 	    (h1s->flags & H1S_F_REOS || h1c->flags & H1C_F_CS_ERROR ||
 	    conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH))) {
 		if (h1c->flags & H1C_F_CS_ERROR || conn->flags & CO_FL_ERROR)
@@ -2297,7 +2303,7 @@
 	if (ret == 0) {
 		struct h1s *h1s = h1c->h1s;
 
-		if (h1s && h1s->cs && h1s->cs->data_cb->wake) {
+		if ((h1c->flags & H1C_F_CS_ATTACHED) && h1s->cs->data_cb->wake) {
 			TRACE_POINT(H1_EV_STRM_WAKE, h1c->conn, h1s);
 			ret = h1s->cs->data_cb->wake(h1s->cs);
 		}
@@ -2350,7 +2356,7 @@
 	 * for the stream's timeout. Otherwise, release the mux. This is only ok
 	 * because same timeouts are used.
 	 */
-	if (h1c->h1s && h1c->h1s->cs) {
+	if (h1c->flags & H1C_F_CS_ATTACHED) {
 		h1c->flags |= H1C_F_CS_ERROR;
 		TRACE_STATE("error on h1c, h1s still attached (expired)", H1_EV_H1C_WAKE|H1_EV_H1C_ERR, h1c->conn, h1c->h1s);
 	}