BUG/MEDIUM: h3: fix MAX_PUSH_ID handling

MAX_PUSH_ID frames are emitted by the client only on the control stream.
These conditions are checked via h3_check_frame_valid() since the
following patch.

  e4a5a64198
  BUG/MINOR: h3: reject server MAX_PUSH_ID frame

However control stream test was inverted by mistake. This patch fixes
it.

Due to this bug, H3 connections were improperly closed on error by
haproxy for clients which send MAX_PUSH_ID frames. This has been
detected on the QUIC interop with aioquic and neqo clients.

This must be backported up to 3.3.
This commit is contained in:
Amaury Denoyelle 2026-06-01 09:47:45 +02:00
parent c989d9da6d
commit 3a5189faba

View file

@ -403,13 +403,6 @@ static int h3_check_frame_valid(struct h3c *h3c, struct qcs *qcs, uint64_t ftype
* control stream as a connection error of type H3_FRAME_UNEXPECTED.
*/
/* RFC 9114 7.2.7. MAX_PUSH_ID
*
* The MAX_PUSH_ID frame is always sent on the control stream. Receipt
* of a MAX_PUSH_ID frame on any other stream MUST be treated as a
* connection error of type H3_FRAME_UNEXPECTED.
*/
if (h3s->type != H3S_T_CTRL)
ret = H3_ERR_FRAME_UNEXPECTED;
else if (!(h3c->flags & H3_CF_SETTINGS_RECV))
@ -459,7 +452,7 @@ static int h3_check_frame_valid(struct h3c *h3c, struct qcs *qcs, uint64_t ftype
* receipt of a MAX_PUSH_ID frame as a connection error of type
* H3_FRAME_UNEXPECTED.
*/
if (h3s->type == H3S_T_CTRL || conn_is_back(qcs->qcc->conn))
if (h3s->type != H3S_T_CTRL || conn_is_back(qcs->qcc->conn))
ret = H3_ERR_FRAME_UNEXPECTED;
else if (!(h3c->flags & H3_CF_SETTINGS_RECV))
ret = H3_ERR_MISSING_SETTINGS;