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)
#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);
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)>.
*/
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.
__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);
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) {
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)
{
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