mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-10 00:57:02 +02:00
QCS instances use qc_stream_desc for data buffering on emission. On stream reset, its Tx channel is closed earlier than expected. This may leave unsent data into qc_stream_desc. Before this patch, these unsent data would remain after QCS freeing. This prevents the buffer to be released as no ACK reception will remove them. The buffer is only freed when the whole connection is closed. As qc_stream_desc buffer is limited per connection, this reduces the buffer pool for other streams of the same connection. In the worst case if several streams are resetted, this may completely freeze the transfer of the remaining connection streams. This bug was reproduced by reducing the connection buffer pool to a single buffer instance by using the following global statement : tune.quic.frontend.conn-tx-buffers.limit 1. Then a QUIC client is used which opens a stream for a large enough object to ensure data are buffered. The client them emits a STOP_SENDING before reading all data, which forces the corresponding QCS instance to be resetted. The client then opens a new request but the transfer is freezed due to this bug. To fix this, adjust qc_stream_desc API. Add a new argument <final_size> on qc_stream_desc_release() function. Its value is compared to the currently buffered offset in latest qc_stream_desc buffer. If <final_size> is inferior, it means unsent data are present in the buffer. As such, qc_stream_desc_release() removes them to ensure the buffer will finally be freed when all ACKs are received. It is also possible that no data remains immediately, indicating that ACK were already received. As such, buffer instance is immediately removed by qc_stream_buf_free(). This must be backported up to 2.6. As this code section is known to regression, a period of observation could be reserved before distributing it on LTS releases.
24 lines
865 B
C
24 lines
865 B
C
#ifndef _HAPROXY_QUIC_STREAM_H_
|
|
#define _HAPROXY_QUIC_STREAM_H_
|
|
|
|
#ifdef USE_QUIC
|
|
|
|
#include <haproxy/mux_quic-t.h>
|
|
#include <haproxy/quic_stream-t.h>
|
|
|
|
struct quic_conn;
|
|
|
|
struct qc_stream_desc *qc_stream_desc_new(uint64_t id, enum qcs_type, void *ctx,
|
|
struct quic_conn *qc);
|
|
void qc_stream_desc_release(struct qc_stream_desc *stream, uint64_t final_size);
|
|
int qc_stream_desc_ack(struct qc_stream_desc **stream, size_t offset, size_t len);
|
|
void qc_stream_desc_free(struct qc_stream_desc *stream, int closing);
|
|
|
|
struct buffer *qc_stream_buf_get(struct qc_stream_desc *stream);
|
|
struct buffer *qc_stream_buf_alloc(struct qc_stream_desc *stream,
|
|
uint64_t offset, int *avail);
|
|
void qc_stream_buf_release(struct qc_stream_desc *stream);
|
|
|
|
#endif /* USE_QUIC */
|
|
#endif /* _HAPROXY_QUIC_STREAM_H_ */
|