haproxy/include/haproxy/quic_stream.h
Amaury Denoyelle e7578084b0 MINOR: quic: implement dedicated type for out-of-order stream ACK
QUIC streamdesc layer is responsible to handle reception of ACK for
streams. It removes stream data from the underlying buffers on ACK
reception.

Streamdesc layer treats ACK in order at the stream level. Out of order
ACKs are buffered in a tree until they can be handled on older data
acknowledgement reception. Previously, qf_stream instance which comes
from the quic_tx_packet was used as tree node to buffer such ranges.

Introduce a new type dedicated to represent out of order stream ack data
range. This type is named qc_stream_ack. It contains minimal infos only
relative to the acknowledged stream data range.

This allows to reduce size of frequently used quic_frame with the
removal of tree node from qf_stream. Another side effect of this change
is that now quic_frame are always released immediately on ACK reception,
both in-order and out-of-order. This allows to also release the
quic_tx_packet instance which should reduce memory consumption.

The drawback of this change is that qc_stream_ack instance must be
allocated on out-of-order ACK reception. As such, qc_stream_desc_ack()
may fail if an error happens on allocation. For the moment, such error
is silenly recovered up to qc_treat_rx_pkts() with the dropping of the
received packet containing the ACK frame. In the future, it may be
useful to close the connection as this error may only happens on low
memory usage.
2024-10-04 17:56:45 +02:00

58 lines
2.1 KiB
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,
void *new_ctx);
int qc_stream_desc_ack(struct qc_stream_desc *stream,
uint64_t offset, uint64_t len, int fin);
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 small);
struct buffer *qc_stream_buf_realloc(struct qc_stream_desc *stream);
void qc_stream_buf_release(struct qc_stream_desc *stream);
/* Returns true if nothing to ack yet for stream <s> including FIN bit. */
static inline int qc_stream_desc_done(const struct qc_stream_desc *s)
{
return (s->flags & (QC_SD_FL_RELEASE|QC_SD_FL_WAIT_FOR_FIN)) == QC_SD_FL_RELEASE &&
eb_is_empty(&s->buf_tree);
}
/* Reports emission of STREAM frame starting at <offset> and of length <len>,
* related to <stream> data storage.
*/
static inline void qc_stream_desc_send(struct qc_stream_desc *stream,
uint64_t offset, uint64_t len)
{
if (stream->notify_send)
stream->notify_send(stream, len, offset);
}
/* Subscribe for send notification on <stream>. */
static inline void qc_stream_desc_sub_send(struct qc_stream_desc *stream,
void (*cb)(struct qc_stream_desc *s, uint64_t offset, uint64_t len))
{
stream->notify_send = cb;
}
/* Subscribe for room notification on <stream>. */
static inline void qc_stream_desc_sub_room(struct qc_stream_desc *stream,
void (*cb)(struct qc_stream_desc *s, uint64_t offset))
{
stream->notify_room = cb;
}
#endif /* USE_QUIC */
#endif /* _HAPROXY_QUIC_STREAM_H_ */