]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
QUIC FIFD: Add support for callback on frame ACK
authorHugo Landau <hlandau@openssl.org>
Tue, 18 Apr 2023 18:30:56 +0000 (19:30 +0100)
committerHugo Landau <hlandau@openssl.org>
Fri, 12 May 2023 13:47:13 +0000 (14:47 +0100)
We need to get acknowledgement notifications for our STOP_SENDING and
STREAM_RESET frames as this information is needed to know when we can
delete a QUIC_STREAM object.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20765)

include/internal/quic_fifd.h
include/internal/quic_stream_map.h
ssl/quic/quic_fifd.c
ssl/quic/quic_txp.c
test/quic_fifd_test.c

index ae9e32882aa2674e54d77dfbb52ab320e064418b..b395865f2ebd65cd08b28bd7aee3cfc45b559126 100644 (file)
@@ -37,6 +37,11 @@ struct quic_fifd_st {
                                  QUIC_TXPIM_PKT *pkt,
                                  void *arg);
     void           *regen_frame_arg;
+    void          (*confirm_frame)(uint64_t frame_type,
+                                   uint64_t stream_id,
+                                   QUIC_TXPIM_PKT *pkt,
+                                   void *arg);
+    void           *confirm_frame_arg;
     void          (*sstream_updated)(uint64_t stream_id,
                                    void *arg);
     void           *sstream_updated_arg;
@@ -57,6 +62,11 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd,
                                             QUIC_TXPIM_PKT *pkt,
                                             void *arg),
                         void *regen_frame_arg,
+                        void (*confirm_frame)(uint64_t frame_type,
+                                             uint64_t stream_id,
+                                             QUIC_TXPIM_PKT *pkt,
+                                             void *arg),
+                        void *confirm_frame_arg,
                         void (*sstream_updated)(uint64_t stream_id,
                                                 void *arg),
                         void *sstream_updated_arg);
index 152a21108dfdddff7fba2143f0423b1271d3d08d..0f2732a6fc92d50bdfa13ec6176107ec2ab1b3cb 100644 (file)
@@ -112,6 +112,10 @@ struct quic_stream_st {
     unsigned int    want_stop_sending       : 1; /* used for gen or regen */
     unsigned int    want_reset_stream       : 1; /* used for gen or regen */
 
+    /* Flags set when frames *we* sent were acknowledged. */
+    unsigned int    acked_stop_sending      : 1;
+    unsigned int    acked_reset_stream      : 1;
+
     /* A FIN has been retired from the rstream buffer. */
     unsigned int    recv_fin_retired        : 1;
 
index ced7e318139aa1682cd8eb296c77194ad5722bb1..8eca7520df239a31ab092f74b5cdab7d399a5480 100644 (file)
@@ -27,6 +27,11 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd,
                                             QUIC_TXPIM_PKT *pkt,
                                             void *arg),
                         void *regen_frame_arg,
+                        void (*confirm_frame)(uint64_t frame_type,
+                                              uint64_t stream_id,
+                                              QUIC_TXPIM_PKT *pkt,
+                                              void *arg),
+                        void *confirm_frame_arg,
                         void (*sstream_updated)(uint64_t stream_id,
                                                 void *arg),
                         void *sstream_updated_arg)
@@ -42,6 +47,8 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd,
     fifd->get_sstream_by_id_arg = get_sstream_by_id_arg;
     fifd->regen_frame           = regen_frame;
     fifd->regen_frame_arg       = regen_frame_arg;
+    fifd->confirm_frame         = confirm_frame;
+    fifd->confirm_frame_arg     = confirm_frame_arg;
     fifd->sstream_updated       = sstream_updated;
     fifd->sstream_updated_arg   = sstream_updated_arg;
     return 1;
@@ -75,6 +82,16 @@ static void on_acked(void *arg)
 
         if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX)
             ossl_quic_sstream_mark_acked_fin(sstream);
+
+        if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX)
+            fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
+                                chunks[i].stream_id, pkt,
+                                fifd->confirm_frame_arg);
+
+        if (chunks[i].has_reset_stream && chunks[i].stream_id != UINT64_MAX)
+            fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
+                                chunks[i].stream_id, pkt,
+                                fifd->confirm_frame_arg);
     }
 
     /* GCR */
index 10a1a5f18eac583a8f02cd5b496ade00e6b885c5..a1341d8b13e16a35d99f9d228401154be15acbff 100644 (file)
@@ -310,6 +310,8 @@ static QUIC_SSTREAM *get_sstream_by_id(uint64_t stream_id, uint32_t pn_space,
                                        void *arg);
 static void on_regen_notify(uint64_t frame_type, uint64_t stream_id,
                             QUIC_TXPIM_PKT *pkt, void *arg);
+static void on_confirm_notify(uint64_t frame_type, uint64_t stream_id,
+                              QUIC_TXPIM_PKT *pkt, void *arg);
 static void on_sstream_updated(uint64_t stream_id, void *arg);
 static int sstream_is_pending(QUIC_SSTREAM *sstream);
 static int txp_el_pending(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level,
@@ -369,6 +371,7 @@ OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETIS
                              txp->args.cfq, txp->args.ackm, txp->args.txpim,
                              get_sstream_by_id, txp,
                              on_regen_notify, txp,
+                             on_confirm_notify, txp,
                              on_sstream_updated, txp)) {
         OPENSSL_free(txp);
         return NULL;
@@ -1129,6 +1132,42 @@ static void on_regen_notify(uint64_t frame_type, uint64_t stream_id,
     }
 }
 
+static void on_confirm_notify(uint64_t frame_type, uint64_t stream_id,
+                              QUIC_TXPIM_PKT *pkt, void *arg)
+{
+    OSSL_QUIC_TX_PACKETISER *txp = arg;
+
+    switch (frame_type) {
+        case OSSL_QUIC_FRAME_TYPE_STOP_SENDING:
+            {
+                QUIC_STREAM *s
+                    = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id);
+
+                if (s == NULL)
+                    return;
+
+                s->acked_stop_sending = 1;
+                ossl_quic_stream_map_update_state(txp->args.qsm, s);
+            }
+            break;
+        case OSSL_QUIC_FRAME_TYPE_RESET_STREAM:
+            {
+                QUIC_STREAM *s
+                    = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id);
+
+                if (s == NULL)
+                    return;
+
+                s->acked_reset_stream = 1;
+                ossl_quic_stream_map_update_state(txp->args.qsm, s);
+            }
+            break;
+        default:
+            assert(0);
+            break;
+    }
+}
+
 static void on_sstream_updated(uint64_t stream_id, void *arg)
 {
     OSSL_QUIC_TX_PACKETISER *txp = arg;
index ccf01fb89b4f49d71b8444bac7b0c81f7a2213b8..bb0cd77105c7ccbdca4e2f7e8fed63d523eee9a9 100644 (file)
@@ -40,6 +40,10 @@ static void regen_frame(uint64_t frame_type, uint64_t stream_id,
     regen_frame_p(frame_type, stream_id, pkt, arg);
 }
 
+static void confirm_frame(uint64_t frame_type, uint64_t stream_id,
+                          QUIC_TXPIM_PKT *pkt, void *arg)
+{}
+
 static void sstream_updated(uint64_t stream_id, void *arg)
 {}
 
@@ -333,6 +337,7 @@ static int test_fifd(int idx)
                                           info.txpim,
                                           get_sstream_by_id, NULL,
                                           regen_frame, NULL,
+                                          confirm_frame, NULL,
                                           sstream_updated, NULL)))
         goto err;