diff --git a/include/haproxy/mux_quic.h b/include/haproxy/mux_quic.h index 56bbad5db..a5b105376 100644 --- a/include/haproxy/mux_quic.h +++ b/include/haproxy/mux_quic.h @@ -23,6 +23,7 @@ void qcs_notify_send(struct qcs *qcs); int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, char fin, char *data, struct qcs **out_qcs); int qcc_decode_qcs(struct qcc *qcc, struct qcs *qcs); +void qcc_streams_sent_done(struct qcs *qcs, uint64_t data, uint64_t offset); /* Bit shift to get the stream sub ID for internal use which is obtained * shifting the stream IDs by this value, knowing that the diff --git a/src/mux_quic.c b/src/mux_quic.c index 0f6f6b82b..e12edcc95 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -400,6 +400,19 @@ static int qcs_push_frame(struct qcs *qcs, struct buffer *payload, int fin, uint return -1; } +/* This function must be called by the upper layer to inform about the sending + * of a STREAM frame for instance. The frame is of length and on + * . + */ +void qcc_streams_sent_done(struct qcs *qcs, uint64_t data, uint64_t offset) +{ + /* check if the STREAM frame has already been notified. It can happen + * for retransmission. + */ + if (offset + data <= qcs->tx.sent_offset) + return; +} + /* Wrapper for send on transport layer. Send a list of frames for the * connection . * diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 7f3b02aeb..bfe888f3b 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -4889,6 +4889,10 @@ static inline int qc_build_frms(struct list *outlist, struct list *inlist, /* STREAM data have been consumed. */ LIST_DELETE(&cf->list); LIST_APPEND(outlist, &cf->list); + + qcc_streams_sent_done(cf->stream.qcs, + cf->stream.len, + cf->stream.offset.key); } else { struct quic_frame *new_cf; @@ -4920,7 +4924,20 @@ static inline int qc_build_frms(struct list *outlist, struct list *inlist, cf->stream.len -= dlen; cf->stream.offset.key += dlen; cf->stream.data = (unsigned char *)b_peek(&cf_buf, dlen); + + qcc_streams_sent_done(new_cf->stream.qcs, + new_cf->stream.len, + new_cf->stream.offset.key); } + + /* TODO the MUX is notified about the frame sending via + * previous qcc_streams_sent_done call. However, the + * sending can fail later, for example if the sendto + * system call returns an error. As the MUX has been + * notified, the transport layer is responsible to + * bufferize and resent the announced data later. + */ + break; default: