From 41caa219e58c6c0fbf418fbf91e8c698786295f1 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Fri, 27 Sep 2024 16:24:18 +0200 Subject: [PATCH] TMP MEDIUM: quic: decount buffer ack for MUX Tx window --- src/quic_rx.c | 9 +++++++ src/quic_stream.c | 60 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/quic_rx.c b/src/quic_rx.c index d74764977..a2e7d42fb 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -353,12 +353,16 @@ static void qc_handle_newly_acked_frm(struct quic_conn *qc, struct quic_frame *f qc_release_frm(qc, frm); } else { + uint64_t diff = strm_frm->len; + /* Loop until there is no overlap between current frame and a next entry. */ while (more_strm && strm_frm->offset.key + strm_frm->len >= more_strm->offset.key) { struct quic_frame *more_frm; struct eb64_node *next; + diff = diff - (strm_frm->offset.key + strm_frm->len - more_strm->offset.key); + more_frm = container_of(more_strm, struct quic_frame, stream); if (strm_frm->offset.key + strm_frm->len < more_strm->offset.key + more_strm->len) { /* Extend current frame to cover next entry. */ @@ -383,6 +387,8 @@ static void qc_handle_newly_acked_frm(struct quic_conn *qc, struct quic_frame *f less_strm->offset.key + less_strm->len >= strm_frm->offset.key) { struct quic_frame *less_frm; + diff = diff - (less_strm->offset.key + less_strm->len - strm_frm->offset.key); + /* Extend previous entry to cover fully the current frame. */ less_strm->len += (strm_frm->offset.key + strm_frm->len) - (less_strm->offset.key + less_strm->len); @@ -398,6 +404,9 @@ static void qc_handle_newly_acked_frm(struct quic_conn *qc, struct quic_frame *f else { eb64_insert(&stream_buf->acked_frms, &strm_frm->offset); } + + if (stream->notify_room && diff && stream->buf != stream_buf) + stream->notify_room(stream, diff); } } } diff --git a/src/quic_stream.c b/src/quic_stream.c index 8f15c6f54..4caff86d7 100644 --- a/src/quic_stream.c +++ b/src/quic_stream.c @@ -94,6 +94,10 @@ struct qc_stream_desc *qc_stream_desc_new(uint64_t id, enum qcs_type type, void void qc_stream_desc_release(struct qc_stream_desc *stream, uint64_t final_size, void *new_ctx) { + struct eb64_node *frm_node; + struct qf_stream *strm_frm; + uint64_t diff; + if (!stream) return; @@ -116,9 +120,18 @@ void qc_stream_desc_release(struct qc_stream_desc *stream, if (final_size < tail_offset) b_sub(buf, tail_offset - final_size); - if (stream->notify_room && b_room(buf)) { + if (stream->notify_room) { /* notify MUX about available buffers. */ - stream->notify_room(stream, b_room(buf)); + diff = b_room(&stream->buf->buf); + frm_node = eb64_first(&stream->buf->acked_frms); + while (frm_node) { + strm_frm = eb64_entry(frm_node, struct qf_stream, offset); + diff += strm_frm->len; + frm_node = eb64_next(frm_node); + } + + if (diff) + stream->notify_room(stream, diff); } if (!b_data(buf)) @@ -175,7 +188,27 @@ int qc_stream_desc_ack(struct qc_stream_desc *stream, size_t offset, size_t len, } else if (stream->buf != stream_buf) { /* inactive buffer, notify immediately about newly acknowledged data. */ - stream->notify_room(stream, diff); + struct qf_stream *strm_frm; + struct eb64_node *frm_node; + uint64_t diff_buffered = 0; + + frm_node = eb64_lookup_le(&stream_buf->acked_frms, offset); + if (frm_node) { + strm_frm = eb64_entry(frm_node, struct qf_stream, offset); + if (strm_frm->offset.key + strm_frm->len > offset) { + if (strm_frm->offset.key + strm_frm->len >= offset + len) { + diff_buffered = diff; + } + else { + diff_buffered = strm_frm->offset.key + strm_frm->len - offset; + } + } + } + + if (diff_buffered < diff) { + } + + stream->notify_room(stream, diff - diff_buffered); } } @@ -333,17 +366,28 @@ struct buffer *qc_stream_buf_realloc(struct qc_stream_desc *stream) */ void qc_stream_buf_release(struct qc_stream_desc *stream) { - struct buffer *buf; + struct qc_stream_buf *stream_buf = stream->buf; + struct eb64_node *frm_node; + struct qf_stream *strm_frm; + size_t diff; /* current buffer already released */ - BUG_ON(!stream->buf); + BUG_ON(!stream_buf); + + diff = b_room(&stream_buf->buf); + frm_node = eb64_first(&stream_buf->acked_frms); + while (frm_node) { + strm_frm = eb64_entry(frm_node, struct qf_stream, offset); + BUG_ON(strm_frm->offset.key < stream->ack_offset); + diff += strm_frm->len; + frm_node = eb64_next(frm_node); + } - buf = &stream->buf->buf; stream->buf = NULL; stream->buf_offset = 0; - if (stream->notify_room && b_room(buf)) - stream->notify_room(stream, b_room(buf)); + if (stream->notify_room && diff) + stream->notify_room(stream, diff); } static int create_sbuf_pool(void)