enum h3s_t type;
enum h3s_st_req st_req; /* only used for request streams */
- uint64_t demux_frame_len;
- uint64_t demux_frame_type;
+ uint64_t demux_frame_len; /* current parser frame remaining content to read */
+ uint64_t demux_frame_type; /* current parser frame type */
unsigned long long body_len; /* known request body length from content-length header if present */
unsigned long long data_len; /* total length of all parsed DATA */
goto err;
}
- if (!b_data(b) && fin && quic_stream_is_bidi(qcs->id)) {
+ if (!b_data(b) && fin) {
TRACE_PROTO("received FIN without data", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
+ /* RFC 9114 7.1. Frame Layout
+ *
+ * When a stream terminates cleanly, if the last frame on the stream was
+ * truncated, this MUST be treated as a connection error of type
+ * H3_FRAME_ERROR.
+ */
+ if (h3s->demux_frame_len) {
+ TRACE_ERROR("truncated frame on FIN", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
+ qcc_set_error(qcs->qcc, H3_ERR_FRAME_ERROR, 1, muxc_tevt_type_proto_err);
+ qcc_report_glitch(qcs->qcc, 1);
+ goto err;
+ }
+
/* FIN received, ensure body length is conform to any content-length header. */
if ((h3s->flags & H3_SF_HAVE_CLEN) && h3_check_body_size(qcs, 1)) {
qcc_abort_stream_read(qcs, h3s->err);
goto done;
}
- if (qcs_http_handle_standalone_fin(qcs)) {
+ if (quic_stream_is_bidi(qcs->id) && qcs_http_handle_standalone_fin(qcs)) {
TRACE_ERROR("cannot set EOM", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
qcc_set_error(qcs->qcc, H3_ERR_INTERNAL_ERROR, 1,
muxc_tevt_type_internal_err);
break;
}
+ /* RFC 9114 7.1. Frame Layout
+ *
+ * When a stream terminates cleanly, if the last frame on the stream was
+ * truncated, this MUST be treated as a connection error of type
+ * H3_FRAME_ERROR.
+ */
+ if (fin && h3s->demux_frame_len > b_data(b)) {
+ TRACE_ERROR("truncated frame on FIN", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
+ qcc_set_error(qcs->qcc, H3_ERR_FRAME_ERROR, 1, muxc_tevt_type_proto_err);
+ qcc_report_glitch(qcs->qcc, 1);
+ goto err;
+ }
+
flen = h3s->demux_frame_len;
ftype = h3s->demux_frame_type;