BUG/MINOR: mux-h2: commit the current stream ID even on reject
authorWilly Tarreau <w@1wt.eu>
Fri, 20 Oct 2023 15:51:12 +0000 (17:51 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Oct 2023 19:09:12 +0000 (21:09 +0200)
commit250b630fb933d652533487cba9e2ae448582b550
tree09b170d7651a9cc5c073f46cdedd0225308b4509
parent08f3bb5bd567fda7f326723eb0c7f94a930f638a
BUG/MINOR: mux-h2: commit the current stream ID even on reject

The H2 spec says that a HEADERS frame turns an idle stream to the open
state, and it may then turn to half-closed(remote) on ES, then to close,
all at once, if we respond with RST (e.g. on error). Due to the fact that
we process a complete frame at once since h2_dec_hdrs() may reassemble
CONTINUATION frames until everything is complete, the state was only
committed after the frame was completley valid (otherwise multiple passes
could result in subsequent frames being rejected as the stream ID would
be equal to the highest one).

However this is not correct because it means that a client may retry on
the same ID as a previously failed one, which technically is forbidden
(for example the client couldn't know which of them a WINDOW_UPDATE or
RST_STREAM frame is for).

In practice, due to the error paths, this would only be possible when
failing to decode HPACK while leaving the HPACK stream intact, thus
when the valid decoded HPACK stream cannot be turned into a valid HTTP
representation, e.g. when the resulting headers are too large for example.
The solution to avoid this consists in committing the stream ID on this
error path as well. h2spec continues to be happy.

Thanks to Annika Wickert and Tim Windelschmidt for reporting this issue.

This fix must be backported to all stable versions.
src/mux_h2.c