From e0fe118dad6cf78c3e563aff9726b8e015d87340 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 28 Feb 2023 15:08:59 +0100 Subject: [PATCH] MINOR: quic: implement qc_notify_send() Implement qc_notify_send(). This function is responsible to notify the upper layer subscribed on SUB_RETRY_SEND if sending condition are back to normal. For the moment, this patch has no functional change as only congestion window room is checked before notifying the upper layer. However, this will be extended when poller subscribe of socket on sendto() error will be implemented. qc_notify_send() will thus be responsible to ensure that all condition are met before wake up the upper layer. This should be backported up to 2.7. --- include/haproxy/quic_conn.h | 1 + src/quic_conn.c | 44 +++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/include/haproxy/quic_conn.h b/include/haproxy/quic_conn.h index 9060acdc9..8b7a43a5f 100644 --- a/include/haproxy/quic_conn.h +++ b/include/haproxy/quic_conn.h @@ -712,6 +712,7 @@ int quic_get_dgram_dcid(unsigned char *buf, const unsigned char *end, int qc_send_mux(struct quic_conn *qc, struct list *frms); void qc_notify_close(struct quic_conn *qc); +int qc_notify_send(struct quic_conn *qc); void qc_release_frm(struct quic_conn *qc, struct quic_frame *frm); diff --git a/src/quic_conn.c b/src/quic_conn.c index 6fd10cc70..8c7676ac9 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -1699,11 +1699,8 @@ static int quic_stream_try_to_consume(struct quic_conn *qc, static inline void qc_treat_acked_tx_frm(struct quic_conn *qc, struct quic_frame *frm) { - int stream_acked; - TRACE_ENTER(QUIC_EV_CONN_PRSAFRM, qc, frm); - stream_acked = 0; switch (frm->type) { case QUIC_FT_STREAM_8 ... QUIC_FT_STREAM_F: { @@ -1732,7 +1729,6 @@ static inline void qc_treat_acked_tx_frm(struct quic_conn *qc, TRACE_DEVEL("acked stream", QUIC_EV_CONN_ACKSTRM, qc, strm_frm, stream); if (offset <= stream->ack_offset) { if (qc_stream_desc_ack(&stream, offset, len)) { - stream_acked = 1; TRACE_DEVEL("stream consumed", QUIC_EV_CONN_ACKSTRM, qc, strm_frm, stream); } @@ -1753,21 +1749,13 @@ static inline void qc_treat_acked_tx_frm(struct quic_conn *qc, eb64_insert(&stream->acked_frms, &strm_frm->offset); } - stream_acked |= quic_stream_try_to_consume(qc, stream); + quic_stream_try_to_consume(qc, stream); } break; default: qc_release_frm(qc, frm); } - if (stream_acked) { - if (qc->subs && qc->subs->events & SUB_RETRY_SEND) { - tasklet_wakeup(qc->subs->tasklet); - qc->subs->events &= ~SUB_RETRY_SEND; - if (!qc->subs->events) - qc->subs = NULL; - } - } leave: TRACE_LEAVE(QUIC_EV_CONN_PRSAFRM, qc); } @@ -2238,6 +2226,7 @@ static inline int qc_parse_ack_frm(struct quic_conn *qc, if (quic_peer_validated_addr(qc)) qc->path->loss.pto_count = 0; qc_set_timer(qc); + qc_notify_send(qc); } ret = 1; @@ -4818,14 +4807,7 @@ struct task *qc_process_timer(struct task *task, void *ctx, unsigned int state) if (qc->path->in_flight) { pktns = quic_pto_pktns(qc, qc->state >= QUIC_HS_ST_CONFIRMED, NULL); - if (qc->subs && qc->subs->events & SUB_RETRY_SEND) { - pktns->tx.pto_probe = QUIC_MAX_NB_PTO_DGRAMS; - tasklet_wakeup(qc->subs->tasklet); - qc->subs->events &= ~SUB_RETRY_SEND; - if (!qc->subs->events) - qc->subs = NULL; - } - else { + if (!qc_notify_send(qc)) { if (pktns == &qc->pktns[QUIC_TLS_PKTNS_INITIAL]) { if (qc_may_probe_ipktns(qc)) { qc->flags |= QUIC_FL_CONN_RETRANS_NEEDED; @@ -7770,6 +7752,26 @@ void qc_notify_close(struct quic_conn *qc) TRACE_LEAVE(QUIC_EV_CONN_CLOSE, qc); } +/* Wake-up upper layer if waiting for send to be ready. + * + * Returns 1 if upper layer has been woken up else 0. + */ +int qc_notify_send(struct quic_conn *qc) +{ + if (qc->subs && qc->subs->events & SUB_RETRY_SEND) { + if (quic_path_prep_data(qc->path)) { + tasklet_wakeup(qc->subs->tasklet); + qc->subs->events &= ~SUB_RETRY_SEND; + if (!qc->subs->events) + qc->subs = NULL; + + return 1; + } + } + + return 0; +} + /* appctx context used by "show quic" command */ struct show_quic_ctx {