MINOR: mux-quic: filter send/receive-only streams on frame parsing
Extend the function qcc_get_qcs() to be able to filter send/receive-only
unidirectional streams. A connection error STREAM_STATE_ERROR is emitted
if this new filter does not match.
This will be useful when various frames handlers are converted with
qcc_get_qcs(). Depending on the frame type, it will be easy to filter on
the forbidden stream types as specified in RFC 9000.
diff --git a/src/mux_quic.c b/src/mux_quic.c
index 0263c07..90d7945 100644
--- a/src/mux_quic.c
+++ b/src/mux_quic.c
@@ -430,17 +430,31 @@
/* Retrieve the stream instance from <id> ID. This can be used when receiving
* STREAM, STREAM_DATA_BLOCKED, RESET_STREAM, MAX_STREAM_DATA or STOP_SENDING
- * frames.
+ * frames. Set to false <receive_only> or <send_only> if these particular types
+ * of streams are not allowed.
*
* Return the stream instance or NULL if not found.
*/
-static struct qcs *qcc_get_qcs(struct qcc *qcc, uint64_t id)
+static struct qcs *qcc_get_qcs(struct qcc *qcc, uint64_t id,
+ int receive_only, int send_only)
{
struct eb64_node *node;
struct qcs *qcs = NULL;
TRACE_ENTER(QMUX_EV_QCC_RECV, qcc->conn);
+ if (!receive_only && quic_stream_is_uni(id) && quic_stream_is_remote(qcc, id)) {
+ TRACE_DEVEL("leaving on receive-only stream not allowed", QMUX_EV_QCC_RECV|QMUX_EV_QCC_NQCS, qcc->conn, NULL, &id);
+ qcc_emit_cc(qcc, QC_ERR_STREAM_STATE_ERROR);
+ return NULL;
+ }
+
+ if (!send_only && quic_stream_is_uni(id) && quic_stream_is_local(qcc, id)) {
+ TRACE_DEVEL("leaving on send-only stream not allowed", QMUX_EV_QCC_RECV|QMUX_EV_QCC_NQCS, qcc->conn, NULL, &id);
+ qcc_emit_cc(qcc, QC_ERR_STREAM_STATE_ERROR);
+ return NULL;
+ }
+
/* Search the stream in the connection tree. */
node = eb64_lookup(&qcc->streams_by_id, id);
if (node) {
@@ -610,13 +624,7 @@
* initiated stream that has not yet been created, or for a send-only
* stream.
*/
- if (quic_stream_is_local(qcc, id) && quic_stream_is_uni(id)) {
- qcc_emit_cc(qcc, QC_ERR_STREAM_STATE_ERROR);
- TRACE_DEVEL("leaving on invalid reception for a send-only stream", QMUX_EV_QCC_RECV|QMUX_EV_QCC_NQCS, qcc->conn, NULL, &id);
- return 1;
- }
-
- qcs = qcc_get_qcs(qcc, id);
+ qcs = qcc_get_qcs(qcc, id, 1, 0);
if (!qcs)
return 0;