]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Plug the QUIC_RSTREAM to the RX depacketizer
authorTomas Mraz <tomas@openssl.org>
Wed, 26 Oct 2022 16:35:04 +0000 (18:35 +0200)
committerHugo Landau <hlandau@openssl.org>
Mon, 14 Nov 2022 08:01:57 +0000 (08:01 +0000)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19351)

include/internal/quic_sf_list.h
include/internal/quic_ssl.h
include/internal/quic_stream.h
ssl/quic/quic_impl.c
ssl/quic/quic_local.h
ssl/quic/quic_rstream.c
ssl/quic/quic_rx_depack.c
ssl/quic/quic_sf_list.c

index 95c795038218fa5daabc70e5d80a5410d1539b92..5411cf6abfe48af933d34134b7b6e9beca4d4eb4 100644 (file)
@@ -17,7 +17,7 @@
  * Stream frame list
  * =================
  *
- * This data structure uses supports similar operations as uint64 set but
+ * This data structure supports similar operations as uint64 set but
  * it has slightly different invariants and also carries data associated with
  * the ranges in the list.
  *
index d9a0ade6d4839cc361913675526abb895fa5d370..03c30e25e1d8ed2b9ea16ba822904b4aa4b556e1 100644 (file)
@@ -37,6 +37,7 @@ __owur const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u);
 int ossl_quic_renegotiate_check(SSL *ssl, int initok);
 
 typedef struct quic_conn_st QUIC_CONNECTION;
+typedef struct quic_stream_st QUIC_STREAM;
 
 __owur QUIC_CONNECTION *ossl_quic_conn_from_ssl(SSL *ssl);
 int ossl_quic_conn_set_qrx(QUIC_CONNECTION *qc, OSSL_QRX *qrx);
index 82411d83a9f81018cce073c5e9879935a1b26937..cd3b810ae1ac1de0a237a50ecd775e6796eb78ec 100644 (file)
@@ -288,7 +288,7 @@ typedef struct quic_rstream_st QUIC_RSTREAM;
  * Create a new instance of QUIC_RSTREAM with pointers to the flow
  * controller and statistics module. They can be NULL for unit testing.
  * If they are non-NULL, the `rxfc` is called when receive stream data
- * is queued or read by application. `statm` is queried for current rtt.
+ * is read by application. `statm` is queried for current rtt.
  */
 QUIC_RSTREAM *ossl_quic_rstream_new(OSSL_QRX *qrx, QUIC_RXFC *rxfc,
                                     OSSL_STATM *statm);
index ed3b07e63d85dcdeb7765059303a354f11eaf896..856fa5e188a7f6e29ffba4a495070ccf44ddd49e 100644 (file)
@@ -21,7 +21,7 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
     if (qc == NULL)
         goto err;
 
-    ssl = &qc->ssl;
+    ssl = &qc->stream.ssl;
     if (!ossl_ssl_init(ssl, ctx, SSL_TYPE_QUIC_CONNECTION)) {
         OPENSSL_free(qc);
         ssl = NULL;
@@ -55,6 +55,7 @@ void ossl_quic_free(SSL *s)
     QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
 
     if (qc == NULL) {
+        /* TODO(QUIC): Temporarily needed to release the inner tls object */
         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
 
         if (sc != NULL)
@@ -71,6 +72,7 @@ int ossl_quic_reset(SSL *s)
     QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
 
     if (qc == NULL) {
+        /* TODO(QUIC): Temporarily needed to reset the inner tls object */
         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
 
         return sc != NULL ? ossl_ssl_connection_reset(s) : 0;
index 3305b03aec6db2e3f23360ee87928264bfa1d101..33301c9a13992a76c128acff0ba2bb325e55b242 100644 (file)
 
 # include <openssl/ssl.h>
 # include "internal/quic_ssl.h"       /* QUIC_CONNECTION */
+# include "internal/quic_fc.h"
+# include "internal/quic_stream.h"
 # include "../ssl_local.h"
 
-struct quic_conn_st {
-    /* type identifier and common data */
+struct quic_stream_st {
+    /* type identifier and common data for the public SSL object */
     struct ssl_st ssl;
+
+    /* QUIC_CONNECTION that this stream belongs to */
+    QUIC_CONNECTION *conn;
+    /* receive flow controller */
+    QUIC_RXFC *rxfc;
+    /* receive and send stream objects */
+    QUIC_RSTREAM *rstream;
+    QUIC_SSTREAM *sstream;
+};
+
+struct quic_conn_st {
+    /* QUIC connection is always a stream (the stream id 0) */
+    struct quic_stream_st stream;
     /* the associated tls-1.3 connection data */
     SSL *tls;
 
-    /* For QUIC, diverse handlers */
+    /* QUIC ack manager */
     OSSL_ACKM *ackm;
+    /* QUIC receive record layer */
     OSSL_QRX *qrx;
 };
 
@@ -31,6 +47,13 @@ struct quic_conn_st {
         ? (c QUIC_CONNECTION *)(ssl)            \
         : NULL))
 
+# define QUIC_STREAM_FROM_SSL_int(ssl, c)       \
+    ((ssl) == NULL ? NULL                       \
+     : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
+         || (ssl)->type == SSL_TYPE_QUIC_STREAM \
+        ? (c QUIC_STREAM *)(ssl)                \
+        : NULL))
+
 # define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c)               \
     ((ssl) == NULL ? NULL                                       \
      : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION                 \
@@ -41,6 +64,10 @@ struct quic_conn_st {
     QUIC_CONNECTION_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
 # define QUIC_CONNECTION_FROM_CONST_SSL(ssl) \
     QUIC_CONNECTION_FROM_SSL_int(ssl, const)
+# define QUIC_STREAM_FROM_SSL(ssl) \
+    QUIC_STREAM_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
+# define QUIC_STREAM_FROM_CONST_SSL(ssl) \
+    QUIC_STREAM_FROM_SSL_int(ssl, const)
 # define SSL_CONNECTION_FROM_QUIC_SSL(ssl) \
     SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
 # define SSL_CONNECTION_FROM_CONST_QUIC_SSL(ssl) \
index 9b4e6a2c51a785494380a76fac8b24a1a7cc2225..9c4b8b716b76fb4c08b9982e7fc1c74449d7d608 100644 (file)
@@ -10,8 +10,6 @@
 #include "internal/time.h"
 #include "internal/quic_stream.h"
 #include "internal/quic_sf_list.h"
-#include "internal/quic_fc.h"
-#include "internal/quic_error.h"
 
 struct quic_rstream_st {
     SFRAME_LIST fl;
@@ -49,12 +47,6 @@ int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT_WRAP *pkt_wrap,
     range.start = offset;
     range.end = offset + data_len;
 
-    if (qrs->rxfc != NULL
-        && (!ossl_quic_rxfc_on_rx_stream_frame(qrs->rxfc, range.end, fin)
-            || ossl_quic_rxfc_get_error(qrs->rxfc, 0) != QUIC_ERR_NO_ERROR))
-        /* QUIC_ERR_FLOW_CONTROL_ERROR or QUIC_ERR_FINAL_SIZE detected */
-        return 0;
-
     return ossl_sframe_list_insert(&qrs->fl, &range, pkt_wrap, data, fin);
 }
 
index 12a7b9c39e91b90a56ea20590d28ba701081e789..66d2edaaae05db78579244c611a8a019a11732cb 100644 (file)
@@ -14,6 +14,8 @@
 #include "internal/quic_ackm.h"
 #include "internal/quic_rx_depack.h"
 #include "internal/quic_record_rx_wrap.h"
+#include "internal/quic_error.h"
+#include "internal/quic_fc.h"
 #include "internal/sockets.h"
 
 #include "quic_local.h"
 # define GET_CONN_ACK_DELAY_EXP(c) 3
 #endif
 
-/* TODO(QUIC): [BEGIN: TO BE REMOVED] placeholder macros and functions */
-
-/* Diverse things that should be implemented elsewhere, bur currently aren't. */
-
-typedef struct quic_stream_st QUIC_STREAM;
-
 /*
- * TODO(QUIC): ASSUMPTION: ssl_get_stream() gets a QUIC_STREAM from a connection
- * by stream ID.  For now, we simply return a fake stream.
+ * TODO(QUIC): In MVP the QUIC_CONNECTION is the only supported stream.
  */
 static QUIC_STREAM *ssl_get_stream(QUIC_CONNECTION *conn, uint64_t stream_id)
 {
-    static uint64_t fake_stream = 0;
-
-    return (QUIC_STREAM *)&fake_stream;
+    return stream_id == 0 ? &conn->stream : NULL;
 }
 
 /*
@@ -68,9 +61,6 @@ static int ssl_get_stream_type(QUIC_STREAM *stream)
 }
 
 /*
- * TODO(QUIC): ASSUMPTION: ssl_queue_data() adds data to a QUIC_STREAM, to be
- * consumed by the application when doing an SSL_read().
- *
  * We assume that queuing of the data has to be done without copying, thus
  * we get the reference counting QRX packet wrapper so it can increment the
  * reference count.  When the data is consumed (i.e. as a result of, say,
@@ -80,23 +70,19 @@ static int ssl_queue_data(QUIC_STREAM *stream, OSSL_QRX_PKT_WRAP *pkt_wrap,
                           const unsigned char *data, uint64_t data_len,
                           uint64_t logical_offset, int is_fin)
 {
-    /*
-     * Since this function is just a placeholder that doesn't actually queue
-     * anything, we do nothing here, not even the reference count increment.
-     */
+    /* Notify stream flow controller */
+    if (stream->rxfc != NULL
+        && (!ossl_quic_rxfc_on_rx_stream_frame(stream->rxfc,
+                                               logical_offset + data_len,
+                                               is_fin)
+            || ossl_quic_rxfc_get_error(stream->rxfc, 0) != QUIC_ERR_NO_ERROR))
+        /* QUIC_ERR_FLOW_CONTROL_ERROR or QUIC_ERR_FINAL_SIZE detected */
+        return 0;
 
-    /*
-     * 1. Queuing the data and the parent packet wrapper should happen here,
-     *    and this call with it:
-     *
-     *        ossl_qrx_pkt_wrap_up_ref(pkt_wrap);
-     *
-     * 2. Dequeuing the data happens somewhere else, and this call with it
-     *    (|pkt_wrap| replaced with the pointer from the queue):
-     *
-     *        ossl_qrx_pkt_wrap_free(pkt_wrap);
-     */
-    return 1;
+    return stream->rstream == NULL
+           || ossl_quic_rstream_queue_data(stream->rstream, pkt_wrap,
+                                           logical_offset, data, data_len,
+                                           is_fin);
 }
 
 /*
index 43e6d3c5e888b5994a7007b1e91f41c0daf1beef..d382bd09041fdb0e5707c12b12be062e29cb17dc 100644 (file)
 #include "internal/quic_record_rx_wrap.h"
 #include "internal/quic_sf_list.h"
 
-/*
- * Stream frame list
- * =================
- *
- * This data structure uses supports similar operations as uint64 set but
- * it has slightly different invariants and also carries data associated with
- * the ranges in the list.
- *
- * Operations:
- *   Insert frame (optimized insertion at the beginning and at the end).
- *   Iterated peek into the frame(s) from the beginning.
- *   Dropping frames from the beginning up to an offset (exclusive).
- *
- * Invariant: The frames in the list are sorted by the start and end bounds.
- * Invariant: There are no fully overlapping frames or frames that would
- *            be fully encompassed by another frame in the list.
- * Invariant: No frame has start > end.
- * Invariant: The range start is inclusive the end is exclusive to be
- *            able to mark an empty frame.
- * Invariant: The offset never points further than into the first frame.
- */
-
 struct stream_frame_st {
     struct stream_frame_st *prev, *next;
     UINT_RANGE range;