From d8460a5339e64b1c16fdaa7cefb11e21fb62eacd Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 26 May 2026 11:22:16 +0200 Subject: [PATCH] BUG/MINOR: h3: reject client CANCEL_PUSH frame CANCEL_PUSH frames are silently ignored on both client and server sides. However, as push support is not implemented by haproxy, clients are thus forbidden to emit any of those frames. Fix this by closing the connection with ID_ERROR when receiving a client CANCEL_PUSH as a server. On client side, the frame is still silently discarded. This must be backported up to 2.6. --- src/h3.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) 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 */