MEDIUM: mux-h2: Close streams when processing data for an aborted tunnel

In the previous patch ("MEDIUM: mux-h2: Block client data on server side
waiting tunnel establishment"), we added a way to block client data for not
fully established tunnel on the server side. This one closes the stream with
an ERR_CANCEL erorr if there are some pending tunneled data while the tunnel
was aborted. This may happen on the client side if a non-empty DATA frame or
an empty DATA frame without the ES flag is received. This may also happen on
the server side if there is a DATA htx block. However in this last case, we
first wait the response is fully forwarded.

This patch contributes to fix the tunnel mode between the H1 and the H2
muxes.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 38c53fe..38a0e2b 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -2860,6 +2860,19 @@
 		HA_ATOMIC_ADD(&h2c->px_counters->strm_proto_err, 1);
 		goto strm_err;
 	}
+	if (!(h2c->flags & H2_CF_IS_BACK) &&
+	    (h2s->flags & (H2_SF_TUNNEL_ABRT|H2_SF_ES_SENT)) == (H2_SF_TUNNEL_ABRT|H2_SF_ES_SENT) &&
+	    ((h2c->dfl - h2c->dpl) || !(h2c->dff & H2_F_DATA_END_STREAM))) {
+		/* a tunnel attempt was aborted but the client still try to send some raw data.
+		 * Thus the stream is closed with the CANCEL error. Here we take care it is not
+		 * an empty DATA Frame with the ES flag. The error is only handled if ES was
+		 * already sent to the client because depending on the scheduling, these data may
+		 * have been sent before the server respnse but not handle here.
+		 */
+		TRACE_ERROR("Request DATA frame for aborted tunnel", H2_EV_RX_FRAME|H2_EV_RX_DATA, h2c->conn, h2s);
+		error = H2_ERR_CANCEL;
+		goto strm_err;
+	}
 
 	if (!h2_frt_transfer_data(h2s))
 		goto fail;
@@ -5537,6 +5550,22 @@
 		TRACE_STATE("Request DATA frame blocked waiting for tunnel establishment", H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
 		goto end;
 	}
+	else if ((h2c->flags & H2_CF_IS_BACK) && (h2s->flags & H2_SF_TUNNEL_ABRT)) {
+		/* a tunnel attempt was aborted but the is pending raw data to xfer to the server.
+		 * Thus the stream is closed with the CANCEL error. The error will be reported to
+		 * the upper layer as aserver abort. But at this stage there is nothing more we can
+		 * do. We just wait for the end of the response to be sure to not truncate it.
+		 */
+		if (!(h2s->flags & H2_SF_ES_RCVD)) {
+			TRACE_STATE("Request DATA frame blocked waiting end of aborted tunnel", H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
+			h2s->flags |= H2_SF_BLK_MBUSY;
+		}
+		else {
+			TRACE_ERROR("Request DATA frame for aborted tunnel", H2_EV_RX_FRAME|H2_EV_RX_DATA, h2c->conn, h2s);
+			h2s_error(h2s, H2_ERR_CANCEL);
+		}
+		goto end;
+	}
 
 	mbuf = br_tail(h2c->mbuf);
  retry: