diff --git a/src/h3.c b/src/h3.c index c412eb8ee..3e28c2e41 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1955,6 +1955,25 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin) h3s->st_req = H3S_ST_REQ_TRAILERS; } break; + case H3_FT_CANCEL_PUSH: + if (!conn_is_back(qcs->qcc->conn)) { + /* RFC 9114 7.2.3. CANCEL_PUSH + * + * If a server receives a CANCEL_PUSH frame for a push ID + * that has not yet been mentioned by a PUSH_PROMISE frame, this MUST be + * treated as a connection error of type H3_ID_ERROR. + */ + TRACE_ERROR("reject CANCEL_PUSH from client", H3_EV_RX_FRAME, qcs->qcc->conn, qcs); + qcc_set_error(qcs->qcc, H3_ERR_ID_ERROR, 1, + muxc_tevt_type_proto_err); + qcc_report_glitch(qcs->qcc, 1); + goto err; + } + else { + /* Not supported */ + ret = flen; + } + break; case H3_FT_GOAWAY: ret = h3_parse_goaway_frm(qcs->qcc->ctx, b, flen); if (ret < 0) { @@ -1963,7 +1982,6 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin) goto err; } break; - case H3_FT_CANCEL_PUSH: case H3_FT_PUSH_PROMISE: case H3_FT_MAX_PUSH_ID: /* Not supported */