MINOR: quic: Send STOP_SENDING frames if mux is released
If the connection client timeout has expired, the mux is released.
If the client decides to initiate a new request, we do not ack its
request. This leads the client to endlessly sent it request.
This patch makes a QUIC listener send a STOP_SENDING frame in such
a situation.
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index 16478d7..115339e 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -2379,6 +2379,35 @@
}
}
+/* Enqueue a STOP_SENDING frame to send into 1RTT packet number space
+ * frame list to send.
+ * Return 1 if succeeded, 0 if not.
+ */
+static int qc_stop_sending_frm_enqueue(struct quic_conn *qc, uint64_t id)
+{
+ struct quic_frame *frm;
+ struct quic_enc_level *qel = &qc->els[QUIC_TLS_ENC_LEVEL_APP];
+ uint64_t app_error_code;
+
+ /* TODO: the mux may be released, we cannot have more
+ * information about the application error code to send
+ * at this time.
+ */
+ app_error_code = H3_REQUEST_REJECTED;
+
+ frm = pool_zalloc(pool_head_quic_frame);
+ if (!frm)
+ return 0;
+
+ frm->type = QUIC_FT_STOP_SENDING;
+ frm->stop_sending.id = id;
+ frm->stop_sending.app_error_code = app_error_code;
+ LIST_INIT(&frm->reflist);
+ LIST_APPEND(&qel->pktns->tx.frms, &frm->list);
+
+ return 1;
+}
+
/* Parse all the frames of <pkt> QUIC packet for QUIC connection with <ctx>
* as I/O handler context and <qel> as encryption level.
* Returns 1 if succeeded, 0 if failed.
@@ -2521,6 +2550,9 @@
}
else {
TRACE_PROTO("Stream not found", QUIC_EV_CONN_PRSHPKT, qc);
+ if (!qc_stop_sending_frm_enqueue(qc, stream->id))
+ TRACE_PROTO("could not enqueue STOP_SENDING frame", QUIC_EV_CONN_PRSHPKT, qc);
+
goto err;
}
}