mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-08 14:36:11 +02:00
BUG/MEDIUM: mux-h2: Properly consume padding for DATA frames
Since the commit 617592c9e ("MEDIUM: mux-h2: try to coalesce outgoing
WINDOW_UPDATE frames"), padding of DATA frames is no longer
consumed. Instead, this padidng is left in the demux buffer and used as the
header of the next frame. Because all bytes of the padding must be zero,
this lead to trigger a PROTOCOL_ERROR because haproxy erroneously thinks the
peer sent a DATA frame for the stream-id 0. It is true for a padding of 9
bytes or more, but similar issues may be exprienced with smaller padding.
Before the commit above, the padding was consumed in h2_process_demux to
restore the H2_CS_FRAME_H state at the end of the while loop processing
received frames.
However, it seems a bit strange to deal with the padding at this stage,
espcially because it is not obvious at all. So to fix the issue, the padding
is now consumed at the end of h2_frt_transfer_data(), inside "end_tranfer"
label. At the stage, we know all payload of the current DATA frame were
consumed and only the padding is still there, if any. We must only take care
to not consume more than available in the demux buffer. The padding may have
been partially received.
This patch should fix the issue #3354. It must be backported as far as 2.8.
This commit is contained in:
parent
72fd357814
commit
faf3e9ac3a
19
src/mux_h2.c
19
src/mux_h2.c
@ -6521,8 +6521,22 @@ try_again:
|
||||
|
||||
end_transfer:
|
||||
/* here we're done with the frame, all the payload (except padding) was
|
||||
* transferred.
|
||||
* transferred. So let's consume the padding now.
|
||||
*
|
||||
* The padding may not have been fully received, so we must take care to
|
||||
* not consume more than avaiable and eventually retry later.
|
||||
*/
|
||||
BUG_ON(h2c->dfl != h2c->dpl);
|
||||
flen = b_data(&h2c->dbuf);
|
||||
if (flen > h2c->dfl)
|
||||
flen = h2c->dfl;
|
||||
b_del(&h2c->dbuf, flen);
|
||||
h2c->dfl -= flen;
|
||||
h2c->dpl -= flen;
|
||||
h2c->rcvd_c += flen;
|
||||
h2c->rcvd_s += flen;
|
||||
if (h2c->dfl)
|
||||
goto fail;
|
||||
|
||||
if (!(h2s->flags & H2_SF_BODY_TUNNEL) && (h2c->dff & H2_F_DATA_END_STREAM)) {
|
||||
/* no more data are expected for this message. This add the EOM
|
||||
@ -6537,9 +6551,6 @@ try_again:
|
||||
}
|
||||
}
|
||||
|
||||
h2c->rcvd_c += h2c->dpl;
|
||||
h2c->rcvd_s += h2c->dpl;
|
||||
h2c->dpl = 0;
|
||||
h2c->st0 = H2_CS_FRAME_A; // send the corresponding window update
|
||||
htx_to_buf(htx, scbuf);
|
||||
TRACE_LEAVE(H2_EV_RX_FRAME|H2_EV_RX_DATA, h2c->conn, h2s);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user