]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: implement qc_notify_send()
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 28 Feb 2023 14:08:59 +0000 (15:08 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 1 Mar 2023 13:29:16 +0000 (14:29 +0100)
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
src/quic_conn.c

index 9060acdc9b436cab9ab1723a1f8b11765bcb7ba6..8b7a43a5f35aee0f202161f9e94bffb5007aaac9 100644 (file)
@@ -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);
 
index 6fd10cc70a49b032cdc63f95241236911da492ea..8c7676ac97e765a4727ce66c5c50f9d9239a0984 100644 (file)
@@ -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 {