]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add stream type flags to SSL_accept_stream
authorAndrew Dinh <andrewd@openssl.org>
Tue, 24 Jun 2025 12:26:38 +0000 (19:26 +0700)
committerNeil Horman <nhorman@openssl.org>
Thu, 3 Jul 2025 00:55:24 +0000 (20:55 -0400)
Introduces SSL_ACCEPT_STREAM_UNI and SSL_ACCEPT_STREAM_BIDI flags to SSL_accept_stream, allowing callers to specify whether to accept only unidirectional or bidirectional streams. Returns the first of its type from the queue

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27883)

doc/man3/SSL_accept_stream.pod
include/internal/quic_stream_map.h
include/openssl/ssl.h.in
ssl/quic/quic_impl.c
ssl/quic/quic_stream_map.c
util/other.syms

index 7d62e34105b3fa0747fa62ac073aeaa2b2b03fa7..afbe0f5f055da01578d72b54a352e2bdb4b2783c 100644 (file)
@@ -10,6 +10,8 @@ accept an incoming QUIC stream from a QUIC peer
  #include <openssl/ssl.h>
 
  #define SSL_ACCEPT_STREAM_NO_BLOCK
+ #define SSL_ACCEPT_STREAM_UNI
+ #define SSL_ACCEPT_STREAM_BIDI
 
  SSL *SSL_accept_stream(SSL *ssl, uint64_t flags);
 
@@ -34,6 +36,13 @@ blocking mode (see L<SSL_set_blocking_mode(3)>), but this may be bypassed by
 passing the flag B<SSL_ACCEPT_STREAM_NO_BLOCK> in I<flags>. If this flag is set,
 this function never blocks.
 
+By default, this function will return the first incoming stream, whether it is
+unidirectional or bidirectional. Passing the flag B<SSL_ACCEPT_STREAM_UNI> or
+B<SSL_ACCEPT_STREAM_BIDI> will return the first stream that is unidirectional or
+bidirectional, respectively. If these flags are both set, either type can be
+returned. A NULL return value may mean that there are still streams that can
+be dequeued.
+
 Calling SSL_accept_stream() if there is no default stream already present
 inhibits the future creation of a default stream. See L<openssl-quic(7)>.
 
index 619a631cfcfb78ac4b9b7693ef93b8ef06c501d1..0e34ae4b4cbff4730be7525f50c59a055fb12a3b 100644 (file)
@@ -834,6 +834,13 @@ void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm,
  */
 QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm);
 
+/*
+ * Returns the next item to be popped from the accept queue matching the given
+ * stream type, or NULL if it there are no items that match.
+ */
+QUIC_STREAM *ossl_quic_stream_map_find_in_accept_queue(QUIC_STREAM_MAP *qsm,
+                                                       int is_uni);
+
 /*
  * Removes a stream from the accept queue. rtt is the estimated connection RTT.
  * The stream is retired for the purposes of MAX_STREAMS RXFC.
index aa17495eb88c7c14538e519d45459678209ddc02..f3c96fed164c795544cd3aadba6c2bf4bd74b216 100644 (file)
@@ -2357,6 +2357,8 @@ __owur SSL *SSL_new_stream(SSL *s, uint64_t flags);
 __owur int SSL_set_incoming_stream_policy(SSL *s, int policy, uint64_t aec);
 
 #define SSL_ACCEPT_STREAM_NO_BLOCK      (1U << 0)
+#define SSL_ACCEPT_STREAM_UNI           (1U << 1)
+#define SSL_ACCEPT_STREAM_BIDI          (1U << 2)
 __owur SSL *SSL_accept_stream(SSL *s, uint64_t flags);
 __owur size_t SSL_get_accept_stream_queue_len(SSL *s);
 
index e5fb74a634f4fa59d9021e9143fb5b5443449bf4..6e5970181c824205636c4f4da810f284d52aca8d 100644 (file)
@@ -3897,7 +3897,15 @@ SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags)
 
     qsm = ossl_quic_channel_get_qsm(ctx.qc->ch);
 
-    qs = ossl_quic_stream_map_peek_accept_queue(qsm);
+    if ((flags & SSL_ACCEPT_STREAM_UNI) && !(flags & SSL_ACCEPT_STREAM_BIDI)) {
+        qs = ossl_quic_stream_map_find_in_accept_queue(qsm, 1);
+    } else if ((flags & SSL_ACCEPT_STREAM_BIDI)
+               && !(flags & SSL_ACCEPT_STREAM_UNI)) {
+        qs = ossl_quic_stream_map_find_in_accept_queue(qsm, 0);
+    } else {
+        qs = ossl_quic_stream_map_peek_accept_queue(qsm);
+    }
+
     if (qs == NULL) {
         if (qctx_blocking(&ctx)
             && (flags & SSL_ACCEPT_STREAM_NO_BLOCK) == 0) {
index 64700b09d95e0a4dab2bc0b665cc12a7e49f534d..7162a53fbd6db294f3a1afc48b89556358f2a201 100644 (file)
@@ -734,6 +734,24 @@ QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm)
     return accept_head(&qsm->accept_list);
 }
 
+QUIC_STREAM *ossl_quic_stream_map_find_in_accept_queue(QUIC_STREAM_MAP *qsm,
+                                                       int is_uni)
+{
+    QUIC_STREAM *qs;
+
+    if (ossl_quic_stream_map_get_accept_queue_len(qsm, is_uni) == 0)
+        return NULL;
+
+    qs = ossl_quic_stream_map_peek_accept_queue(qsm);
+    while (qs != NULL) {
+        if ((is_uni && !ossl_quic_stream_is_bidi(qs))
+            || (!is_uni && ossl_quic_stream_is_bidi(qs)))
+            break;
+        qs = accept_next(&qsm->accept_list, qs);
+    }
+    return qs;
+}
+
 void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm,
                                             QUIC_STREAM *s)
 {
index 41d1a66e603392cbc8182267ab84f5e0df7c77bd..484f176c5f7cdc3be40c0c70451e8d2b57f45136 100644 (file)
@@ -762,6 +762,8 @@ SSL_STREAM_STATE_RESET_REMOTE           define
 SSL_STREAM_STATE_CONN_CLOSED            define
 SSL_ACCEPT_CONNECTION_NO_BLOCK          define
 SSL_ACCEPT_STREAM_NO_BLOCK              define
+SSL_ACCEPT_STREAM_UNI                   define
+SSL_ACCEPT_STREAM_BIDI                  define
 SSL_DEFAULT_STREAM_MODE_AUTO_BIDI       define
 SSL_DEFAULT_STREAM_MODE_AUTO_UNI        define
 SSL_DEFAULT_STREAM_MODE_NONE            define