Skip to content

Commit 290c6a5

Browse files
committed
MINOR: quic: refactor acknowledgment for emitted STREAM
1 parent e8710a3 commit 290c6a5

File tree

3 files changed

+44
-39
lines changed

3 files changed

+44
-39
lines changed

include/haproxy/quic_stream.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
#include <haproxy/quic_stream-t.h>
88

99
struct quic_conn;
10+
struct quic_frame;
1011

1112
struct qc_stream_desc *qc_stream_desc_new(uint64_t id, enum qcs_type, void *ctx,
1213
struct quic_conn *qc);
1314
void qc_stream_desc_release(struct qc_stream_desc *stream, uint64_t final_size,
1415
void *new_ctx);
15-
int qc_stream_desc_ack(struct qc_stream_desc *stream, size_t offset, size_t len, int fin);
16+
int qc_stream_desc_ack(struct qc_stream_desc *stream, struct quic_frame *frm);
1617
void qc_stream_desc_free(struct qc_stream_desc *stream, int closing);
1718

1819
struct buffer *qc_stream_buf_get(struct qc_stream_desc *stream);

src/quic_rx.c

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,11 @@ static int quic_stream_try_to_consume(struct quic_conn *qc,
225225
while (frm_node) {
226226
struct qf_stream *strm_frm;
227227
struct quic_frame *frm;
228-
size_t offset, len;
229-
int fin;
228+
size_t offset;
230229

231230
strm_frm = eb64_entry(frm_node, struct qf_stream, offset);
232231
frm = container_of(strm_frm, struct quic_frame, stream);
233232
offset = strm_frm->offset.key;
234-
len = strm_frm->len;
235-
fin = frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT;
236233

237234
if (offset > stream->ack_offset)
238235
break;
@@ -241,13 +238,13 @@ static int quic_stream_try_to_consume(struct quic_conn *qc,
241238
* stream_buf instance is removed via qc_stream_desc_ack().
242239
*/
243240
eb64_delete(frm_node);
244-
qc_release_frm(qc, frm);
245241

246-
if (qc_stream_desc_ack(stream, offset, len, fin)) {
242+
if (qc_stream_desc_ack(stream, frm)) {
247243
TRACE_DEVEL("stream consumed", QUIC_EV_CONN_ACKSTRM,
248244
qc, strm_frm, stream);
249245
ret = 1;
250246
}
247+
qc_release_frm(qc, frm);
251248

252249
/* Always retrieve first buffer as the previously used
253250
* instance could have been removed during qc_stream_desc_ack().
@@ -284,9 +281,6 @@ static void qc_handle_newly_acked_frm(struct quic_conn *qc, struct quic_frame *f
284281
struct qf_stream *strm_frm = &frm->stream;
285282
struct eb64_node *node = NULL;
286283
struct qc_stream_desc *stream = NULL;
287-
const size_t offset = strm_frm->offset.key;
288-
const size_t len = strm_frm->len;
289-
const int fin = frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT;
290284
int ack;
291285

292286
/* do not use strm_frm->stream as the qc_stream_desc instance
@@ -306,31 +300,24 @@ static void qc_handle_newly_acked_frm(struct quic_conn *qc, struct quic_frame *f
306300
stream = eb64_entry(node, struct qc_stream_desc, by_id);
307301

308302
TRACE_DEVEL("acked stream", QUIC_EV_CONN_ACKSTRM, qc, strm_frm, stream);
309-
if (offset <= stream->ack_offset) {
310-
ack = qc_stream_desc_ack(stream, offset, len, fin);
311-
if (ack || fin) {
312-
TRACE_DEVEL("stream consumed", QUIC_EV_CONN_ACKSTRM,
313-
qc, strm_frm, stream);
303+
ack = qc_stream_desc_ack(stream, frm);
304+
if (!ack) {
305+
TRACE_DEVEL("stream consumed", QUIC_EV_CONN_ACKSTRM,
306+
qc, strm_frm, stream);
314307

315-
quic_stream_try_to_consume(qc, stream);
308+
quic_stream_try_to_consume(qc, stream);
316309

317-
if (qc_stream_desc_done(stream)) {
318-
/* no need to continue if stream freed. */
319-
TRACE_DEVEL("stream released and freed", QUIC_EV_CONN_ACKSTRM, qc);
320-
qc_check_close_on_released_mux(qc);
321-
}
310+
if (qc_stream_desc_done(stream)) {
311+
/* no need to continue if stream freed. */
312+
TRACE_DEVEL("stream released and freed", QUIC_EV_CONN_ACKSTRM, qc);
313+
qc_check_close_on_released_mux(qc);
322314
}
323315

324316
qc_release_frm(qc, frm);
325317
}
326318
else {
327-
struct qc_stream_buf *stream_buf;
328-
struct eb64_node *buf_node;
329-
330-
buf_node = eb64_lookup_le(&stream->buf_tree, offset);
331-
BUG_ON(!buf_node);
332-
stream_buf = eb64_entry(buf_node, struct qc_stream_buf, offset_node);
333-
eb64_insert(&stream_buf->acked_frms, &strm_frm->offset);
319+
TRACE_DEVEL("handled out-of-order stream ACK", QUIC_EV_CONN_ACKSTRM,
320+
qc, strm_frm, stream);
334321
}
335322
}
336323
break;

src/quic_stream.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <haproxy/mux_quic.h>
1010
#include <haproxy/pool.h>
1111
#include <haproxy/quic_conn.h>
12-
#include <haproxy/quic_frame.h>
12+
#include <haproxy/quic_frame-t.h>
1313
#include <haproxy/task.h>
1414

1515
DECLARE_STATIC_POOL(pool_head_quic_stream_desc, "qc_stream_desc",
@@ -134,26 +134,43 @@ void qc_stream_desc_release(struct qc_stream_desc *stream,
134134
}
135135
}
136136

137-
/* Acknowledge data at <offset> of length <len> for <stream> with <fin> set for
138-
* the final data.
137+
/* Acknowledge <frm> STREAM frame whose content is managed by <stream>
138+
* descriptor.
139139
*
140-
* Returns the count of byte removed from stream.
140+
* Returns 0 if the frame has been handled and can be removed.
141+
* Returns a positive value if the frame cannot be acknowledged and has been
142+
* buffered.
141143
*/
142-
int qc_stream_desc_ack(struct qc_stream_desc *stream, size_t offset, size_t len,
143-
int fin)
144+
int qc_stream_desc_ack(struct qc_stream_desc *stream, struct quic_frame *frm)
144145
{
146+
struct qf_stream *strm_frm = &frm->stream;
147+
uint64_t offset = strm_frm->offset.key;
148+
uint64_t len = strm_frm->len;
149+
int fin = frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT;
150+
145151
struct qc_stream_buf *stream_buf = NULL;
152+
struct eb64_node *buf_node;
146153
struct buffer *buf = NULL;
147154
size_t diff;
148155

149156
/* Cannot advertise FIN for an inferior data range. */
150157
BUG_ON(fin && offset + len < stream->ack_offset);
151158

152-
/* No support now for out-of-order ACK reporting. */
153-
BUG_ON(offset > stream->ack_offset);
154-
155-
if (offset + len < stream->ack_offset)
159+
if (offset + len < stream->ack_offset) {
156160
return 0;
161+
}
162+
else if (offset > stream->ack_offset) {
163+
buf_node = eb64_lookup_le(&stream->buf_tree, offset);
164+
if (buf_node) {
165+
stream_buf = eb64_entry(buf_node, struct qc_stream_buf, offset_node);
166+
eb64_insert(&stream_buf->acked_frms, &strm_frm->offset);
167+
return 1;
168+
}
169+
else {
170+
ABORT_NOW();
171+
return 0;
172+
}
173+
}
157174

158175
diff = offset + len - stream->ack_offset;
159176
if (diff) {
@@ -193,7 +210,7 @@ int qc_stream_desc_ack(struct qc_stream_desc *stream, size_t offset, size_t len,
193210
stream->flags &= ~QC_SD_FL_WAIT_FOR_FIN;
194211
}
195212

196-
return diff;
213+
return 0;
197214
}
198215

199216
/* Free the stream descriptor <stream> content. This function should be used

0 commit comments

Comments
 (0)