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.
This commit is contained in:
Amaury Denoyelle 2026-05-26 11:22:16 +02:00
parent 8e77620616
commit d8460a5339

View file

@ -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 */