A connection freeze may occur if a QCS is released before transmitting
any data. This can happen when an error is detected early by the stream,
for example during HTTP response headers encoding, forcing the whole
connection closure.
In this case, a connection error is registered by the QUIC MUX to the
lower layer. MUX is then release and xprt layer is notified to prepare
CONNECTION_CLOSE emission. However, this is prevented because quic_conn
streams tree is not empty as it contains the qc_stream_desc previously
attached to the failed QCS instance. The connection will freeze until
QUIC idle timeout.
This situation is caused by an omission during qc_stream_desc release
operation. In the described situation, qc_stream_desc current buffer is
empty and can thus by removed, which is the purpose of this patch. This
unblocks this previously failed situation, with qc_stream_desc removal
from quic_conn tree.
This issue can be reproduced by modifying H3/QPACK code to return an
early error during HEADERS response processing.
This must be backported up to 2.6, after a period of observation.
BUG_ON(final_size > tail_offset);
/* Remove unsent data from current buffer. */
- if (final_size < tail_offset) {
+ if (final_size < tail_offset)
b_sub(buf, tail_offset - final_size);
- /* Remove buffer if all ACK already received. */
- if (!b_data(buf))
- qc_stream_buf_free(stream, &stream_buf);
- }
+
+ if (!b_data(buf))
+ qc_stream_buf_free(stream, &stream_buf);
/* A released stream does not use <stream.buf>. */
stream->buf = NULL;