return -1;
}
-/* Parse a SETTINGS frame of length <len> of payload <buf>.
+/* Parse a SETTINGS frame of length <len> and of payload <buf>. An empty frame
+ * is supported : this will leave the parameters to their default value.
*
* Returns the number of consumed bytes or a negative error code.
*/
b = b_make(b_orig(buf), b_size(buf), b_head_ofs(buf), len);
if (!b_quic_dec_int(&id, &b, &ret)) {
+ /* RFC 9114 7.1. Frame Layout
+ *
+ * Each frame's payload MUST contain exactly the fields identified in
+ * its description. A frame payload that contains additional bytes after
+ * the identified fields or a frame payload that terminates before the
+ * end of the identified fields MUST be treated as a connection error of
+ * type H3_FRAME_ERROR.
+ */
+ TRACE_ERROR("truncated GOAWAY frame", H3_EV_RX_FRAME, h3c->qcc->conn);
h3c->err = H3_ERR_FRAME_ERROR;
qcc_report_glitch(h3c->qcc, 1);
return -1;
}
break;
case H3_FT_CANCEL_PUSH:
+ if (unlikely(!flen)) {
+ /* RFC 9114 7.1. Frame Layout
+ *
+ * Each frame's payload MUST contain exactly the fields identified in
+ * its description. A frame payload that contains additional bytes after
+ * the identified fields or a frame payload that terminates before the
+ * end of the identified fields MUST be treated as a connection error of
+ * type H3_FRAME_ERROR.
+ */
+ TRACE_ERROR("truncated CANCEL_PUSH frame", 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;
+ }
+
if (!conn_is_back(qcs->qcc->conn)) {
/* RFC 9114 7.2.3. CANCEL_PUSH
*
/* h3_check_frame_valid() must reject on server side. */
BUG_ON(!conn_is_back(qcs->qcc->conn));
+ if (unlikely(!flen)) {
+ /* RFC 9114 7.1. Frame Layout
+ *
+ * Each frame's payload MUST contain exactly the fields identified in
+ * its description. A frame payload that contains additional bytes after
+ * the identified fields or a frame payload that terminates before the
+ * end of the identified fields MUST be treated as a connection error of
+ * type H3_FRAME_ERROR.
+ */
+ TRACE_ERROR("truncated PUSH_PROMISE frame", 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;
+ }
+
/* RFC 9114 7.2.5. PUSH_PROMISE
*
* A client MUST treat
/* h3_check_frame_valid() must reject on client side. */
BUG_ON(conn_is_back(qcs->qcc->conn));
+ if (unlikely(!flen)) {
+ /* RFC 9114 7.1. Frame Layout
+ *
+ * Each frame's payload MUST contain exactly the fields identified in
+ * its description. A frame payload that contains additional bytes after
+ * the identified fields or a frame payload that terminates before the
+ * end of the identified fields MUST be treated as a connection error of
+ * type H3_FRAME_ERROR.
+ */
+ TRACE_ERROR("truncated MAX_PUSH_ID frame", 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;
+ }
+
/* Not supported. */
ret = flen;
break;