BUG/MINOR: quic: Dropped retransmitted STREAM frames

It is possible that we continue to receive retransmitted STREAM frames after
the mux have been released. We rely on the ->rx.streams[].nb_streams counter
to check the stream was closed. If not, at this time we drop the packet.
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index a83fb0c..524c42d 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -2689,6 +2689,7 @@
 		case QUIC_FT_STREAM_8 ... QUIC_FT_STREAM_F:
 		{
 			struct quic_stream *stream = &frm.stream;
+			unsigned nb_streams = qc->rx.strms[qcs_id_type(stream->id)].nb_streams;
 
 			if (qc_is_listener(ctx->qc)) {
 				if (stream->id & QUIC_STREAM_FRAME_ID_INITIATOR_BIT)
@@ -2696,12 +2697,17 @@
 			} else if (!(stream->id & QUIC_STREAM_FRAME_ID_INITIATOR_BIT))
 				goto err;
 
-			/* The upper layer may not be allocated.
-			 *
-			 * TODO emit a CONNECTION_CLOSE if mux already freed.
-			 */
-			if (qc->mux_state != QC_MUX_READY)
-				goto err;
+			/* The upper layer may not be allocated. */
+			if (qc->mux_state != QC_MUX_READY) {
+				if ((stream->id >> QCS_ID_TYPE_SHIFT) < nb_streams) {
+					TRACE_PROTO("Already closed stream", QUIC_EV_CONN_PRSHPKT, qc);
+					break;
+				}
+				else {
+					TRACE_PROTO("Stream not found", QUIC_EV_CONN_PRSHPKT, qc);
+					goto err;
+				}
+			}
 
 			if (!qc_handle_strm_frm(pkt, stream, qc))
 				goto err;