Path: blob/main/crypto/openssl/ssl/quic/quic_impl.c
48266 views
/*1* Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <openssl/macros.h>10#include <openssl/objects.h>11#include <openssl/sslerr.h>12#include <crypto/rand.h>13#include "quic_local.h"14#include "internal/hashfunc.h"15#include "internal/ssl_unwrap.h"16#include "internal/quic_tls.h"17#include "internal/quic_rx_depack.h"18#include "internal/quic_error.h"19#include "internal/quic_engine.h"20#include "internal/quic_port.h"21#include "internal/quic_reactor_wait_ctx.h"22#include "internal/time.h"2324typedef struct qctx_st QCTX;2526static void qc_cleanup(QUIC_CONNECTION *qc, int have_lock);27static void aon_write_finish(QUIC_XSO *xso);28static int create_channel(QUIC_CONNECTION *qc, SSL_CTX *ctx);29static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs);30static QUIC_CONNECTION *create_qc_from_incoming_conn(QUIC_LISTENER *ql, QUIC_CHANNEL *ch);31static int qc_try_create_default_xso_for_write(QCTX *ctx);32static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek);33static void qctx_lock(QCTX *qctx);34static void qctx_unlock(QCTX *qctx);35static void qctx_lock_for_io(QCTX *ctx);36static int quic_do_handshake(QCTX *ctx);37static void qc_update_reject_policy(QUIC_CONNECTION *qc);38static void qc_touch_default_xso(QUIC_CONNECTION *qc);39static void qc_set_default_xso(QUIC_CONNECTION *qc, QUIC_XSO *xso, int touch);40static void qc_set_default_xso_keep_ref(QUIC_CONNECTION *qc, QUIC_XSO *xso,41int touch, QUIC_XSO **old_xso);42static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock);43static int quic_validate_for_write(QUIC_XSO *xso, int *err);44static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active);45static void qctx_maybe_autotick(QCTX *ctx);46static int qctx_should_autotick(QCTX *ctx);4748/*49* QCTX is a utility structure which provides information we commonly wish to50* unwrap upon an API call being dispatched to us, namely:51*52* - a pointer to the QUIC_CONNECTION (regardless of whether a QCSO or QSSO53* was passed);54* - a pointer to any applicable QUIC_XSO (e.g. if a QSSO was passed, or if55* a QCSO with a default stream was passed);56* - whether a QSSO was passed (xso == NULL must not be used to determine this57* because it may be non-NULL when a QCSO is passed if that QCSO has a58* default stream);59* - a pointer to a QUIC_LISTENER object, if one is relevant;60* - whether we are in "I/O context", meaning that non-normal errors can61* be reported via SSL_get_error() as well as via ERR. Functions such as62* SSL_read(), SSL_write() and SSL_do_handshake() are "I/O context"63* functions which are allowed to change the value returned by64* SSL_get_error. However, other functions (including functions which call65* SSL_do_handshake() implicitly) are not allowed to change the return value66* of SSL_get_error.67*/68struct qctx_st {69QUIC_OBJ *obj;70QUIC_DOMAIN *qd;71QUIC_LISTENER *ql;72QUIC_CONNECTION *qc;73QUIC_XSO *xso;74int is_stream, is_listener, is_domain, in_io;75};7677QUIC_NEEDS_LOCK78static void quic_set_last_error(QCTX *ctx, int last_error)79{80if (!ctx->in_io)81return;8283if (ctx->is_stream && ctx->xso != NULL)84ctx->xso->last_error = last_error;85else if (!ctx->is_stream && ctx->qc != NULL)86ctx->qc->last_error = last_error;87}8889/*90* Raise a 'normal' error, meaning one that can be reported via SSL_get_error()91* rather than via ERR. Note that normal errors must always be raised while92* holding a lock.93*/94QUIC_NEEDS_LOCK95static int quic_raise_normal_error(QCTX *ctx,96int err)97{98assert(ctx->in_io);99quic_set_last_error(ctx, err);100101return 0;102}103104/*105* Raise a 'non-normal' error, meaning any error that is not reported via106* SSL_get_error() and must be reported via ERR.107*108* qc should be provided if available. In exceptional circumstances when qc is109* not known NULL may be passed. This should generally only happen when an110* expect_...() function defined below fails, which generally indicates a111* dispatch error or caller error.112*113* ctx should be NULL if the connection lock is not held.114*/115static int quic_raise_non_normal_error(QCTX *ctx,116const char *file,117int line,118const char *func,119int reason,120const char *fmt,121...)122{123va_list args;124125if (ctx != NULL) {126quic_set_last_error(ctx, SSL_ERROR_SSL);127128if (reason == SSL_R_PROTOCOL_IS_SHUTDOWN && ctx->qc != NULL)129ossl_quic_channel_restore_err_state(ctx->qc->ch);130}131132ERR_new();133ERR_set_debug(file, line, func);134135va_start(args, fmt);136ERR_vset_error(ERR_LIB_SSL, reason, fmt, args);137va_end(args);138139return 0;140}141142#define QUIC_RAISE_NORMAL_ERROR(ctx, err) \143quic_raise_normal_error((ctx), (err))144145#define QUIC_RAISE_NON_NORMAL_ERROR(ctx, reason, msg) \146quic_raise_non_normal_error((ctx), \147OPENSSL_FILE, OPENSSL_LINE, \148OPENSSL_FUNC, \149(reason), \150(msg))151/*152* Flags for expect_quic_as:153*154* QCTX_C155* The input SSL object may be a QCSO.156*157* QCTX_S158* The input SSL object may be a QSSO or a QCSO with a default stream159* attached.160*161* (Note this means there is no current way to require an SSL object with a162* QUIC stream which is not a QCSO; a QCSO with a default stream attached163* is always considered to satisfy QCTX_S.)164*165* QCTX_AUTO_S166* The input SSL object may be a QSSO or a QCSO with a default stream167* attached. If no default stream is currently attached to a QCSO,168* one may be auto-created if possible.169*170* If QCTX_REMOTE_INIT is set, an auto-created default XSO is171* initiated by the remote party (i.e., local party reads first).172*173* If it is not set, an auto-created default XSO is174* initiated by the local party (i.e., local party writes first).175*176* QCTX_L177* The input SSL object may be a QLSO.178*179* QCTX_LOCK180* If and only if the function returns successfully, the ctx181* is guaranteed to be locked.182*183* QCTX_IO184* Begin an I/O context. If not set, begins a non-I/O context.185* This determines whether SSL_get_error() is updated; the value it returns186* is modified only by an I/O call.187*188* QCTX_NO_ERROR189* Don't raise an error if the object type is wrong. Should not be used in190* conjunction with any flags that may raise errors not related to a wrong191* object type.192*/193#define QCTX_C (1U << 0)194#define QCTX_S (1U << 1)195#define QCTX_L (1U << 2)196#define QCTX_AUTO_S (1U << 3)197#define QCTX_REMOTE_INIT (1U << 4)198#define QCTX_LOCK (1U << 5)199#define QCTX_IO (1U << 6)200#define QCTX_D (1U << 7)201#define QCTX_NO_ERROR (1U << 8)202203/*204* Called when expect_quic failed. Used to diagnose why such a call failed and205* raise a reasonable error code based on the configured preconditions in flags.206*/207static int wrong_type(const SSL *s, uint32_t flags)208{209const uint32_t mask = QCTX_C | QCTX_S | QCTX_L | QCTX_D;210int code = ERR_R_UNSUPPORTED;211212if ((flags & QCTX_NO_ERROR) != 0)213return 1;214else if ((flags & mask) == QCTX_D)215code = SSL_R_DOMAIN_USE_ONLY;216else if ((flags & mask) == QCTX_L)217code = SSL_R_LISTENER_USE_ONLY;218else if ((flags & mask) == QCTX_C)219code = SSL_R_CONN_USE_ONLY;220else if ((flags & mask) == QCTX_S221|| (flags & mask) == (QCTX_C | QCTX_S))222code = SSL_R_NO_STREAM;223224return QUIC_RAISE_NON_NORMAL_ERROR(NULL, code, NULL);225}226227/*228* Given a QDSO, QCSO, QSSO or QLSO, initialises a QCTX, determining the229* contextually applicable QUIC_LISTENER, QUIC_CONNECTION and QUIC_XSO230* pointers.231*232* After this returns 1, all fields of the passed QCTX are initialised.233* Returns 0 on failure. This function is intended to be used to provide API234* semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure235* unless the QCTX_NO_ERROR flag is set.236*237* The flags argument controls the preconditions and postconditions of this238* function. See above for the different flags.239*240* The fields of a QCTX are initialised as follows depending on the identity of241* the SSL object, and assuming the preconditions demanded by the flags field as242* described above are met:243*244* QDSO QLSO QCSO QSSO245* qd non-NULL maybe maybe maybe246* ql NULL non-NULL maybe maybe247* qc NULL NULL non-NULL non-NULL248* xso NULL NULL maybe non-NULL249* is_stream 0 0 0 1250* is_listener 0 1 0 0251* is_domain 1 0 0 0252*253*/254static int expect_quic_as(const SSL *s, QCTX *ctx, uint32_t flags)255{256int ok = 0, locked = 0, lock_requested = ((flags & QCTX_LOCK) != 0);257QUIC_DOMAIN *qd;258QUIC_LISTENER *ql;259QUIC_CONNECTION *qc;260QUIC_XSO *xso;261262if ((flags & QCTX_AUTO_S) != 0)263flags |= QCTX_S;264265ctx->obj = NULL;266ctx->qd = NULL;267ctx->ql = NULL;268ctx->qc = NULL;269ctx->xso = NULL;270ctx->is_stream = 0;271ctx->is_listener = 0;272ctx->is_domain = 0;273ctx->in_io = ((flags & QCTX_IO) != 0);274275if (s == NULL) {276QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_PASSED_NULL_PARAMETER, NULL);277goto err;278}279280switch (s->type) {281case SSL_TYPE_QUIC_DOMAIN:282if ((flags & QCTX_D) == 0) {283wrong_type(s, flags);284goto err;285}286287qd = (QUIC_DOMAIN *)s;288ctx->obj = &qd->obj;289ctx->qd = qd;290ctx->is_domain = 1;291break;292293case SSL_TYPE_QUIC_LISTENER:294if ((flags & QCTX_L) == 0) {295wrong_type(s, flags);296goto err;297}298299ql = (QUIC_LISTENER *)s;300ctx->obj = &ql->obj;301ctx->qd = ql->domain;302ctx->ql = ql;303ctx->is_listener = 1;304break;305306case SSL_TYPE_QUIC_CONNECTION:307qc = (QUIC_CONNECTION *)s;308ctx->obj = &qc->obj;309ctx->qd = qc->domain;310ctx->ql = qc->listener; /* never changes, so can be read without lock */311ctx->qc = qc;312313if ((flags & QCTX_AUTO_S) != 0) {314if ((flags & QCTX_IO) != 0)315qctx_lock_for_io(ctx);316else317qctx_lock(ctx);318319locked = 1;320}321322if ((flags & QCTX_AUTO_S) != 0 && qc->default_xso == NULL) {323if (!quic_mutation_allowed(qc, /*req_active=*/0)) {324QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);325goto err;326}327328/* If we haven't finished the handshake, try to advance it. */329if (quic_do_handshake(ctx) < 1)330/* ossl_quic_do_handshake raised error here */331goto err;332333if ((flags & QCTX_REMOTE_INIT) != 0) {334if (!qc_wait_for_default_xso_for_read(ctx, /*peek=*/0))335goto err;336} else {337if (!qc_try_create_default_xso_for_write(ctx))338goto err;339}340}341342if ((flags & QCTX_C) == 0343&& (qc->default_xso == NULL || (flags & QCTX_S) == 0)) {344wrong_type(s, flags);345goto err;346}347348ctx->xso = qc->default_xso;349break;350351case SSL_TYPE_QUIC_XSO:352if ((flags & QCTX_S) == 0) {353wrong_type(s, flags);354goto err;355}356357xso = (QUIC_XSO *)s;358ctx->obj = &xso->obj;359ctx->qd = xso->conn->domain;360ctx->ql = xso->conn->listener;361ctx->qc = xso->conn;362ctx->xso = xso;363ctx->is_stream = 1;364break;365366default:367QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);368goto err;369}370371if (lock_requested && !locked) {372if ((flags & QCTX_IO) != 0)373qctx_lock_for_io(ctx);374else375qctx_lock(ctx);376377locked = 1;378}379380ok = 1;381err:382if (locked && (!ok || !lock_requested))383qctx_unlock(ctx);384385return ok;386}387388static int is_quic_c(const SSL *s, QCTX *ctx, int raiseerrs)389{390uint32_t flags = QCTX_C;391392if (!raiseerrs)393flags |= QCTX_NO_ERROR;394return expect_quic_as(s, ctx, flags);395}396397/* Same as expect_quic_cs except that errors are not raised if raiseerrs == 0 */398static int is_quic_cs(const SSL *s, QCTX *ctx, int raiseerrs)399{400uint32_t flags = QCTX_C | QCTX_S;401402if (!raiseerrs)403flags |= QCTX_NO_ERROR;404return expect_quic_as(s, ctx, flags);405}406407static int expect_quic_cs(const SSL *s, QCTX *ctx)408{409return expect_quic_as(s, ctx, QCTX_C | QCTX_S);410}411412static int expect_quic_csl(const SSL *s, QCTX *ctx)413{414return expect_quic_as(s, ctx, QCTX_C | QCTX_S | QCTX_L);415}416417static int expect_quic_csld(const SSL *s, QCTX *ctx)418{419return expect_quic_as(s, ctx, QCTX_C | QCTX_S | QCTX_L | QCTX_D);420}421422#define expect_quic_any expect_quic_csld423424static int expect_quic_listener(const SSL *s, QCTX *ctx)425{426return expect_quic_as(s, ctx, QCTX_L);427}428429static int expect_quic_domain(const SSL *s, QCTX *ctx)430{431return expect_quic_as(s, ctx, QCTX_D);432}433434/*435* Like expect_quic_cs(), but requires a QUIC_XSO be contextually available. In436* other words, requires that the passed QSO be a QSSO or a QCSO with a default437* stream.438*439* remote_init determines if we expect the default XSO to be remotely created or440* not. If it is -1, do not instantiate a default XSO if one does not yet exist.441*442* Channel mutex is acquired and retained on success.443*/444QUIC_ACQUIRES_LOCK445static int ossl_unused expect_quic_with_stream_lock(const SSL *s, int remote_init,446int in_io, QCTX *ctx)447{448uint32_t flags = QCTX_S | QCTX_LOCK;449450if (remote_init >= 0)451flags |= QCTX_AUTO_S;452453if (remote_init > 0)454flags |= QCTX_REMOTE_INIT;455456if (in_io)457flags |= QCTX_IO;458459return expect_quic_as(s, ctx, flags);460}461462/*463* Like expect_quic_cs(), but fails if called on a QUIC_XSO. ctx->xso may still464* be non-NULL if the QCSO has a default stream.465*/466static int ossl_unused expect_quic_conn_only(const SSL *s, QCTX *ctx)467{468return expect_quic_as(s, ctx, QCTX_C);469}470471/*472* Ensures that the domain mutex is held for a method which touches channel473* state.474*475* Precondition: Domain mutex is not held (unchecked)476*/477static void qctx_lock(QCTX *ctx)478{479#if defined(OPENSSL_THREADS)480assert(ctx->obj != NULL);481ossl_crypto_mutex_lock(ossl_quic_obj_get0_mutex(ctx->obj));482#endif483}484485/* Precondition: Channel mutex is held (unchecked) */486QUIC_NEEDS_LOCK487static void qctx_unlock(QCTX *ctx)488{489#if defined(OPENSSL_THREADS)490assert(ctx->obj != NULL);491ossl_crypto_mutex_unlock(ossl_quic_obj_get0_mutex(ctx->obj));492#endif493}494495static void qctx_lock_for_io(QCTX *ctx)496{497qctx_lock(ctx);498ctx->in_io = 1;499500/*501* We are entering an I/O function so we must update the values returned by502* SSL_get_error and SSL_want. Set no error. This will be overridden later503* if a call to QUIC_RAISE_NORMAL_ERROR or QUIC_RAISE_NON_NORMAL_ERROR504* occurs during the API call.505*/506quic_set_last_error(ctx, SSL_ERROR_NONE);507}508509/*510* This predicate is the criterion which should determine API call rejection for511* *most* mutating API calls, particularly stream-related operations for send512* parts.513*514* A call is rejected (this function returns 0) if shutdown is in progress515* (stream flushing), or we are in a TERMINATING or TERMINATED state. If516* req_active=1, the connection must be active (i.e., the IDLE state is also517* rejected).518*/519static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active)520{521if (qc->shutting_down || ossl_quic_channel_is_term_any(qc->ch))522return 0;523524if (req_active && !ossl_quic_channel_is_active(qc->ch))525return 0;526527return 1;528}529530static int qctx_is_top_level(QCTX *ctx)531{532return ctx->obj->parent_obj == NULL;533}534535static int qctx_blocking(QCTX *ctx)536{537return ossl_quic_obj_blocking(ctx->obj);538}539540/*541* Block until a predicate is met.542*543* Precondition: Must have a channel.544* Precondition: Must hold channel lock (unchecked).545*/546QUIC_NEEDS_LOCK547static int block_until_pred(QCTX *ctx,548int (*pred)(void *arg), void *pred_arg,549uint32_t flags)550{551QUIC_ENGINE *qeng;552QUIC_REACTOR *rtor;553554qeng = ossl_quic_obj_get0_engine(ctx->obj);555assert(qeng != NULL);556557/*558* Any attempt to block auto-disables tick inhibition as otherwise we will559* hang around forever.560*/561ossl_quic_engine_set_inhibit_tick(qeng, 0);562563rtor = ossl_quic_engine_get0_reactor(qeng);564return ossl_quic_reactor_block_until_pred(rtor, pred, pred_arg, flags);565}566567/*568* QUIC Front-End I/O API: Initialization569* ======================================570*571* SSL_new => ossl_quic_new572* ossl_quic_init573* SSL_reset => ossl_quic_reset574* SSL_clear => ossl_quic_clear575* ossl_quic_deinit576* SSL_free => ossl_quic_free577*578* SSL_set_options => ossl_quic_set_options579* SSL_get_options => ossl_quic_get_options580* SSL_clear_options => ossl_quic_clear_options581*582*/583584/* SSL_new */585SSL *ossl_quic_new(SSL_CTX *ctx)586{587QUIC_CONNECTION *qc = NULL;588SSL_CONNECTION *sc = NULL;589590/*591* QUIC_server_method should not be used with SSL_new.592* It should only be used with SSL_new_listener.593*/594if (ctx->method == OSSL_QUIC_server_method()) {595QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, NULL);596return NULL;597}598599qc = OPENSSL_zalloc(sizeof(*qc));600if (qc == NULL) {601QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);602return NULL;603}604605/* Create the QUIC domain mutex. */606#if defined(OPENSSL_THREADS)607if ((qc->mutex = ossl_crypto_mutex_new()) == NULL) {608QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);609goto err;610}611#endif612613/* Create the handshake layer. */614qc->tls = ossl_ssl_connection_new_int(ctx, &qc->obj.ssl, TLS_method());615if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL) {616QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);617goto err;618}619620/* override the user_ssl of the inner connection */621sc->s3.flags |= TLS1_FLAGS_QUIC | TLS1_FLAGS_QUIC_INTERNAL;622623/* Restrict options derived from the SSL_CTX. */624sc->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN;625sc->pha_enabled = 0;626627/* Determine mode of operation. */628#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)629qc->is_thread_assisted630= ((ctx->domain_flags & SSL_DOMAIN_FLAG_THREAD_ASSISTED) != 0);631#endif632633qc->as_server = 0;634qc->as_server_state = qc->as_server;635636if (!create_channel(qc, ctx))637goto err;638639ossl_quic_channel_set_msg_callback(qc->ch, ctx->msg_callback, &qc->obj.ssl);640ossl_quic_channel_set_msg_callback_arg(qc->ch, ctx->msg_callback_arg);641642/* Initialise the QUIC_CONNECTION's QUIC_OBJ base. */643if (!ossl_quic_obj_init(&qc->obj, ctx, SSL_TYPE_QUIC_CONNECTION, NULL,644qc->engine, qc->port)) {645QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);646goto err;647}648649/* Initialise libssl APL-related state. */650qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;651qc->default_ssl_mode = qc->obj.ssl.ctx->mode;652qc->default_ssl_options = qc->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;653qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;654qc->last_error = SSL_ERROR_NONE;655656qc_update_reject_policy(qc);657658/*659* We do not create the default XSO yet. The reason for this is that the660* stream ID of the default XSO will depend on whether the stream is client661* or server-initiated, which depends on who transmits first. Since we do662* not know whether the application will be using a client-transmits-first663* or server-transmits-first protocol, we defer default XSO creation until664* the client calls SSL_read() or SSL_write(). If it calls SSL_read() first,665* we take that as a cue that the client is expecting a server-initiated666* stream, and vice versa if SSL_write() is called first.667*/668return &qc->obj.ssl;669670err:671if (qc != NULL) {672qc_cleanup(qc, /*have_lock=*/0);673OPENSSL_free(qc);674}675return NULL;676}677678QUIC_NEEDS_LOCK679static void quic_unref_port_bios(QUIC_PORT *port)680{681BIO *b;682683b = ossl_quic_port_get_net_rbio(port);684BIO_free_all(b);685686b = ossl_quic_port_get_net_wbio(port);687BIO_free_all(b);688}689690QUIC_NEEDS_LOCK691static void qc_cleanup(QUIC_CONNECTION *qc, int have_lock)692{693SSL_free(qc->tls);694qc->tls = NULL;695696ossl_quic_channel_free(qc->ch);697qc->ch = NULL;698699if (qc->port != NULL && qc->listener == NULL && qc->pending == 0) { /* TODO */700quic_unref_port_bios(qc->port);701ossl_quic_port_free(qc->port);702qc->port = NULL;703704ossl_quic_engine_free(qc->engine);705qc->engine = NULL;706}707708#if defined(OPENSSL_THREADS)709if (have_lock)710/* tsan doesn't like freeing locked mutexes */711ossl_crypto_mutex_unlock(qc->mutex);712713if (qc->listener == NULL && qc->pending == 0)714ossl_crypto_mutex_free(&qc->mutex);715#endif716}717718/* SSL_free */719QUIC_TAKES_LOCK720static void quic_free_listener(QCTX *ctx)721{722quic_unref_port_bios(ctx->ql->port);723ossl_quic_port_drop_incoming(ctx->ql->port);724ossl_quic_port_free(ctx->ql->port);725726if (ctx->ql->domain == NULL) {727ossl_quic_engine_free(ctx->ql->engine);728#if defined(OPENSSL_THREADS)729ossl_crypto_mutex_free(&ctx->ql->mutex);730#endif731} else {732SSL_free(&ctx->ql->domain->obj.ssl);733}734}735736/* SSL_free */737QUIC_TAKES_LOCK738static void quic_free_domain(QCTX *ctx)739{740ossl_quic_engine_free(ctx->qd->engine);741#if defined(OPENSSL_THREADS)742ossl_crypto_mutex_free(&ctx->qd->mutex);743#endif744}745746QUIC_TAKES_LOCK747void ossl_quic_free(SSL *s)748{749QCTX ctx;750int is_default;751752/* We should never be called on anything but a QSO. */753if (!expect_quic_any(s, &ctx))754return;755756if (ctx.is_domain) {757quic_free_domain(&ctx);758return;759}760761if (ctx.is_listener) {762quic_free_listener(&ctx);763return;764}765766qctx_lock(&ctx);767768if (ctx.is_stream) {769/*770* When a QSSO is freed, the XSO is freed immediately, because the XSO771* itself only contains API personality layer data. However the772* underlying QUIC_STREAM is not freed immediately but is instead marked773* as deleted for later collection.774*/775776assert(ctx.qc->num_xso > 0);777--ctx.qc->num_xso;778779/* If a stream's send part has not been finished, auto-reset it. */780if (( ctx.xso->stream->send_state == QUIC_SSTREAM_STATE_READY781|| ctx.xso->stream->send_state == QUIC_SSTREAM_STATE_SEND)782&& !ossl_quic_sstream_get_final_size(ctx.xso->stream->sstream, NULL))783ossl_quic_stream_map_reset_stream_send_part(ossl_quic_channel_get_qsm(ctx.qc->ch),784ctx.xso->stream, 0);785786/* Do STOP_SENDING for the receive part, if applicable. */787if ( ctx.xso->stream->recv_state == QUIC_RSTREAM_STATE_RECV788|| ctx.xso->stream->recv_state == QUIC_RSTREAM_STATE_SIZE_KNOWN)789ossl_quic_stream_map_stop_sending_recv_part(ossl_quic_channel_get_qsm(ctx.qc->ch),790ctx.xso->stream, 0);791792/* Update stream state. */793ctx.xso->stream->deleted = 1;794ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(ctx.qc->ch),795ctx.xso->stream);796797is_default = (ctx.xso == ctx.qc->default_xso);798qctx_unlock(&ctx);799800/*801* Unref the connection in most cases; the XSO has a ref to the QC and802* not vice versa. But for a default XSO, to avoid circular references,803* the QC refs the XSO but the XSO does not ref the QC. If we are the804* default XSO, we only get here when the QC is being torn down anyway,805* so don't call SSL_free(qc) as we are already in it.806*/807if (!is_default)808SSL_free(&ctx.qc->obj.ssl);809810/* Note: SSL_free calls OPENSSL_free(xso) for us */811return;812}813814/*815* Free the default XSO, if any. The QUIC_STREAM is not deleted at this816* stage, but is freed during the channel free when the whole QSM is freed.817*/818if (ctx.qc->default_xso != NULL) {819QUIC_XSO *xso = ctx.qc->default_xso;820821qctx_unlock(&ctx);822SSL_free(&xso->obj.ssl);823qctx_lock(&ctx);824ctx.qc->default_xso = NULL;825}826827/* Ensure we have no remaining XSOs. */828assert(ctx.qc->num_xso == 0);829830#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)831if (ctx.qc->is_thread_assisted && ctx.qc->started) {832ossl_quic_thread_assist_wait_stopped(&ctx.qc->thread_assist);833ossl_quic_thread_assist_cleanup(&ctx.qc->thread_assist);834}835#endif836837/*838* Note: SSL_free (that called this function) calls OPENSSL_free(ctx.qc) for839* us840*/841qc_cleanup(ctx.qc, /*have_lock=*/1);842/* Note: SSL_free calls OPENSSL_free(qc) for us */843844if (ctx.qc->listener != NULL)845SSL_free(&ctx.qc->listener->obj.ssl);846if (ctx.qc->domain != NULL)847SSL_free(&ctx.qc->domain->obj.ssl);848}849850/* SSL method init */851int ossl_quic_init(SSL *s)852{853/* Same op as SSL_clear, forward the call. */854return ossl_quic_clear(s);855}856857/* SSL method deinit */858void ossl_quic_deinit(SSL *s)859{860/* No-op. */861}862863/* SSL_clear (ssl_reset method) */864int ossl_quic_reset(SSL *s)865{866QCTX ctx;867868if (!expect_quic_any(s, &ctx))869return 0;870871ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED);872return 0;873}874875/* ssl_clear method (unused) */876int ossl_quic_clear(SSL *s)877{878QCTX ctx;879880if (!expect_quic_any(s, &ctx))881return 0;882883ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED);884return 0;885}886887int ossl_quic_set_override_now_cb(SSL *s,888OSSL_TIME (*now_cb)(void *arg),889void *now_cb_arg)890{891QCTX ctx;892893if (!expect_quic_any(s, &ctx))894return 0;895896qctx_lock(&ctx);897898ossl_quic_engine_set_time_cb(ctx.obj->engine, now_cb, now_cb_arg);899900qctx_unlock(&ctx);901return 1;902}903904void ossl_quic_conn_force_assist_thread_wake(SSL *s)905{906QCTX ctx;907908if (!expect_quic_conn_only(s, &ctx))909return;910911#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)912if (ctx.qc->is_thread_assisted && ctx.qc->started)913ossl_quic_thread_assist_notify_deadline_changed(&ctx.qc->thread_assist);914#endif915}916917QUIC_NEEDS_LOCK918static void qc_touch_default_xso(QUIC_CONNECTION *qc)919{920qc->default_xso_created = 1;921qc_update_reject_policy(qc);922}923924/*925* Changes default XSO. Allows caller to keep reference to the old default XSO926* (if any). Reference to new XSO is transferred from caller.927*/928QUIC_NEEDS_LOCK929static void qc_set_default_xso_keep_ref(QUIC_CONNECTION *qc, QUIC_XSO *xso,930int touch,931QUIC_XSO **old_xso)932{933int refs;934935*old_xso = NULL;936937if (qc->default_xso != xso) {938*old_xso = qc->default_xso; /* transfer old XSO ref to caller */939940qc->default_xso = xso;941942if (xso == NULL) {943/*944* Changing to not having a default XSO. XSO becomes standalone and945* now has a ref to the QC.946*/947if (!ossl_assert(SSL_up_ref(&qc->obj.ssl)))948return;949} else {950/*951* Changing from not having a default XSO to having one. The new XSO952* will have had a reference to the QC we need to drop to avoid a953* circular reference.954*955* Currently we never change directly from one default XSO to956* another, though this function would also still be correct if this957* weren't the case.958*/959assert(*old_xso == NULL);960961CRYPTO_DOWN_REF(&qc->obj.ssl.references, &refs);962assert(refs > 0);963}964}965966if (touch)967qc_touch_default_xso(qc);968}969970/*971* Changes default XSO, releasing the reference to any previous default XSO.972* Reference to new XSO is transferred from caller.973*/974QUIC_NEEDS_LOCK975static void qc_set_default_xso(QUIC_CONNECTION *qc, QUIC_XSO *xso, int touch)976{977QUIC_XSO *old_xso = NULL;978979qc_set_default_xso_keep_ref(qc, xso, touch, &old_xso);980981if (old_xso != NULL)982SSL_free(&old_xso->obj.ssl);983}984985QUIC_NEEDS_LOCK986static void xso_update_options(QUIC_XSO *xso)987{988int cleanse = ((xso->ssl_options & SSL_OP_CLEANSE_PLAINTEXT) != 0);989990if (xso->stream->rstream != NULL)991ossl_quic_rstream_set_cleanse(xso->stream->rstream, cleanse);992993if (xso->stream->sstream != NULL)994ossl_quic_sstream_set_cleanse(xso->stream->sstream, cleanse);995}996997/*998* SSL_set_options999* ---------------1000*1001* Setting options on a QCSO1002* - configures the handshake-layer options;1003* - configures the default data-plane options for new streams;1004* - configures the data-plane options on the default XSO, if there is one.1005*1006* Setting options on a QSSO1007* - configures data-plane options for that stream only.1008*/1009QUIC_TAKES_LOCK1010static uint64_t quic_mask_or_options(SSL *ssl, uint64_t mask_value, uint64_t or_value)1011{1012QCTX ctx;1013uint64_t hs_mask_value, hs_or_value, ret;10141015if (!expect_quic_cs(ssl, &ctx))1016return 0;10171018qctx_lock(&ctx);10191020if (!ctx.is_stream) {1021/*1022* If we were called on the connection, we apply any handshake option1023* changes.1024*/1025hs_mask_value = (mask_value & OSSL_QUIC_PERMITTED_OPTIONS_CONN);1026hs_or_value = (or_value & OSSL_QUIC_PERMITTED_OPTIONS_CONN);10271028SSL_clear_options(ctx.qc->tls, hs_mask_value);1029SSL_set_options(ctx.qc->tls, hs_or_value);10301031/* Update defaults for new streams. */1032ctx.qc->default_ssl_options1033= ((ctx.qc->default_ssl_options & ~mask_value) | or_value)1034& OSSL_QUIC_PERMITTED_OPTIONS;1035}10361037ret = ctx.qc->default_ssl_options;1038if (ctx.xso != NULL) {1039ctx.xso->ssl_options1040= ((ctx.xso->ssl_options & ~mask_value) | or_value)1041& OSSL_QUIC_PERMITTED_OPTIONS_STREAM;10421043xso_update_options(ctx.xso);10441045if (ctx.is_stream)1046ret = ctx.xso->ssl_options;1047}10481049qctx_unlock(&ctx);1050return ret;1051}10521053uint64_t ossl_quic_set_options(SSL *ssl, uint64_t options)1054{1055return quic_mask_or_options(ssl, 0, options);1056}10571058/* SSL_clear_options */1059uint64_t ossl_quic_clear_options(SSL *ssl, uint64_t options)1060{1061return quic_mask_or_options(ssl, options, 0);1062}10631064/* SSL_get_options */1065uint64_t ossl_quic_get_options(const SSL *ssl)1066{1067return quic_mask_or_options((SSL *)ssl, 0, 0);1068}10691070/*1071* QUIC Front-End I/O API: Network BIO Configuration1072* =================================================1073*1074* Handling the different BIOs is difficult:1075*1076* - It is more or less a requirement that we use non-blocking network I/O;1077* we need to be able to have timeouts on recv() calls, and make best effort1078* (non blocking) send() and recv() calls.1079*1080* The only sensible way to do this is to configure the socket into1081* non-blocking mode. We could try to do select() before calling send() or1082* recv() to get a guarantee that the call will not block, but this will1083* probably run into issues with buggy OSes which generate spurious socket1084* readiness events. In any case, relying on this to work reliably does not1085* seem sane.1086*1087* Timeouts could be handled via setsockopt() socket timeout options, but1088* this depends on OS support and adds another syscall to every network I/O1089* operation. It also has obvious thread safety concerns if we want to move1090* to concurrent use of a single socket at some later date.1091*1092* Some OSes support a MSG_DONTWAIT flag which allows a single I/O option to1093* be made non-blocking. However some OSes (e.g. Windows) do not support1094* this, so we cannot rely on this.1095*1096* As such, we need to configure any FD in non-blocking mode. This may1097* confound users who pass a blocking socket to libssl. However, in practice1098* it would be extremely strange for a user of QUIC to pass an FD to us,1099* then also try and send receive traffic on the same socket(!). Thus the1100* impact of this should be limited, and can be documented.1101*1102* - We support both blocking and non-blocking operation in terms of the API1103* presented to the user. One prospect is to set the blocking mode based on1104* whether the socket passed to us was already in blocking mode. However,1105* Windows has no API for determining if a socket is in blocking mode (!),1106* therefore this cannot be done portably. Currently therefore we expose an1107* explicit API call to set this, and default to blocking mode.1108*1109* - We need to determine our initial destination UDP address. The "natural"1110* way for a user to do this is to set the peer variable on a BIO_dgram.1111* However, this has problems because BIO_dgram's peer variable is used for1112* both transmission and reception. This means it can be constantly being1113* changed to a malicious value (e.g. if some random unrelated entity on the1114* network starts sending traffic to us) on every read call. This is not a1115* direct issue because we use the 'stateless' BIO_sendmmsg and BIO_recvmmsg1116* calls only, which do not use this variable. However, we do need to let1117* the user specify the peer in a 'normal' manner. The compromise here is1118* that we grab the current peer value set at the time the write BIO is set1119* and do not read the value again.1120*1121* - We also need to support memory BIOs (e.g. BIO_dgram_pair) or custom BIOs.1122* Currently we do this by only supporting non-blocking mode.1123*1124*/11251126/*1127* Determines what initial destination UDP address we should use, if possible.1128* If this fails the client must set the destination address manually, or use a1129* BIO which does not need a destination address.1130*/1131static int csm_analyse_init_peer_addr(BIO *net_wbio, BIO_ADDR *peer)1132{1133if (BIO_dgram_detect_peer_addr(net_wbio, peer) <= 0)1134return 0;11351136return 1;1137}11381139static int1140quic_set0_net_rbio(QUIC_OBJ *obj, BIO *net_rbio)1141{1142QUIC_PORT *port;1143BIO *old_rbio = NULL;11441145port = ossl_quic_obj_get0_port(obj);1146old_rbio = ossl_quic_port_get_net_rbio(port);1147if (old_rbio == net_rbio)1148return 0;11491150if (!ossl_quic_port_set_net_rbio(port, net_rbio))1151return 0;11521153BIO_free_all(old_rbio);1154if (net_rbio != NULL)1155BIO_set_nbio(net_rbio, 1); /* best effort autoconfig */11561157return 1;1158}11591160static int1161quic_set0_net_wbio(QUIC_OBJ *obj, BIO *net_wbio)1162{1163QUIC_PORT *port;1164BIO *old_wbio = NULL;11651166port = ossl_quic_obj_get0_port(obj);1167old_wbio = ossl_quic_port_get_net_wbio(port);1168if (old_wbio == net_wbio)1169return 0;11701171if (!ossl_quic_port_set_net_wbio(port, net_wbio))1172return 0;11731174BIO_free_all(old_wbio);1175if (net_wbio != NULL)1176BIO_set_nbio(net_wbio, 1); /* best effort autoconfig */11771178return 1;1179}11801181void ossl_quic_conn_set0_net_rbio(SSL *s, BIO *net_rbio)1182{1183QCTX ctx;11841185if (!expect_quic_csl(s, &ctx))1186return;11871188/* Returns 0 if no change. */1189if (!quic_set0_net_rbio(ctx.obj, net_rbio))1190return;1191}11921193void ossl_quic_conn_set0_net_wbio(SSL *s, BIO *net_wbio)1194{1195QCTX ctx;11961197if (!expect_quic_csl(s, &ctx))1198return;11991200/* Returns 0 if no change. */1201if (!quic_set0_net_wbio(ctx.obj, net_wbio))1202return;1203}12041205BIO *ossl_quic_conn_get_net_rbio(const SSL *s)1206{1207QCTX ctx;1208QUIC_PORT *port;12091210if (!expect_quic_csl(s, &ctx))1211return NULL;12121213port = ossl_quic_obj_get0_port(ctx.obj);1214assert(port != NULL);1215return ossl_quic_port_get_net_rbio(port);1216}12171218BIO *ossl_quic_conn_get_net_wbio(const SSL *s)1219{1220QCTX ctx;1221QUIC_PORT *port;12221223if (!expect_quic_csl(s, &ctx))1224return NULL;12251226port = ossl_quic_obj_get0_port(ctx.obj);1227assert(port != NULL);1228return ossl_quic_port_get_net_wbio(port);1229}12301231int ossl_quic_conn_get_blocking_mode(const SSL *s)1232{1233QCTX ctx;12341235if (!expect_quic_csl(s, &ctx))1236return 0;12371238return qctx_blocking(&ctx);1239}12401241QUIC_TAKES_LOCK1242int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking)1243{1244int ret = 0;1245unsigned int mode;1246QCTX ctx;12471248if (!expect_quic_csl(s, &ctx))1249return 0;12501251qctx_lock(&ctx);12521253/* Sanity check - can we support the request given the current network BIO? */1254if (blocking) {1255/*1256* If called directly on a top-level object (QCSO or QLSO), update our1257* information on network BIO capabilities.1258*/1259if (qctx_is_top_level(&ctx))1260ossl_quic_engine_update_poll_descriptors(ctx.obj->engine, /*force=*/1);12611262/* Cannot enable blocking mode if we do not have pollable FDs. */1263if (!ossl_quic_obj_can_support_blocking(ctx.obj)) {1264ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL);1265goto out;1266}1267}12681269mode = (blocking != 0)1270? QUIC_BLOCKING_MODE_BLOCKING1271: QUIC_BLOCKING_MODE_NONBLOCKING;12721273ossl_quic_obj_set_blocking_mode(ctx.obj, mode);12741275ret = 1;1276out:1277qctx_unlock(&ctx);1278return ret;1279}12801281int ossl_quic_conn_set_initial_peer_addr(SSL *s,1282const BIO_ADDR *peer_addr)1283{1284QCTX ctx;12851286if (!expect_quic_cs(s, &ctx))1287return 0;12881289if (ctx.qc->started)1290return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,1291NULL);12921293if (peer_addr == NULL) {1294BIO_ADDR_clear(&ctx.qc->init_peer_addr);1295return 1;1296}12971298return BIO_ADDR_copy(&ctx.qc->init_peer_addr, peer_addr);1299}13001301/*1302* QUIC Front-End I/O API: Asynchronous I/O Management1303* ===================================================1304*1305* (BIO/)SSL_handle_events => ossl_quic_handle_events1306* (BIO/)SSL_get_event_timeout => ossl_quic_get_event_timeout1307* (BIO/)SSL_get_poll_fd => ossl_quic_get_poll_fd1308*1309*/13101311/* SSL_handle_events; performs QUIC I/O and timeout processing. */1312QUIC_TAKES_LOCK1313int ossl_quic_handle_events(SSL *s)1314{1315QCTX ctx;13161317if (!expect_quic_any(s, &ctx))1318return 0;13191320qctx_lock(&ctx);1321ossl_quic_reactor_tick(ossl_quic_obj_get0_reactor(ctx.obj), 0);1322qctx_unlock(&ctx);1323return 1;1324}13251326/*1327* SSL_get_event_timeout. Get the time in milliseconds until the SSL object1328* should next have events handled by the application by calling1329* SSL_handle_events(). tv is set to 0 if the object should have events handled1330* immediately. If no timeout is currently active, *is_infinite is set to 1 and1331* the value of *tv is undefined.1332*/1333QUIC_TAKES_LOCK1334int ossl_quic_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite)1335{1336QCTX ctx;1337QUIC_REACTOR *reactor;1338OSSL_TIME deadline;1339OSSL_TIME basetime;13401341if (!expect_quic_any(s, &ctx))1342return 0;13431344qctx_lock(&ctx);13451346reactor = ossl_quic_obj_get0_reactor(ctx.obj);1347deadline = ossl_quic_reactor_get_tick_deadline(reactor);13481349if (ossl_time_is_infinite(deadline)) {1350qctx_unlock(&ctx);1351*is_infinite = 1;13521353/*1354* Robustness against faulty applications that don't check *is_infinite;1355* harmless long timeout.1356*/1357tv->tv_sec = 1000000;1358tv->tv_usec = 0;1359return 1;1360}13611362basetime = ossl_quic_engine_get_time(ctx.obj->engine);13631364qctx_unlock(&ctx);13651366*tv = ossl_time_to_timeval(ossl_time_subtract(deadline, basetime));1367*is_infinite = 0;13681369return 1;1370}13711372/* SSL_get_rpoll_descriptor */1373int ossl_quic_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)1374{1375QCTX ctx;1376QUIC_PORT *port = NULL;1377BIO *net_rbio;13781379if (!expect_quic_csl(s, &ctx))1380return 0;13811382port = ossl_quic_obj_get0_port(ctx.obj);1383net_rbio = ossl_quic_port_get_net_rbio(port);1384if (desc == NULL || net_rbio == NULL)1385return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT,1386NULL);13871388return BIO_get_rpoll_descriptor(net_rbio, desc);1389}13901391/* SSL_get_wpoll_descriptor */1392int ossl_quic_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)1393{1394QCTX ctx;1395QUIC_PORT *port = NULL;1396BIO *net_wbio;13971398if (!expect_quic_csl(s, &ctx))1399return 0;14001401port = ossl_quic_obj_get0_port(ctx.obj);1402net_wbio = ossl_quic_port_get_net_wbio(port);1403if (desc == NULL || net_wbio == NULL)1404return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT,1405NULL);14061407return BIO_get_wpoll_descriptor(net_wbio, desc);1408}14091410/* SSL_net_read_desired */1411QUIC_TAKES_LOCK1412int ossl_quic_get_net_read_desired(SSL *s)1413{1414QCTX ctx;1415int ret;14161417if (!expect_quic_csl(s, &ctx))1418return 0;14191420qctx_lock(&ctx);1421ret = ossl_quic_reactor_net_read_desired(ossl_quic_obj_get0_reactor(ctx.obj));1422qctx_unlock(&ctx);1423return ret;1424}14251426/* SSL_net_write_desired */1427QUIC_TAKES_LOCK1428int ossl_quic_get_net_write_desired(SSL *s)1429{1430int ret;1431QCTX ctx;14321433if (!expect_quic_csl(s, &ctx))1434return 0;14351436qctx_lock(&ctx);1437ret = ossl_quic_reactor_net_write_desired(ossl_quic_obj_get0_reactor(ctx.obj));1438qctx_unlock(&ctx);1439return ret;1440}14411442/*1443* QUIC Front-End I/O API: Connection Lifecycle Operations1444* =======================================================1445*1446* SSL_do_handshake => ossl_quic_do_handshake1447* SSL_set_connect_state => ossl_quic_set_connect_state1448* SSL_set_accept_state => ossl_quic_set_accept_state1449* SSL_shutdown => ossl_quic_shutdown1450* SSL_ctrl => ossl_quic_ctrl1451* (BIO/)SSL_connect => ossl_quic_connect1452* (BIO/)SSL_accept => ossl_quic_accept1453*1454*/14551456QUIC_NEEDS_LOCK1457static void qc_shutdown_flush_init(QUIC_CONNECTION *qc)1458{1459QUIC_STREAM_MAP *qsm;14601461if (qc->shutting_down)1462return;14631464qsm = ossl_quic_channel_get_qsm(qc->ch);14651466ossl_quic_stream_map_begin_shutdown_flush(qsm);1467qc->shutting_down = 1;1468}14691470/* Returns 1 if all shutdown-flush streams have been done with. */1471QUIC_NEEDS_LOCK1472static int qc_shutdown_flush_finished(QUIC_CONNECTION *qc)1473{1474QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(qc->ch);14751476return qc->shutting_down1477&& ossl_quic_stream_map_is_shutdown_flush_finished(qsm);1478}14791480/* SSL_shutdown */1481static int quic_shutdown_wait(void *arg)1482{1483QUIC_CONNECTION *qc = arg;14841485return ossl_quic_channel_is_terminated(qc->ch);1486}14871488/* Returns 1 if shutdown flush process has finished or is inapplicable. */1489static int quic_shutdown_flush_wait(void *arg)1490{1491QUIC_CONNECTION *qc = arg;14921493return ossl_quic_channel_is_term_any(qc->ch)1494|| qc_shutdown_flush_finished(qc);1495}14961497static int quic_shutdown_peer_wait(void *arg)1498{1499QUIC_CONNECTION *qc = arg;1500return ossl_quic_channel_is_term_any(qc->ch);1501}15021503QUIC_TAKES_LOCK1504int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,1505const SSL_SHUTDOWN_EX_ARGS *args,1506size_t args_len)1507{1508int ret;1509QCTX ctx;1510int stream_flush = ((flags & SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH) == 0);1511int no_block = ((flags & SSL_SHUTDOWN_FLAG_NO_BLOCK) != 0);1512int wait_peer = ((flags & SSL_SHUTDOWN_FLAG_WAIT_PEER) != 0);15131514if (!expect_quic_cs(s, &ctx))1515return -1;15161517if (ctx.is_stream) {1518QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_CONN_USE_ONLY, NULL);1519return -1;1520}15211522qctx_lock(&ctx);15231524if (ossl_quic_channel_is_terminated(ctx.qc->ch)) {1525qctx_unlock(&ctx);1526return 1;1527}15281529/* Phase 1: Stream Flushing */1530if (!wait_peer && stream_flush) {1531qc_shutdown_flush_init(ctx.qc);15321533if (!qc_shutdown_flush_finished(ctx.qc)) {1534if (!no_block && qctx_blocking(&ctx)) {1535ret = block_until_pred(&ctx, quic_shutdown_flush_wait, ctx.qc, 0);1536if (ret < 1) {1537ret = 0;1538goto err;1539}1540} else {1541qctx_maybe_autotick(&ctx);1542}1543}15441545if (!qc_shutdown_flush_finished(ctx.qc)) {1546qctx_unlock(&ctx);1547return 0; /* ongoing */1548}1549}15501551/* Phase 2: Connection Closure */1552if (wait_peer && !ossl_quic_channel_is_term_any(ctx.qc->ch)) {1553if (!no_block && qctx_blocking(&ctx)) {1554ret = block_until_pred(&ctx, quic_shutdown_peer_wait, ctx.qc, 0);1555if (ret < 1) {1556ret = 0;1557goto err;1558}1559} else {1560qctx_maybe_autotick(&ctx);1561}15621563if (!ossl_quic_channel_is_term_any(ctx.qc->ch)) {1564ret = 0; /* peer hasn't closed yet - still not done */1565goto err;1566}15671568/*1569* We are at least terminating - go through the normal process of1570* waiting until we are in the TERMINATED state.1571*/1572}15731574/* Block mutation ops regardless of if we did stream flush. */1575ctx.qc->shutting_down = 1;15761577/*1578* This call is a no-op if we are already terminating, so it doesn't1579* affect the wait_peer case.1580*/1581ossl_quic_channel_local_close(ctx.qc->ch,1582args != NULL ? args->quic_error_code : 0,1583args != NULL ? args->quic_reason : NULL);15841585SSL_set_shutdown(ctx.qc->tls, SSL_SENT_SHUTDOWN);15861587if (ossl_quic_channel_is_terminated(ctx.qc->ch)) {1588qctx_unlock(&ctx);1589return 1;1590}15911592/* Phase 3: Terminating Wait Time */1593if (!no_block && qctx_blocking(&ctx)1594&& (flags & SSL_SHUTDOWN_FLAG_RAPID) == 0) {1595ret = block_until_pred(&ctx, quic_shutdown_wait, ctx.qc, 0);1596if (ret < 1) {1597ret = 0;1598goto err;1599}1600} else {1601qctx_maybe_autotick(&ctx);1602}16031604ret = ossl_quic_channel_is_terminated(ctx.qc->ch);1605err:1606qctx_unlock(&ctx);1607return ret;1608}16091610/* SSL_ctrl */1611long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg)1612{1613QCTX ctx;16141615if (!expect_quic_csl(s, &ctx))1616return 0;16171618switch (cmd) {1619case SSL_CTRL_MODE:1620if (ctx.is_listener)1621return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL);16221623/* If called on a QCSO, update the default mode. */1624if (!ctx.is_stream)1625ctx.qc->default_ssl_mode |= (uint32_t)larg;16261627/*1628* If we were called on a QSSO or have a default stream, we also update1629* that.1630*/1631if (ctx.xso != NULL) {1632/* Cannot enable EPW while AON write in progress. */1633if (ctx.xso->aon_write_in_progress)1634larg &= ~SSL_MODE_ENABLE_PARTIAL_WRITE;16351636ctx.xso->ssl_mode |= (uint32_t)larg;1637return ctx.xso->ssl_mode;1638}16391640return ctx.qc->default_ssl_mode;1641case SSL_CTRL_CLEAR_MODE:1642if (ctx.is_listener)1643return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL);16441645if (!ctx.is_stream)1646ctx.qc->default_ssl_mode &= ~(uint32_t)larg;16471648if (ctx.xso != NULL) {1649ctx.xso->ssl_mode &= ~(uint32_t)larg;1650return ctx.xso->ssl_mode;1651}16521653return ctx.qc->default_ssl_mode;16541655case SSL_CTRL_SET_MSG_CALLBACK_ARG:1656if (ctx.is_listener)1657return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL);16581659ossl_quic_channel_set_msg_callback_arg(ctx.qc->ch, parg);1660/* This ctrl also needs to be passed to the internal SSL object */1661return SSL_ctrl(ctx.qc->tls, cmd, larg, parg);16621663case DTLS_CTRL_GET_TIMEOUT: /* DTLSv1_get_timeout */1664{1665int is_infinite;16661667if (!ossl_quic_get_event_timeout(s, parg, &is_infinite))1668return 0;16691670return !is_infinite;1671}1672case DTLS_CTRL_HANDLE_TIMEOUT: /* DTLSv1_handle_timeout */1673/* For legacy compatibility with DTLS calls. */1674return ossl_quic_handle_events(s) == 1 ? 1 : -1;16751676/* Mask ctrls we shouldn't support for QUIC. */1677case SSL_CTRL_GET_READ_AHEAD:1678case SSL_CTRL_SET_READ_AHEAD:1679case SSL_CTRL_SET_MAX_SEND_FRAGMENT:1680case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:1681case SSL_CTRL_SET_MAX_PIPELINES:1682return 0;16831684default:1685/*1686* Probably a TLS related ctrl. Send back to the frontend SSL_ctrl1687* implementation. Either SSL_ctrl will handle it itself by direct1688* access into handshake layer state, or failing that, it will be passed1689* to the handshake layer via the SSL_METHOD vtable. If the ctrl is not1690* supported by anything, the handshake layer's ctrl method will finally1691* return 0.1692*/1693if (ctx.is_listener)1694return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL);16951696return ossl_ctrl_internal(&ctx.qc->obj.ssl, cmd, larg, parg, /*no_quic=*/1);1697}1698}16991700/* SSL_set_connect_state */1701int ossl_quic_set_connect_state(SSL *s, int raiseerrs)1702{1703QCTX ctx;17041705if (!is_quic_c(s, &ctx, raiseerrs))1706return 0;17071708if (ctx.qc->as_server_state == 0)1709return 1;17101711/* Cannot be changed after handshake started */1712if (ctx.qc->started) {1713if (raiseerrs)1714QUIC_RAISE_NON_NORMAL_ERROR(NULL, SSL_R_INVALID_COMMAND, NULL);1715return 0;1716}17171718ctx.qc->as_server_state = 0;1719return 1;1720}17211722/* SSL_set_accept_state */1723int ossl_quic_set_accept_state(SSL *s, int raiseerrs)1724{1725QCTX ctx;17261727if (!is_quic_c(s, &ctx, raiseerrs))1728return 0;17291730if (ctx.qc->as_server_state == 1)1731return 1;17321733/* Cannot be changed after handshake started */1734if (ctx.qc->started) {1735if (raiseerrs)1736QUIC_RAISE_NON_NORMAL_ERROR(NULL, SSL_R_INVALID_COMMAND, NULL);1737return 0;1738}17391740ctx.qc->as_server_state = 1;1741return 1;1742}17431744/* SSL_do_handshake */1745struct quic_handshake_wait_args {1746QUIC_CONNECTION *qc;1747};17481749static int tls_wants_non_io_retry(QUIC_CONNECTION *qc)1750{1751int want = SSL_want(qc->tls);17521753if (want == SSL_X509_LOOKUP1754|| want == SSL_CLIENT_HELLO_CB1755|| want == SSL_RETRY_VERIFY)1756return 1;17571758return 0;1759}17601761static int quic_handshake_wait(void *arg)1762{1763struct quic_handshake_wait_args *args = arg;17641765if (!quic_mutation_allowed(args->qc, /*req_active=*/1))1766return -1;17671768if (ossl_quic_channel_is_handshake_complete(args->qc->ch))1769return 1;17701771if (tls_wants_non_io_retry(args->qc))1772return 1;17731774return 0;1775}17761777static int configure_channel(QUIC_CONNECTION *qc)1778{1779assert(qc->ch != NULL);17801781if (!ossl_quic_channel_set_peer_addr(qc->ch, &qc->init_peer_addr))1782return 0;17831784return 1;1785}17861787static int need_notifier_for_domain_flags(uint64_t domain_flags)1788{1789return (domain_flags & SSL_DOMAIN_FLAG_THREAD_ASSISTED) != 01790|| ((domain_flags & SSL_DOMAIN_FLAG_MULTI_THREAD) != 01791&& (domain_flags & SSL_DOMAIN_FLAG_BLOCKING) != 0);1792}17931794QUIC_NEEDS_LOCK1795static int create_channel(QUIC_CONNECTION *qc, SSL_CTX *ctx)1796{1797QUIC_ENGINE_ARGS engine_args = {0};1798QUIC_PORT_ARGS port_args = {0};17991800engine_args.libctx = ctx->libctx;1801engine_args.propq = ctx->propq;1802#if defined(OPENSSL_THREADS)1803engine_args.mutex = qc->mutex;1804#endif18051806if (need_notifier_for_domain_flags(ctx->domain_flags))1807engine_args.reactor_flags |= QUIC_REACTOR_FLAG_USE_NOTIFIER;18081809qc->engine = ossl_quic_engine_new(&engine_args);1810if (qc->engine == NULL) {1811QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);1812return 0;1813}18141815port_args.channel_ctx = ctx;1816qc->port = ossl_quic_engine_create_port(qc->engine, &port_args);1817if (qc->port == NULL) {1818QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);1819ossl_quic_engine_free(qc->engine);1820return 0;1821}18221823qc->ch = ossl_quic_port_create_outgoing(qc->port, qc->tls);1824if (qc->ch == NULL) {1825QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);1826ossl_quic_port_free(qc->port);1827ossl_quic_engine_free(qc->engine);1828return 0;1829}18301831return 1;1832}18331834/*1835* Configures a channel with the information we have accumulated via calls made1836* to us from the application prior to starting a handshake attempt.1837*/1838QUIC_NEEDS_LOCK1839static int ensure_channel_started(QCTX *ctx)1840{1841QUIC_CONNECTION *qc = ctx->qc;18421843if (!qc->started) {1844if (!configure_channel(qc)) {1845QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR,1846"failed to configure channel");1847return 0;1848}18491850if (!ossl_quic_channel_start(qc->ch)) {1851ossl_quic_channel_restore_err_state(qc->ch);1852QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR,1853"failed to start channel");1854return 0;1855}18561857#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)1858if (qc->is_thread_assisted)1859if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch)) {1860QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR,1861"failed to start assist thread");1862return 0;1863}1864#endif1865}18661867qc->started = 1;1868return 1;1869}18701871QUIC_NEEDS_LOCK1872static int quic_do_handshake(QCTX *ctx)1873{1874int ret;1875QUIC_CONNECTION *qc = ctx->qc;1876QUIC_PORT *port;1877BIO *net_rbio, *net_wbio;18781879if (ossl_quic_channel_is_handshake_complete(qc->ch))1880/* Handshake already completed. */1881return 1;18821883if (!quic_mutation_allowed(qc, /*req_active=*/0))1884return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);18851886if (qc->as_server != qc->as_server_state) {1887QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL);1888return -1; /* Non-protocol error */1889}18901891port = ossl_quic_obj_get0_port(ctx->obj);1892net_rbio = ossl_quic_port_get_net_rbio(port);1893net_wbio = ossl_quic_port_get_net_wbio(port);1894if (net_rbio == NULL || net_wbio == NULL) {1895/* Need read and write BIOs. */1896QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_BIO_NOT_SET, NULL);1897return -1; /* Non-protocol error */1898}18991900if (!qc->started && ossl_quic_port_is_addressed_w(port)1901&& BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) {1902/*1903* We are trying to connect and are using addressed mode, which means we1904* need an initial peer address; if we do not have a peer address yet,1905* we should try to autodetect one.1906*1907* We do this as late as possible because some BIOs (e.g. BIO_s_connect)1908* may not be able to provide us with a peer address until they have1909* finished their own processing. They may not be able to perform this1910* processing until an application has finished configuring that BIO1911* (e.g. with setter calls), which might happen after SSL_set_bio is1912* called.1913*/1914if (!csm_analyse_init_peer_addr(net_wbio, &qc->init_peer_addr))1915/* best effort */1916BIO_ADDR_clear(&qc->init_peer_addr);1917else1918ossl_quic_channel_set_peer_addr(qc->ch, &qc->init_peer_addr);1919}19201921if (!qc->started1922&& ossl_quic_port_is_addressed_w(port)1923&& BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) {1924/*1925* If we still don't have a peer address in addressed mode, we can't do1926* anything.1927*/1928QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_REMOTE_PEER_ADDRESS_NOT_SET, NULL);1929return -1; /* Non-protocol error */1930}19311932/*1933* Start connection process. Note we may come here multiple times in1934* non-blocking mode, which is fine.1935*/1936if (!ensure_channel_started(ctx)) /* raises on failure */1937return -1; /* Non-protocol error */19381939if (ossl_quic_channel_is_handshake_complete(qc->ch))1940/* The handshake is now done. */1941return 1;19421943if (!qctx_blocking(ctx)) {1944/* Try to advance the reactor. */1945qctx_maybe_autotick(ctx);19461947if (ossl_quic_channel_is_handshake_complete(qc->ch))1948/* The handshake is now done. */1949return 1;19501951if (ossl_quic_channel_is_term_any(qc->ch)) {1952QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);1953return 0;1954} else if (ossl_quic_obj_desires_blocking(&qc->obj)) {1955/*1956* As a special case when doing a handshake when blocking mode is1957* desired yet not available, see if the network BIOs have become1958* poll descriptor-enabled. This supports BIOs such as BIO_s_connect1959* which do late creation of socket FDs and therefore cannot expose1960* a poll descriptor until after a network BIO is set on the QCSO.1961*/1962ossl_quic_engine_update_poll_descriptors(qc->obj.engine, /*force=*/1);1963}1964}19651966/*1967* We are either in blocking mode or just entered it due to the code above.1968*/1969if (qctx_blocking(ctx)) {1970/* In blocking mode, wait for the handshake to complete. */1971struct quic_handshake_wait_args args;19721973args.qc = qc;19741975ret = block_until_pred(ctx, quic_handshake_wait, &args, 0);1976if (!quic_mutation_allowed(qc, /*req_active=*/1)) {1977QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);1978return 0; /* Shutdown before completion */1979} else if (ret <= 0) {1980QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);1981return -1; /* Non-protocol error */1982}19831984if (tls_wants_non_io_retry(qc)) {1985QUIC_RAISE_NORMAL_ERROR(ctx, SSL_get_error(qc->tls, 0));1986return -1;1987}19881989assert(ossl_quic_channel_is_handshake_complete(qc->ch));1990return 1;1991}19921993if (tls_wants_non_io_retry(qc)) {1994QUIC_RAISE_NORMAL_ERROR(ctx, SSL_get_error(qc->tls, 0));1995return -1;1996}19971998/*1999* Otherwise, indicate that the handshake isn't done yet.2000* We can only get here in non-blocking mode.2001*/2002QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ);2003return -1; /* Non-protocol error */2004}20052006QUIC_TAKES_LOCK2007int ossl_quic_do_handshake(SSL *s)2008{2009int ret;2010QCTX ctx;20112012if (!expect_quic_cs(s, &ctx))2013return 0;20142015qctx_lock_for_io(&ctx);20162017ret = quic_do_handshake(&ctx);2018qctx_unlock(&ctx);2019return ret;2020}20212022/* SSL_connect */2023int ossl_quic_connect(SSL *s)2024{2025/* Ensure we are in connect state (no-op if non-idle). */2026if (!ossl_quic_set_connect_state(s, 1))2027return -1;20282029/* Begin or continue the handshake */2030return ossl_quic_do_handshake(s);2031}20322033/* SSL_accept */2034int ossl_quic_accept(SSL *s)2035{2036/* Ensure we are in accept state (no-op if non-idle). */2037if (!ossl_quic_set_accept_state(s, 1))2038return -1;20392040/* Begin or continue the handshake */2041return ossl_quic_do_handshake(s);2042}20432044/*2045* QUIC Front-End I/O API: Stream Lifecycle Operations2046* ===================================================2047*2048* SSL_stream_new => ossl_quic_conn_stream_new2049*2050*/20512052/*2053* Try to create the default XSO if it doesn't already exist. Returns 1 if the2054* default XSO was created. Returns 0 if it was not (e.g. because it already2055* exists). Note that this is NOT an error condition.2056*/2057QUIC_NEEDS_LOCK2058static int qc_try_create_default_xso_for_write(QCTX *ctx)2059{2060uint64_t flags = 0;2061QUIC_CONNECTION *qc = ctx->qc;20622063if (qc->default_xso_created2064|| qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE)2065/*2066* We only do this once. If the user detaches a previously created2067* default XSO we don't auto-create another one.2068*/2069return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL);20702071/* Create a locally-initiated stream. */2072if (qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_AUTO_UNI)2073flags |= SSL_STREAM_FLAG_UNI;20742075qc_set_default_xso(qc, (QUIC_XSO *)quic_conn_stream_new(ctx, flags,2076/*needs_lock=*/0),2077/*touch=*/0);2078if (qc->default_xso == NULL)2079return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);20802081qc_touch_default_xso(qc);2082return 1;2083}20842085struct quic_wait_for_stream_args {2086QUIC_CONNECTION *qc;2087QUIC_STREAM *qs;2088QCTX *ctx;2089uint64_t expect_id;2090};20912092QUIC_NEEDS_LOCK2093static int quic_wait_for_stream(void *arg)2094{2095struct quic_wait_for_stream_args *args = arg;20962097if (!quic_mutation_allowed(args->qc, /*req_active=*/1)) {2098/* If connection is torn down due to an error while blocking, stop. */2099QUIC_RAISE_NON_NORMAL_ERROR(args->ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);2100return -1;2101}21022103args->qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(args->qc->ch),2104args->expect_id | QUIC_STREAM_DIR_BIDI);2105if (args->qs == NULL)2106args->qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(args->qc->ch),2107args->expect_id | QUIC_STREAM_DIR_UNI);21082109if (args->qs != NULL)2110return 1; /* stream now exists */21112112return 0; /* did not get a stream, keep trying */2113}21142115QUIC_NEEDS_LOCK2116static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek)2117{2118/* Called on a QCSO and we don't currently have a default stream. */2119uint64_t expect_id;2120QUIC_CONNECTION *qc = ctx->qc;2121QUIC_STREAM *qs;2122int res;2123struct quic_wait_for_stream_args wargs;2124OSSL_RTT_INFO rtt_info;21252126/*2127* If default stream functionality is disabled or we already detached2128* one, don't make another default stream and just fail.2129*/2130if (qc->default_xso_created2131|| qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE)2132return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL);21332134/*2135* The peer may have opened a stream since we last ticked. So tick and2136* see if the stream with ordinal 0 (remote, bidi/uni based on stream2137* mode) exists yet. QUIC stream IDs must be allocated in order, so the2138* first stream created by a peer must have an ordinal of 0.2139*/2140expect_id = qc->as_server2141? QUIC_STREAM_INITIATOR_CLIENT2142: QUIC_STREAM_INITIATOR_SERVER;21432144qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch),2145expect_id | QUIC_STREAM_DIR_BIDI);2146if (qs == NULL)2147qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch),2148expect_id | QUIC_STREAM_DIR_UNI);21492150if (qs == NULL) {2151qctx_maybe_autotick(ctx);21522153qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch),2154expect_id);2155}21562157if (qs == NULL) {2158if (peek)2159return 0;21602161if (ossl_quic_channel_is_term_any(qc->ch)) {2162return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);2163} else if (!qctx_blocking(ctx)) {2164/* Non-blocking mode, so just bail immediately. */2165return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ);2166}21672168/* Block until we have a stream. */2169wargs.qc = qc;2170wargs.qs = NULL;2171wargs.ctx = ctx;2172wargs.expect_id = expect_id;21732174res = block_until_pred(ctx, quic_wait_for_stream, &wargs, 0);2175if (res == 0)2176return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2177else if (res < 0 || wargs.qs == NULL)2178/* quic_wait_for_stream raised error here */2179return 0;21802181qs = wargs.qs;2182}21832184/*2185* We now have qs != NULL. Remove it from the incoming stream queue so that2186* it isn't also returned by any future SSL_accept_stream calls.2187*/2188ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(qc->ch), &rtt_info);2189ossl_quic_stream_map_remove_from_accept_queue(ossl_quic_channel_get_qsm(qc->ch),2190qs, rtt_info.smoothed_rtt);21912192/*2193* Now make qs the default stream, creating the necessary XSO.2194*/2195qc_set_default_xso(qc, create_xso_from_stream(qc, qs), /*touch=*/0);2196if (qc->default_xso == NULL)2197return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);21982199qc_touch_default_xso(qc); /* inhibits default XSO */2200return 1;2201}22022203QUIC_NEEDS_LOCK2204static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs)2205{2206QUIC_XSO *xso = NULL;22072208if ((xso = OPENSSL_zalloc(sizeof(*xso))) == NULL) {2209QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);2210goto err;2211}22122213if (!ossl_quic_obj_init(&xso->obj, qc->obj.ssl.ctx, SSL_TYPE_QUIC_XSO,2214&qc->obj.ssl, NULL, NULL)) {2215QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);2216goto err;2217}22182219/* XSO refs QC */2220if (!SSL_up_ref(&qc->obj.ssl)) {2221QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_SSL_LIB, NULL);2222goto err;2223}22242225xso->conn = qc;2226xso->ssl_mode = qc->default_ssl_mode;2227xso->ssl_options2228= qc->default_ssl_options & OSSL_QUIC_PERMITTED_OPTIONS_STREAM;2229xso->last_error = SSL_ERROR_NONE;22302231xso->stream = qs;22322233++qc->num_xso;2234xso_update_options(xso);2235return xso;22362237err:2238OPENSSL_free(xso);2239return NULL;2240}22412242struct quic_new_stream_wait_args {2243QUIC_CONNECTION *qc;2244int is_uni;2245};22462247static int quic_new_stream_wait(void *arg)2248{2249struct quic_new_stream_wait_args *args = arg;2250QUIC_CONNECTION *qc = args->qc;22512252if (!quic_mutation_allowed(qc, /*req_active=*/1))2253return -1;22542255if (ossl_quic_channel_is_new_local_stream_admissible(qc->ch, args->is_uni))2256return 1;22572258return 0;2259}22602261/* locking depends on need_lock */2262static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock)2263{2264int ret;2265QUIC_CONNECTION *qc = ctx->qc;2266QUIC_XSO *xso = NULL;2267QUIC_STREAM *qs = NULL;2268int is_uni = ((flags & SSL_STREAM_FLAG_UNI) != 0);2269int no_blocking = ((flags & SSL_STREAM_FLAG_NO_BLOCK) != 0);2270int advance = ((flags & SSL_STREAM_FLAG_ADVANCE) != 0);22712272if (need_lock)2273qctx_lock(ctx);22742275if (!quic_mutation_allowed(qc, /*req_active=*/0)) {2276QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);2277goto err;2278}22792280if (!advance2281&& !ossl_quic_channel_is_new_local_stream_admissible(qc->ch, is_uni)) {2282struct quic_new_stream_wait_args args;22832284/*2285* Stream count flow control currently doesn't permit this stream to be2286* opened.2287*/2288if (no_blocking || !qctx_blocking(ctx)) {2289QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_STREAM_COUNT_LIMITED, NULL);2290goto err;2291}22922293args.qc = qc;2294args.is_uni = is_uni;22952296/* Blocking mode - wait until we can get a stream. */2297ret = block_until_pred(ctx, quic_new_stream_wait, &args, 0);2298if (!quic_mutation_allowed(qc, /*req_active=*/1)) {2299QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);2300goto err; /* Shutdown before completion */2301} else if (ret <= 0) {2302QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2303goto err; /* Non-protocol error */2304}2305}23062307qs = ossl_quic_channel_new_stream_local(qc->ch, is_uni);2308if (qs == NULL) {2309QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2310goto err;2311}23122313xso = create_xso_from_stream(qc, qs);2314if (xso == NULL)2315goto err;23162317qc_touch_default_xso(qc); /* inhibits default XSO */2318if (need_lock)2319qctx_unlock(ctx);23202321return &xso->obj.ssl;23222323err:2324OPENSSL_free(xso);2325ossl_quic_stream_map_release(ossl_quic_channel_get_qsm(qc->ch), qs);2326if (need_lock)2327qctx_unlock(ctx);23282329return NULL;23302331}23322333QUIC_TAKES_LOCK2334SSL *ossl_quic_conn_stream_new(SSL *s, uint64_t flags)2335{2336QCTX ctx;23372338if (!expect_quic_conn_only(s, &ctx))2339return NULL;23402341return quic_conn_stream_new(&ctx, flags, /*need_lock=*/1);2342}23432344/*2345* QUIC Front-End I/O API: Steady-State Operations2346* ===============================================2347*2348* Here we dispatch calls to the steady-state front-end I/O API functions; that2349* is, the functions used during the established phase of a QUIC connection2350* (e.g. SSL_read, SSL_write).2351*2352* Each function must handle both blocking and non-blocking modes. As discussed2353* above, all QUIC I/O is implemented using non-blocking mode internally.2354*2355* SSL_get_error => partially implemented by ossl_quic_get_error2356* SSL_want => ossl_quic_want2357* (BIO/)SSL_read => ossl_quic_read2358* (BIO/)SSL_write => ossl_quic_write2359* SSL_pending => ossl_quic_pending2360* SSL_stream_conclude => ossl_quic_conn_stream_conclude2361* SSL_key_update => ossl_quic_key_update2362*/23632364/* SSL_get_error */2365int ossl_quic_get_error(const SSL *s, int i)2366{2367QCTX ctx;2368int net_error, last_error;23692370/* SSL_get_errors() should not raise new errors */2371if (!is_quic_cs(s, &ctx, 0 /* suppress errors */))2372return SSL_ERROR_SSL;23732374qctx_lock(&ctx);2375net_error = ossl_quic_channel_net_error(ctx.qc->ch);2376last_error = ctx.is_stream ? ctx.xso->last_error : ctx.qc->last_error;2377qctx_unlock(&ctx);23782379if (net_error)2380return SSL_ERROR_SYSCALL;23812382return last_error;2383}23842385/* Converts a code returned by SSL_get_error to a code returned by SSL_want. */2386static int error_to_want(int error)2387{2388switch (error) {2389case SSL_ERROR_WANT_CONNECT: /* never used - UDP is connectionless */2390case SSL_ERROR_WANT_ACCEPT: /* never used - UDP is connectionless */2391case SSL_ERROR_ZERO_RETURN:2392default:2393return SSL_NOTHING;23942395case SSL_ERROR_WANT_READ:2396return SSL_READING;23972398case SSL_ERROR_WANT_WRITE:2399return SSL_WRITING;24002401case SSL_ERROR_WANT_RETRY_VERIFY:2402return SSL_RETRY_VERIFY;24032404case SSL_ERROR_WANT_CLIENT_HELLO_CB:2405return SSL_CLIENT_HELLO_CB;24062407case SSL_ERROR_WANT_X509_LOOKUP:2408return SSL_X509_LOOKUP;2409}2410}24112412/* SSL_want */2413int ossl_quic_want(const SSL *s)2414{2415QCTX ctx;2416int w;24172418if (!expect_quic_cs(s, &ctx))2419return SSL_NOTHING;24202421qctx_lock(&ctx);24222423w = error_to_want(ctx.is_stream ? ctx.xso->last_error : ctx.qc->last_error);24242425qctx_unlock(&ctx);2426return w;2427}24282429/*2430* SSL_write2431* ---------2432*2433* The set of functions below provide the implementation of the public SSL_write2434* function. We must handle:2435*2436* - both blocking and non-blocking operation at the application level,2437* depending on how we are configured;2438*2439* - SSL_MODE_ENABLE_PARTIAL_WRITE being on or off;2440*2441* - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER.2442*2443*/2444QUIC_NEEDS_LOCK2445static void quic_post_write(QUIC_XSO *xso, int did_append,2446int did_append_all, uint64_t flags,2447int do_tick)2448{2449/*2450* We have appended at least one byte to the stream.2451* Potentially mark stream as active, depending on FC.2452*/2453if (did_append)2454ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(xso->conn->ch),2455xso->stream);24562457if (did_append_all && (flags & SSL_WRITE_FLAG_CONCLUDE) != 0)2458ossl_quic_sstream_fin(xso->stream->sstream);24592460/*2461* Try and send.2462*2463* TODO(QUIC FUTURE): It is probably inefficient to try and do this2464* immediately, plus we should eventually consider Nagle's algorithm.2465*/2466if (do_tick)2467ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(xso->conn->ch), 0);2468}24692470struct quic_write_again_args {2471QUIC_XSO *xso;2472const unsigned char *buf;2473size_t len;2474size_t total_written;2475int err;2476uint64_t flags;2477};24782479/*2480* Absolute maximum write buffer size, enforced to prevent a rogue peer from2481* deliberately inducing DoS. This has been chosen based on the optimal buffer2482* size for an RTT of 500ms and a bandwidth of 100 Mb/s.2483*/2484#define MAX_WRITE_BUF_SIZE (6 * 1024 * 1024)24852486/*2487* Ensure spare buffer space available (up until a limit, at least).2488*/2489QUIC_NEEDS_LOCK2490static int sstream_ensure_spare(QUIC_SSTREAM *sstream, uint64_t spare)2491{2492size_t cur_sz = ossl_quic_sstream_get_buffer_size(sstream);2493size_t avail = ossl_quic_sstream_get_buffer_avail(sstream);2494size_t spare_ = (spare > SIZE_MAX) ? SIZE_MAX : (size_t)spare;2495size_t new_sz, growth;24962497if (spare_ <= avail || cur_sz == MAX_WRITE_BUF_SIZE)2498return 1;24992500growth = spare_ - avail;2501if (cur_sz + growth > MAX_WRITE_BUF_SIZE)2502new_sz = MAX_WRITE_BUF_SIZE;2503else2504new_sz = cur_sz + growth;25052506return ossl_quic_sstream_set_buffer_size(sstream, new_sz);2507}25082509/*2510* Append to a QUIC_STREAM's QUIC_SSTREAM, ensuring buffer space is expanded2511* as needed according to flow control.2512*/2513QUIC_NEEDS_LOCK2514static int xso_sstream_append(QUIC_XSO *xso, const unsigned char *buf,2515size_t len, size_t *actual_written)2516{2517QUIC_SSTREAM *sstream = xso->stream->sstream;2518uint64_t cur = ossl_quic_sstream_get_cur_size(sstream);2519uint64_t cwm = ossl_quic_txfc_get_cwm(&xso->stream->txfc);2520uint64_t permitted = (cwm >= cur ? cwm - cur : 0);25212522if (len > permitted)2523len = (size_t)permitted;25242525if (!sstream_ensure_spare(sstream, len))2526return 0;25272528return ossl_quic_sstream_append(sstream, buf, len, actual_written);2529}25302531QUIC_NEEDS_LOCK2532static int quic_write_again(void *arg)2533{2534struct quic_write_again_args *args = arg;2535size_t actual_written = 0;25362537if (!quic_mutation_allowed(args->xso->conn, /*req_active=*/1))2538/* If connection is torn down due to an error while blocking, stop. */2539return -2;25402541if (!quic_validate_for_write(args->xso, &args->err))2542/*2543* Stream may have become invalid for write due to connection events2544* while we blocked.2545*/2546return -2;25472548args->err = ERR_R_INTERNAL_ERROR;2549if (!xso_sstream_append(args->xso, args->buf, args->len, &actual_written))2550return -2;25512552quic_post_write(args->xso, actual_written > 0,2553args->len == actual_written, args->flags, 0);25542555args->buf += actual_written;2556args->len -= actual_written;2557args->total_written += actual_written;25582559if (args->len == 0)2560/* Written everything, done. */2561return 1;25622563/* Not written everything yet, keep trying. */2564return 0;2565}25662567QUIC_NEEDS_LOCK2568static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len,2569uint64_t flags, size_t *written)2570{2571int res;2572QUIC_XSO *xso = ctx->xso;2573struct quic_write_again_args args;2574size_t actual_written = 0;25752576/* First make a best effort to append as much of the data as possible. */2577if (!xso_sstream_append(xso, buf, len, &actual_written)) {2578/* Stream already finished or allocation error. */2579*written = 0;2580return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2581}25822583quic_post_write(xso, actual_written > 0, actual_written == len, flags, 1);25842585/*2586* Record however much data we wrote2587*/2588*written = actual_written;25892590if (actual_written == len) {2591/* Managed to append everything on the first try. */2592return 1;2593}25942595/*2596* We did not manage to append all of the data immediately, so the stream2597* buffer has probably filled up. This means we need to block until some of2598* it is freed up.2599*/2600args.xso = xso;2601args.buf = (const unsigned char *)buf + actual_written;2602args.len = len - actual_written;2603args.total_written = 0;2604args.err = ERR_R_INTERNAL_ERROR;2605args.flags = flags;26062607res = block_until_pred(ctx, quic_write_again, &args, 0);2608if (res <= 0) {2609if (!quic_mutation_allowed(xso->conn, /*req_active=*/1))2610return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);2611else2612return QUIC_RAISE_NON_NORMAL_ERROR(ctx, args.err, NULL);2613}26142615/*2616* When waiting on extra buffer space to be available, args.total_written2617* holds the amount of remaining data we requested to write, which will be2618* something less than the len parameter passed in, however much we wrote2619* here, add it to the value that we wrote when we initially called2620* xso_sstream_append2621*/2622*written += args.total_written;2623return 1;2624}26252626/*2627* Functions to manage All-or-Nothing (AON) (that is, non-ENABLE_PARTIAL_WRITE)2628* write semantics.2629*/2630static void aon_write_begin(QUIC_XSO *xso, const unsigned char *buf,2631size_t buf_len, size_t already_sent)2632{2633assert(!xso->aon_write_in_progress);26342635xso->aon_write_in_progress = 1;2636xso->aon_buf_base = buf;2637xso->aon_buf_pos = already_sent;2638xso->aon_buf_len = buf_len;2639}26402641static void aon_write_finish(QUIC_XSO *xso)2642{2643xso->aon_write_in_progress = 0;2644xso->aon_buf_base = NULL;2645xso->aon_buf_pos = 0;2646xso->aon_buf_len = 0;2647}26482649QUIC_NEEDS_LOCK2650static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf,2651size_t len, uint64_t flags,2652size_t *written)2653{2654QUIC_XSO *xso = ctx->xso;2655const void *actual_buf;2656size_t actual_len, actual_written = 0;2657int accept_moving_buffer2658= ((xso->ssl_mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) != 0);26592660if (xso->aon_write_in_progress) {2661/*2662* We are in the middle of an AON write (i.e., a previous write did not2663* manage to append all data to the SSTREAM and we have Enable Partial2664* Write (EPW) mode disabled.)2665*/2666if ((!accept_moving_buffer && xso->aon_buf_base != buf)2667|| len != xso->aon_buf_len)2668/*2669* Pointer must not have changed if we are not in accept moving2670* buffer mode. Length must never change.2671*/2672return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_BAD_WRITE_RETRY, NULL);26732674actual_buf = (unsigned char *)buf + xso->aon_buf_pos;2675actual_len = len - xso->aon_buf_pos;2676assert(actual_len > 0);2677} else {2678actual_buf = buf;2679actual_len = len;2680}26812682/* First make a best effort to append as much of the data as possible. */2683if (!xso_sstream_append(xso, actual_buf, actual_len, &actual_written)) {2684/* Stream already finished or allocation error. */2685*written = 0;2686return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2687}26882689quic_post_write(xso, actual_written > 0, actual_written == actual_len,2690flags, qctx_should_autotick(ctx));26912692if (actual_written == actual_len) {2693/* We have sent everything. */2694if (xso->aon_write_in_progress) {2695/*2696* We have sent everything, and we were in the middle of an AON2697* write. The output write length is the total length of the AON2698* buffer, not however many bytes we managed to write to the stream2699* in this call.2700*/2701*written = xso->aon_buf_len;2702aon_write_finish(xso);2703} else {2704*written = actual_written;2705}27062707return 1;2708}27092710if (xso->aon_write_in_progress) {2711/*2712* AON write is in progress but we have not written everything yet. We2713* may have managed to send zero bytes, or some number of bytes less2714* than the total remaining which need to be appended during this2715* AON operation.2716*/2717xso->aon_buf_pos += actual_written;2718assert(xso->aon_buf_pos < xso->aon_buf_len);2719return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_WRITE);2720}27212722/*2723* Not in an existing AON operation but partial write is not enabled, so we2724* need to begin a new AON operation. However we needn't bother if we didn't2725* actually append anything.2726*/2727if (actual_written > 0)2728aon_write_begin(xso, buf, len, actual_written);27292730/*2731* AON - We do not publicly admit to having appended anything until AON2732* completes.2733*/2734*written = 0;2735return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_WRITE);2736}27372738QUIC_NEEDS_LOCK2739static int quic_write_nonblocking_epw(QCTX *ctx, const void *buf, size_t len,2740uint64_t flags, size_t *written)2741{2742QUIC_XSO *xso = ctx->xso;27432744/* Simple best effort operation. */2745if (!xso_sstream_append(xso, buf, len, written)) {2746/* Stream already finished or allocation error. */2747*written = 0;2748return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2749}27502751quic_post_write(xso, *written > 0, *written == len, flags,2752qctx_should_autotick(ctx));27532754if (*written == 0)2755/* SSL_write_ex returns 0 if it didn't write anything. */2756return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_WRITE);27572758return 1;2759}27602761QUIC_NEEDS_LOCK2762static int quic_validate_for_write(QUIC_XSO *xso, int *err)2763{2764QUIC_STREAM_MAP *qsm;27652766if (xso == NULL || xso->stream == NULL) {2767*err = ERR_R_INTERNAL_ERROR;2768return 0;2769}27702771switch (xso->stream->send_state) {2772default:2773case QUIC_SSTREAM_STATE_NONE:2774*err = SSL_R_STREAM_RECV_ONLY;2775return 0;27762777case QUIC_SSTREAM_STATE_READY:2778qsm = ossl_quic_channel_get_qsm(xso->conn->ch);27792780if (!ossl_quic_stream_map_ensure_send_part_id(qsm, xso->stream)) {2781*err = ERR_R_INTERNAL_ERROR;2782return 0;2783}27842785/* FALLTHROUGH */2786case QUIC_SSTREAM_STATE_SEND:2787case QUIC_SSTREAM_STATE_DATA_SENT:2788if (ossl_quic_sstream_get_final_size(xso->stream->sstream, NULL)) {2789*err = SSL_R_STREAM_FINISHED;2790return 0;2791}2792return 1;27932794case QUIC_SSTREAM_STATE_DATA_RECVD:2795*err = SSL_R_STREAM_FINISHED;2796return 0;27972798case QUIC_SSTREAM_STATE_RESET_SENT:2799case QUIC_SSTREAM_STATE_RESET_RECVD:2800*err = SSL_R_STREAM_RESET;2801return 0;2802}2803}28042805QUIC_TAKES_LOCK2806int ossl_quic_write_flags(SSL *s, const void *buf, size_t len,2807uint64_t flags, size_t *written)2808{2809int ret;2810QCTX ctx;2811int partial_write, err;28122813*written = 0;28142815if (len == 0) {2816/* Do not autocreate default XSO for zero-length writes. */2817if (!expect_quic_cs(s, &ctx))2818return 0;28192820qctx_lock_for_io(&ctx);2821} else {2822if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/1, &ctx))2823return 0;2824}28252826partial_write = ((ctx.xso != NULL)2827? ((ctx.xso->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0) : 0);28282829if ((flags & ~SSL_WRITE_FLAG_CONCLUDE) != 0) {2830ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_UNSUPPORTED_WRITE_FLAG, NULL);2831goto out;2832}28332834if (!quic_mutation_allowed(ctx.qc, /*req_active=*/0)) {2835ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);2836goto out;2837}28382839/*2840* If we haven't finished the handshake, try to advance it.2841* We don't accept writes until the handshake is completed.2842*/2843if (quic_do_handshake(&ctx) < 1) {2844ret = 0;2845goto out;2846}28472848/* Ensure correct stream state, stream send part not concluded, etc. */2849if (len > 0 && !quic_validate_for_write(ctx.xso, &err)) {2850ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL);2851goto out;2852}28532854if (len == 0) {2855if ((flags & SSL_WRITE_FLAG_CONCLUDE) != 0)2856quic_post_write(ctx.xso, 0, 1, flags,2857qctx_should_autotick(&ctx));28582859ret = 1;2860goto out;2861}28622863if (qctx_blocking(&ctx))2864ret = quic_write_blocking(&ctx, buf, len, flags, written);2865else if (partial_write)2866ret = quic_write_nonblocking_epw(&ctx, buf, len, flags, written);2867else2868ret = quic_write_nonblocking_aon(&ctx, buf, len, flags, written);28692870out:2871qctx_unlock(&ctx);2872return ret;2873}28742875QUIC_TAKES_LOCK2876int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written)2877{2878return ossl_quic_write_flags(s, buf, len, 0, written);2879}28802881/*2882* SSL_read2883* --------2884*/2885struct quic_read_again_args {2886QCTX *ctx;2887QUIC_STREAM *stream;2888void *buf;2889size_t len;2890size_t *bytes_read;2891int peek;2892};28932894QUIC_NEEDS_LOCK2895static int quic_validate_for_read(QUIC_XSO *xso, int *err, int *eos)2896{2897QUIC_STREAM_MAP *qsm;28982899*eos = 0;29002901if (xso == NULL || xso->stream == NULL) {2902*err = ERR_R_INTERNAL_ERROR;2903return 0;2904}29052906switch (xso->stream->recv_state) {2907default:2908case QUIC_RSTREAM_STATE_NONE:2909*err = SSL_R_STREAM_SEND_ONLY;2910return 0;29112912case QUIC_RSTREAM_STATE_RECV:2913case QUIC_RSTREAM_STATE_SIZE_KNOWN:2914case QUIC_RSTREAM_STATE_DATA_RECVD:2915return 1;29162917case QUIC_RSTREAM_STATE_DATA_READ:2918*eos = 1;2919return 0;29202921case QUIC_RSTREAM_STATE_RESET_RECVD:2922qsm = ossl_quic_channel_get_qsm(xso->conn->ch);2923ossl_quic_stream_map_notify_app_read_reset_recv_part(qsm, xso->stream);29242925/* FALLTHROUGH */2926case QUIC_RSTREAM_STATE_RESET_READ:2927*err = SSL_R_STREAM_RESET;2928return 0;2929}2930}29312932QUIC_NEEDS_LOCK2933static int quic_read_actual(QCTX *ctx,2934QUIC_STREAM *stream,2935void *buf, size_t buf_len,2936size_t *bytes_read,2937int peek)2938{2939int is_fin = 0, err, eos;2940QUIC_CONNECTION *qc = ctx->qc;29412942if (!quic_validate_for_read(ctx->xso, &err, &eos)) {2943if (eos) {2944ctx->xso->retired_fin = 1;2945return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN);2946} else {2947return QUIC_RAISE_NON_NORMAL_ERROR(ctx, err, NULL);2948}2949}29502951if (peek) {2952if (!ossl_quic_rstream_peek(stream->rstream, buf, buf_len,2953bytes_read, &is_fin))2954return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);29552956} else {2957if (!ossl_quic_rstream_read(stream->rstream, buf, buf_len,2958bytes_read, &is_fin))2959return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2960}29612962if (!peek) {2963if (*bytes_read > 0) {2964/*2965* We have read at least one byte from the stream. Inform stream-level2966* RXFC of the retirement of controlled bytes. Update the active stream2967* status (the RXFC may now want to emit a frame granting more credit to2968* the peer).2969*/2970OSSL_RTT_INFO rtt_info;29712972ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(qc->ch), &rtt_info);29732974if (!ossl_quic_rxfc_on_retire(&stream->rxfc, *bytes_read,2975rtt_info.smoothed_rtt))2976return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);2977}29782979if (is_fin && !peek) {2980QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(ctx->qc->ch);29812982ossl_quic_stream_map_notify_totally_read(qsm, ctx->xso->stream);2983}29842985if (*bytes_read > 0)2986ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(qc->ch),2987stream);2988}29892990if (*bytes_read == 0 && is_fin) {2991ctx->xso->retired_fin = 1;2992return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN);2993}29942995return 1;2996}29972998QUIC_NEEDS_LOCK2999static int quic_read_again(void *arg)3000{3001struct quic_read_again_args *args = arg;30023003if (!quic_mutation_allowed(args->ctx->qc, /*req_active=*/1)) {3004/* If connection is torn down due to an error while blocking, stop. */3005QUIC_RAISE_NON_NORMAL_ERROR(args->ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);3006return -1;3007}30083009if (!quic_read_actual(args->ctx, args->stream,3010args->buf, args->len, args->bytes_read,3011args->peek))3012return -1;30133014if (*args->bytes_read > 0)3015/* got at least one byte, the SSL_read op can finish now */3016return 1;30173018return 0; /* did not read anything, keep trying */3019}30203021QUIC_TAKES_LOCK3022static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek)3023{3024int ret, res;3025QCTX ctx;3026struct quic_read_again_args args;30273028*bytes_read = 0;30293030if (!expect_quic_cs(s, &ctx))3031return 0;30323033qctx_lock_for_io(&ctx);30343035/* If we haven't finished the handshake, try to advance it. */3036if (quic_do_handshake(&ctx) < 1) {3037ret = 0; /* ossl_quic_do_handshake raised error here */3038goto out;3039}30403041if (ctx.xso == NULL) {3042/*3043* Called on a QCSO and we don't currently have a default stream.3044*3045* Wait until we get a stream initiated by the peer (blocking mode) or3046* fail if we don't have one yet (non-blocking mode).3047*/3048if (!qc_wait_for_default_xso_for_read(&ctx, /*peek=*/0)) {3049ret = 0; /* error already raised here */3050goto out;3051}30523053ctx.xso = ctx.qc->default_xso;3054}30553056if (!quic_read_actual(&ctx, ctx.xso->stream, buf, len, bytes_read, peek)) {3057ret = 0; /* quic_read_actual raised error here */3058goto out;3059}30603061if (*bytes_read > 0) {3062/*3063* Even though we succeeded, tick the reactor here to ensure we are3064* handling other aspects of the QUIC connection.3065*/3066if (quic_mutation_allowed(ctx.qc, /*req_active=*/0))3067qctx_maybe_autotick(&ctx);30683069ret = 1;3070} else if (!quic_mutation_allowed(ctx.qc, /*req_active=*/0)) {3071ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);3072goto out;3073} else if (qctx_blocking(&ctx)) {3074/*3075* We were not able to read anything immediately, so our stream3076* buffer is empty. This means we need to block until we get3077* at least one byte.3078*/3079args.ctx = &ctx;3080args.stream = ctx.xso->stream;3081args.buf = buf;3082args.len = len;3083args.bytes_read = bytes_read;3084args.peek = peek;30853086res = block_until_pred(&ctx, quic_read_again, &args, 0);3087if (res == 0) {3088ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL);3089goto out;3090} else if (res < 0) {3091ret = 0; /* quic_read_again raised error here */3092goto out;3093}30943095ret = 1;3096} else {3097/*3098* We did not get any bytes and are not in blocking mode.3099* Tick to see if this delivers any more.3100*/3101qctx_maybe_autotick(&ctx);31023103/* Try the read again. */3104if (!quic_read_actual(&ctx, ctx.xso->stream, buf, len, bytes_read, peek)) {3105ret = 0; /* quic_read_actual raised error here */3106goto out;3107}31083109if (*bytes_read > 0)3110ret = 1; /* Succeeded this time. */3111else3112ret = QUIC_RAISE_NORMAL_ERROR(&ctx, SSL_ERROR_WANT_READ);3113}31143115out:3116qctx_unlock(&ctx);3117return ret;3118}31193120int ossl_quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read)3121{3122return quic_read(s, buf, len, bytes_read, 0);3123}31243125int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *bytes_read)3126{3127return quic_read(s, buf, len, bytes_read, 1);3128}31293130/*3131* SSL_pending3132* -----------3133*/31343135QUIC_TAKES_LOCK3136static size_t ossl_quic_pending_int(const SSL *s, int check_channel)3137{3138QCTX ctx;3139size_t avail = 0;31403141if (!expect_quic_cs(s, &ctx))3142return 0;31433144qctx_lock(&ctx);31453146if (!ctx.qc->started)3147goto out;31483149if (ctx.xso == NULL) {3150/* No XSO yet, but there might be a default XSO eligible to be created. */3151if (qc_wait_for_default_xso_for_read(&ctx, /*peek=*/1)) {3152ctx.xso = ctx.qc->default_xso;3153} else {3154QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_NO_STREAM, NULL);3155goto out;3156}3157}31583159if (ctx.xso->stream == NULL) {3160QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL);3161goto out;3162}31633164if (check_channel)3165avail = ossl_quic_stream_recv_pending(ctx.xso->stream,3166/*include_fin=*/1)3167|| ossl_quic_channel_has_pending(ctx.qc->ch)3168|| ossl_quic_channel_is_term_any(ctx.qc->ch);3169else3170avail = ossl_quic_stream_recv_pending(ctx.xso->stream,3171/*include_fin=*/0);31723173out:3174qctx_unlock(&ctx);3175return avail;3176}31773178size_t ossl_quic_pending(const SSL *s)3179{3180return ossl_quic_pending_int(s, /*check_channel=*/0);3181}31823183int ossl_quic_has_pending(const SSL *s)3184{3185/* Do we have app-side pending data or pending URXEs or RXEs? */3186return ossl_quic_pending_int(s, /*check_channel=*/1) > 0;3187}31883189/*3190* SSL_stream_conclude3191* -------------------3192*/3193QUIC_TAKES_LOCK3194int ossl_quic_conn_stream_conclude(SSL *s)3195{3196QCTX ctx;3197QUIC_STREAM *qs;3198int err;3199int ret;32003201if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/0, &ctx))3202return 0;32033204qs = ctx.xso->stream;32053206if (!quic_mutation_allowed(ctx.qc, /*req_active=*/1)) {3207ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);3208qctx_unlock(&ctx);3209return ret;3210}32113212if (!quic_validate_for_write(ctx.xso, &err)) {3213ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL);3214qctx_unlock(&ctx);3215return ret;3216}32173218if (ossl_quic_sstream_get_final_size(qs->sstream, NULL)) {3219qctx_unlock(&ctx);3220return 1;3221}32223223ossl_quic_sstream_fin(qs->sstream);3224quic_post_write(ctx.xso, 1, 0, 0, qctx_should_autotick(&ctx));3225qctx_unlock(&ctx);3226return 1;3227}32283229/*3230* SSL_inject_net_dgram3231* --------------------3232*/3233QUIC_TAKES_LOCK3234int SSL_inject_net_dgram(SSL *s, const unsigned char *buf,3235size_t buf_len,3236const BIO_ADDR *peer,3237const BIO_ADDR *local)3238{3239int ret = 0;3240QCTX ctx;3241QUIC_DEMUX *demux;3242QUIC_PORT *port;32433244if (!expect_quic_csl(s, &ctx))3245return 0;32463247qctx_lock(&ctx);32483249port = ossl_quic_obj_get0_port(ctx.obj);3250if (port == NULL) {3251QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL);3252goto err;3253}32543255demux = ossl_quic_port_get0_demux(port);3256ret = ossl_quic_demux_inject(demux, buf, buf_len, peer, local);32573258err:3259qctx_unlock(&ctx);3260return ret;3261}32623263/*3264* SSL_get0_connection3265* -------------------3266*/3267SSL *ossl_quic_get0_connection(SSL *s)3268{3269QCTX ctx;32703271if (!expect_quic_cs(s, &ctx))3272return NULL;32733274return &ctx.qc->obj.ssl;3275}32763277/*3278* SSL_get0_listener3279* -----------------3280*/3281SSL *ossl_quic_get0_listener(SSL *s)3282{3283QCTX ctx;32843285if (!expect_quic_csl(s, &ctx))3286return NULL;32873288return ctx.ql != NULL ? &ctx.ql->obj.ssl : NULL;3289}32903291/*3292* SSL_get0_domain3293* ---------------3294*/3295SSL *ossl_quic_get0_domain(SSL *s)3296{3297QCTX ctx;32983299if (!expect_quic_any(s, &ctx))3300return NULL;33013302return ctx.qd != NULL ? &ctx.qd->obj.ssl : NULL;3303}33043305/*3306* SSL_get_domain_flags3307* --------------------3308*/3309int ossl_quic_get_domain_flags(const SSL *ssl, uint64_t *domain_flags)3310{3311QCTX ctx;33123313if (!expect_quic_any(ssl, &ctx))3314return 0;33153316if (domain_flags != NULL)3317*domain_flags = ctx.obj->domain_flags;33183319return 1;3320}33213322/*3323* SSL_get_stream_type3324* -------------------3325*/3326int ossl_quic_get_stream_type(SSL *s)3327{3328QCTX ctx;33293330if (!expect_quic_cs(s, &ctx))3331return SSL_STREAM_TYPE_BIDI;33323333if (ctx.xso == NULL) {3334/*3335* If deferred XSO creation has yet to occur, proceed according to the3336* default stream mode. If AUTO_BIDI or AUTO_UNI is set, we cannot know3337* what kind of stream will be created yet, so return BIDI on the basis3338* that at this time, the client still has the option of calling3339* SSL_read() or SSL_write() first.3340*/3341if (ctx.qc->default_xso_created3342|| ctx.qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE)3343return SSL_STREAM_TYPE_NONE;3344else3345return SSL_STREAM_TYPE_BIDI;3346}33473348if (ossl_quic_stream_is_bidi(ctx.xso->stream))3349return SSL_STREAM_TYPE_BIDI;33503351if (ossl_quic_stream_is_server_init(ctx.xso->stream) != ctx.qc->as_server)3352return SSL_STREAM_TYPE_READ;3353else3354return SSL_STREAM_TYPE_WRITE;3355}33563357/*3358* SSL_get_stream_id3359* -----------------3360*/3361QUIC_TAKES_LOCK3362uint64_t ossl_quic_get_stream_id(SSL *s)3363{3364QCTX ctx;3365uint64_t id;33663367if (!expect_quic_with_stream_lock(s, /*remote_init=*/-1, /*io=*/0, &ctx))3368return UINT64_MAX;33693370id = ctx.xso->stream->id;3371qctx_unlock(&ctx);33723373return id;3374}33753376/*3377* SSL_is_stream_local3378* -------------------3379*/3380QUIC_TAKES_LOCK3381int ossl_quic_is_stream_local(SSL *s)3382{3383QCTX ctx;3384int is_local;33853386if (!expect_quic_with_stream_lock(s, /*remote_init=*/-1, /*io=*/0, &ctx))3387return -1;33883389is_local = ossl_quic_stream_is_local_init(ctx.xso->stream);3390qctx_unlock(&ctx);33913392return is_local;3393}33943395/*3396* SSL_set_default_stream_mode3397* ---------------------------3398*/3399QUIC_TAKES_LOCK3400int ossl_quic_set_default_stream_mode(SSL *s, uint32_t mode)3401{3402QCTX ctx;34033404if (!expect_quic_conn_only(s, &ctx))3405return 0;34063407qctx_lock(&ctx);34083409if (ctx.qc->default_xso_created) {3410qctx_unlock(&ctx);3411return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,3412"too late to change default stream mode");3413}34143415switch (mode) {3416case SSL_DEFAULT_STREAM_MODE_NONE:3417case SSL_DEFAULT_STREAM_MODE_AUTO_BIDI:3418case SSL_DEFAULT_STREAM_MODE_AUTO_UNI:3419ctx.qc->default_stream_mode = mode;3420break;3421default:3422qctx_unlock(&ctx);3423return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT,3424"bad default stream type");3425}34263427qctx_unlock(&ctx);3428return 1;3429}34303431/*3432* SSL_detach_stream3433* -----------------3434*/3435QUIC_TAKES_LOCK3436SSL *ossl_quic_detach_stream(SSL *s)3437{3438QCTX ctx;3439QUIC_XSO *xso = NULL;34403441if (!expect_quic_conn_only(s, &ctx))3442return NULL;34433444qctx_lock(&ctx);34453446/* Calling this function inhibits default XSO autocreation. */3447/* QC ref to any default XSO is transferred to us and to caller. */3448qc_set_default_xso_keep_ref(ctx.qc, NULL, /*touch=*/1, &xso);34493450qctx_unlock(&ctx);34513452return xso != NULL ? &xso->obj.ssl : NULL;3453}34543455/*3456* SSL_attach_stream3457* -----------------3458*/3459QUIC_TAKES_LOCK3460int ossl_quic_attach_stream(SSL *conn, SSL *stream)3461{3462QCTX ctx;3463QUIC_XSO *xso;3464int nref;34653466if (!expect_quic_conn_only(conn, &ctx))3467return 0;34683469if (stream == NULL || stream->type != SSL_TYPE_QUIC_XSO)3470return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_NULL_PARAMETER,3471"stream to attach must be a valid QUIC stream");34723473xso = (QUIC_XSO *)stream;34743475qctx_lock(&ctx);34763477if (ctx.qc->default_xso != NULL) {3478qctx_unlock(&ctx);3479return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,3480"connection already has a default stream");3481}34823483/*3484* It is a caller error for the XSO being attached as a default XSO to have3485* more than one ref.3486*/3487if (!CRYPTO_GET_REF(&xso->obj.ssl.references, &nref)) {3488qctx_unlock(&ctx);3489return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR,3490"ref");3491}34923493if (nref != 1) {3494qctx_unlock(&ctx);3495return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT,3496"stream being attached must have "3497"only 1 reference");3498}34993500/* Caller's reference to the XSO is transferred to us. */3501/* Calling this function inhibits default XSO autocreation. */3502qc_set_default_xso(ctx.qc, xso, /*touch=*/1);35033504qctx_unlock(&ctx);3505return 1;3506}35073508/*3509* SSL_set_incoming_stream_policy3510* ------------------------------3511*/3512QUIC_NEEDS_LOCK3513static int qc_get_effective_incoming_stream_policy(QUIC_CONNECTION *qc)3514{3515switch (qc->incoming_stream_policy) {3516case SSL_INCOMING_STREAM_POLICY_AUTO:3517if ((qc->default_xso == NULL && !qc->default_xso_created)3518|| qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE)3519return SSL_INCOMING_STREAM_POLICY_ACCEPT;3520else3521return SSL_INCOMING_STREAM_POLICY_REJECT;35223523default:3524return qc->incoming_stream_policy;3525}3526}35273528QUIC_NEEDS_LOCK3529static void qc_update_reject_policy(QUIC_CONNECTION *qc)3530{3531int policy = qc_get_effective_incoming_stream_policy(qc);3532int enable_reject = (policy == SSL_INCOMING_STREAM_POLICY_REJECT);35333534ossl_quic_channel_set_incoming_stream_auto_reject(qc->ch,3535enable_reject,3536qc->incoming_stream_aec);3537}35383539QUIC_TAKES_LOCK3540int ossl_quic_set_incoming_stream_policy(SSL *s, int policy,3541uint64_t aec)3542{3543int ret = 1;3544QCTX ctx;35453546if (!expect_quic_conn_only(s, &ctx))3547return 0;35483549qctx_lock(&ctx);35503551switch (policy) {3552case SSL_INCOMING_STREAM_POLICY_AUTO:3553case SSL_INCOMING_STREAM_POLICY_ACCEPT:3554case SSL_INCOMING_STREAM_POLICY_REJECT:3555ctx.qc->incoming_stream_policy = policy;3556ctx.qc->incoming_stream_aec = aec;3557break;35583559default:3560QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL);3561ret = 0;3562break;3563}35643565qc_update_reject_policy(ctx.qc);3566qctx_unlock(&ctx);3567return ret;3568}35693570/*3571* SSL_get_value, SSL_set_value3572* ----------------------------3573*/3574QUIC_TAKES_LOCK3575static int qc_getset_idle_timeout(QCTX *ctx, uint32_t class_,3576uint64_t *p_value_out, uint64_t *p_value_in)3577{3578int ret = 0;3579uint64_t value_out = 0, value_in;35803581qctx_lock(ctx);35823583switch (class_) {3584case SSL_VALUE_CLASS_FEATURE_REQUEST:3585value_out = ossl_quic_channel_get_max_idle_timeout_request(ctx->qc->ch);35863587if (p_value_in != NULL) {3588value_in = *p_value_in;3589if (value_in > OSSL_QUIC_VLINT_MAX) {3590QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT,3591NULL);3592goto err;3593}35943595if (ossl_quic_channel_have_generated_transport_params(ctx->qc->ch)) {3596QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_FEATURE_NOT_RENEGOTIABLE,3597NULL);3598goto err;3599}36003601ossl_quic_channel_set_max_idle_timeout_request(ctx->qc->ch, value_in);3602}3603break;36043605case SSL_VALUE_CLASS_FEATURE_PEER_REQUEST:3606case SSL_VALUE_CLASS_FEATURE_NEGOTIATED:3607if (p_value_in != NULL) {3608QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_OP,3609NULL);3610goto err;3611}36123613if (!ossl_quic_channel_is_handshake_complete(ctx->qc->ch)) {3614QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE,3615NULL);3616goto err;3617}36183619value_out = (class_ == SSL_VALUE_CLASS_FEATURE_NEGOTIATED)3620? ossl_quic_channel_get_max_idle_timeout_actual(ctx->qc->ch)3621: ossl_quic_channel_get_max_idle_timeout_peer_request(ctx->qc->ch);3622break;36233624default:3625QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS,3626NULL);3627goto err;3628}36293630ret = 1;3631err:3632qctx_unlock(ctx);3633if (ret && p_value_out != NULL)3634*p_value_out = value_out;36353636return ret;3637}36383639QUIC_TAKES_LOCK3640static int qc_get_stream_avail(QCTX *ctx, uint32_t class_,3641int is_uni, int is_remote,3642uint64_t *value)3643{3644int ret = 0;36453646if (class_ != SSL_VALUE_CLASS_GENERIC) {3647QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS,3648NULL);3649return 0;3650}36513652qctx_lock(ctx);36533654*value = is_remote3655? ossl_quic_channel_get_remote_stream_count_avail(ctx->qc->ch, is_uni)3656: ossl_quic_channel_get_local_stream_count_avail(ctx->qc->ch, is_uni);36573658ret = 1;3659qctx_unlock(ctx);3660return ret;3661}36623663QUIC_NEEDS_LOCK3664static int qctx_should_autotick(QCTX *ctx)3665{3666int event_handling_mode;3667QUIC_OBJ *obj = ctx->obj;36683669for (; (event_handling_mode = obj->event_handling_mode) == SSL_VALUE_EVENT_HANDLING_MODE_INHERIT3670&& obj->parent_obj != NULL; obj = obj->parent_obj);36713672return event_handling_mode != SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT;3673}36743675QUIC_NEEDS_LOCK3676static void qctx_maybe_autotick(QCTX *ctx)3677{3678if (!qctx_should_autotick(ctx))3679return;36803681ossl_quic_reactor_tick(ossl_quic_obj_get0_reactor(ctx->obj), 0);3682}36833684QUIC_TAKES_LOCK3685static int qc_getset_event_handling(QCTX *ctx, uint32_t class_,3686uint64_t *p_value_out,3687uint64_t *p_value_in)3688{3689int ret = 0;3690uint64_t value_out = 0;36913692qctx_lock(ctx);36933694if (class_ != SSL_VALUE_CLASS_GENERIC) {3695QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS,3696NULL);3697goto err;3698}36993700if (p_value_in != NULL) {3701switch (*p_value_in) {3702case SSL_VALUE_EVENT_HANDLING_MODE_INHERIT:3703case SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT:3704case SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT:3705break;3706default:3707QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT,3708NULL);3709goto err;3710}37113712value_out = *p_value_in;3713ctx->obj->event_handling_mode = (int)value_out;3714} else {3715value_out = ctx->obj->event_handling_mode;3716}37173718ret = 1;3719err:3720qctx_unlock(ctx);3721if (ret && p_value_out != NULL)3722*p_value_out = value_out;37233724return ret;3725}37263727QUIC_TAKES_LOCK3728static int qc_get_stream_write_buf_stat(QCTX *ctx, uint32_t class_,3729uint64_t *p_value_out,3730size_t (*getter)(QUIC_SSTREAM *sstream))3731{3732int ret = 0;3733size_t value = 0;37343735qctx_lock(ctx);37363737if (class_ != SSL_VALUE_CLASS_GENERIC) {3738QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS,3739NULL);3740goto err;3741}37423743if (ctx->xso == NULL) {3744QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL);3745goto err;3746}37473748if (!ossl_quic_stream_has_send(ctx->xso->stream)) {3749QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_STREAM_RECV_ONLY, NULL);3750goto err;3751}37523753if (ossl_quic_stream_has_send_buffer(ctx->xso->stream))3754value = getter(ctx->xso->stream->sstream);37553756ret = 1;3757err:3758qctx_unlock(ctx);3759*p_value_out = (uint64_t)value;3760return ret;3761}37623763QUIC_NEEDS_LOCK3764static int expect_quic_for_value(SSL *s, QCTX *ctx, uint32_t id)3765{3766switch (id) {3767case SSL_VALUE_EVENT_HANDLING_MODE:3768case SSL_VALUE_STREAM_WRITE_BUF_SIZE:3769case SSL_VALUE_STREAM_WRITE_BUF_USED:3770case SSL_VALUE_STREAM_WRITE_BUF_AVAIL:3771return expect_quic_cs(s, ctx);3772default:3773return expect_quic_conn_only(s, ctx);3774}3775}37763777QUIC_TAKES_LOCK3778int ossl_quic_get_value_uint(SSL *s, uint32_t class_, uint32_t id,3779uint64_t *value)3780{3781QCTX ctx;37823783if (!expect_quic_for_value(s, &ctx, id))3784return 0;37853786if (value == NULL)3787return QUIC_RAISE_NON_NORMAL_ERROR(&ctx,3788ERR_R_PASSED_INVALID_ARGUMENT, NULL);37893790switch (id) {3791case SSL_VALUE_QUIC_IDLE_TIMEOUT:3792return qc_getset_idle_timeout(&ctx, class_, value, NULL);37933794case SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL:3795return qc_get_stream_avail(&ctx, class_, /*uni=*/0, /*remote=*/0, value);3796case SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL:3797return qc_get_stream_avail(&ctx, class_, /*uni=*/0, /*remote=*/1, value);3798case SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL:3799return qc_get_stream_avail(&ctx, class_, /*uni=*/1, /*remote=*/0, value);3800case SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL:3801return qc_get_stream_avail(&ctx, class_, /*uni=*/1, /*remote=*/1, value);38023803case SSL_VALUE_EVENT_HANDLING_MODE:3804return qc_getset_event_handling(&ctx, class_, value, NULL);38053806case SSL_VALUE_STREAM_WRITE_BUF_SIZE:3807return qc_get_stream_write_buf_stat(&ctx, class_, value,3808ossl_quic_sstream_get_buffer_size);3809case SSL_VALUE_STREAM_WRITE_BUF_USED:3810return qc_get_stream_write_buf_stat(&ctx, class_, value,3811ossl_quic_sstream_get_buffer_used);3812case SSL_VALUE_STREAM_WRITE_BUF_AVAIL:3813return qc_get_stream_write_buf_stat(&ctx, class_, value,3814ossl_quic_sstream_get_buffer_avail);38153816default:3817return QUIC_RAISE_NON_NORMAL_ERROR(&ctx,3818SSL_R_UNSUPPORTED_CONFIG_VALUE, NULL);3819}38203821return 1;3822}38233824QUIC_TAKES_LOCK3825int ossl_quic_set_value_uint(SSL *s, uint32_t class_, uint32_t id,3826uint64_t value)3827{3828QCTX ctx;38293830if (!expect_quic_for_value(s, &ctx, id))3831return 0;38323833switch (id) {3834case SSL_VALUE_QUIC_IDLE_TIMEOUT:3835return qc_getset_idle_timeout(&ctx, class_, NULL, &value);38363837case SSL_VALUE_EVENT_HANDLING_MODE:3838return qc_getset_event_handling(&ctx, class_, NULL, &value);38393840default:3841return QUIC_RAISE_NON_NORMAL_ERROR(&ctx,3842SSL_R_UNSUPPORTED_CONFIG_VALUE, NULL);3843}38443845return 1;3846}38473848/*3849* SSL_accept_stream3850* -----------------3851*/3852struct wait_for_incoming_stream_args {3853QCTX *ctx;3854QUIC_STREAM *qs;3855};38563857QUIC_NEEDS_LOCK3858static int wait_for_incoming_stream(void *arg)3859{3860struct wait_for_incoming_stream_args *args = arg;3861QUIC_CONNECTION *qc = args->ctx->qc;3862QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(qc->ch);38633864if (!quic_mutation_allowed(qc, /*req_active=*/1)) {3865/* If connection is torn down due to an error while blocking, stop. */3866QUIC_RAISE_NON_NORMAL_ERROR(args->ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);3867return -1;3868}38693870args->qs = ossl_quic_stream_map_peek_accept_queue(qsm);3871if (args->qs != NULL)3872return 1; /* got a stream */38733874return 0; /* did not get a stream, keep trying */3875}38763877QUIC_TAKES_LOCK3878SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags)3879{3880QCTX ctx;3881int ret;3882SSL *new_s = NULL;3883QUIC_STREAM_MAP *qsm;3884QUIC_STREAM *qs;3885QUIC_XSO *xso;3886OSSL_RTT_INFO rtt_info;38873888if (!expect_quic_conn_only(s, &ctx))3889return NULL;38903891qctx_lock(&ctx);38923893if (qc_get_effective_incoming_stream_policy(ctx.qc)3894== SSL_INCOMING_STREAM_POLICY_REJECT) {3895QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, NULL);3896goto out;3897}38983899qsm = ossl_quic_channel_get_qsm(ctx.qc->ch);39003901qs = ossl_quic_stream_map_peek_accept_queue(qsm);3902if (qs == NULL) {3903if (qctx_blocking(&ctx)3904&& (flags & SSL_ACCEPT_STREAM_NO_BLOCK) == 0) {3905struct wait_for_incoming_stream_args args;39063907args.ctx = &ctx;3908args.qs = NULL;39093910ret = block_until_pred(&ctx, wait_for_incoming_stream, &args, 0);3911if (ret == 0) {3912QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL);3913goto out;3914} else if (ret < 0 || args.qs == NULL) {3915goto out;3916}39173918qs = args.qs;3919} else {3920goto out;3921}3922}39233924xso = create_xso_from_stream(ctx.qc, qs);3925if (xso == NULL)3926goto out;39273928ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ctx.qc->ch), &rtt_info);3929ossl_quic_stream_map_remove_from_accept_queue(qsm, qs,3930rtt_info.smoothed_rtt);3931new_s = &xso->obj.ssl;39323933/* Calling this function inhibits default XSO autocreation. */3934qc_touch_default_xso(ctx.qc); /* inhibits default XSO */39353936out:3937qctx_unlock(&ctx);3938return new_s;3939}39403941/*3942* SSL_get_accept_stream_queue_len3943* -------------------------------3944*/3945QUIC_TAKES_LOCK3946size_t ossl_quic_get_accept_stream_queue_len(SSL *s)3947{3948QCTX ctx;3949size_t v;39503951if (!expect_quic_conn_only(s, &ctx))3952return 0;39533954qctx_lock(&ctx);39553956v = ossl_quic_stream_map_get_total_accept_queue_len(ossl_quic_channel_get_qsm(ctx.qc->ch));39573958qctx_unlock(&ctx);3959return v;3960}39613962/*3963* SSL_stream_reset3964* ----------------3965*/3966int ossl_quic_stream_reset(SSL *ssl,3967const SSL_STREAM_RESET_ARGS *args,3968size_t args_len)3969{3970QCTX ctx;3971QUIC_STREAM_MAP *qsm;3972QUIC_STREAM *qs;3973uint64_t error_code;3974int ok, err;39753976if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/0, /*io=*/0, &ctx))3977return 0;39783979qsm = ossl_quic_channel_get_qsm(ctx.qc->ch);3980qs = ctx.xso->stream;3981error_code = (args != NULL ? args->quic_error_code : 0);39823983if (!quic_validate_for_write(ctx.xso, &err)) {3984ok = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL);3985goto err;3986}39873988ok = ossl_quic_stream_map_reset_stream_send_part(qsm, qs, error_code);3989if (ok)3990ctx.xso->requested_reset = 1;39913992err:3993qctx_unlock(&ctx);3994return ok;3995}39963997/*3998* SSL_get_stream_read_state3999* -------------------------4000*/4001static void quic_classify_stream(QUIC_CONNECTION *qc,4002QUIC_STREAM *qs,4003int is_write,4004int *state,4005uint64_t *app_error_code)4006{4007int local_init;4008uint64_t final_size;40094010local_init = (ossl_quic_stream_is_server_init(qs) == qc->as_server);40114012if (app_error_code != NULL)4013*app_error_code = UINT64_MAX;4014else4015app_error_code = &final_size; /* throw away value */40164017if (!ossl_quic_stream_is_bidi(qs) && local_init != is_write) {4018/*4019* Unidirectional stream and this direction of transmission doesn't4020* exist.4021*/4022*state = SSL_STREAM_STATE_WRONG_DIR;4023} else if (ossl_quic_channel_is_term_any(qc->ch)) {4024/* Connection already closed. */4025*state = SSL_STREAM_STATE_CONN_CLOSED;4026} else if (!is_write && qs->recv_state == QUIC_RSTREAM_STATE_DATA_READ) {4027/* Application has read a FIN. */4028*state = SSL_STREAM_STATE_FINISHED;4029} else if ((!is_write && qs->stop_sending)4030|| (is_write && ossl_quic_stream_send_is_reset(qs))) {4031/*4032* Stream has been reset locally. FIN takes precedence over this for the4033* read case as the application need not care if the stream is reset4034* after a FIN has been successfully processed.4035*/4036*state = SSL_STREAM_STATE_RESET_LOCAL;4037*app_error_code = !is_write4038? qs->stop_sending_aec4039: qs->reset_stream_aec;4040} else if ((!is_write && ossl_quic_stream_recv_is_reset(qs))4041|| (is_write && qs->peer_stop_sending)) {4042/*4043* Stream has been reset remotely. */4044*state = SSL_STREAM_STATE_RESET_REMOTE;4045*app_error_code = !is_write4046? qs->peer_reset_stream_aec4047: qs->peer_stop_sending_aec;4048} else if (is_write && ossl_quic_sstream_get_final_size(qs->sstream,4049&final_size)) {4050/*4051* Stream has been finished. Stream reset takes precedence over this for4052* the write case as peer may not have received all data.4053*/4054*state = SSL_STREAM_STATE_FINISHED;4055} else {4056/* Stream still healthy. */4057*state = SSL_STREAM_STATE_OK;4058}4059}40604061static int quic_get_stream_state(SSL *ssl, int is_write)4062{4063QCTX ctx;4064int state;40654066if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/-1, /*io=*/0, &ctx))4067return SSL_STREAM_STATE_NONE;40684069quic_classify_stream(ctx.qc, ctx.xso->stream, is_write, &state, NULL);4070qctx_unlock(&ctx);4071return state;4072}40734074int ossl_quic_get_stream_read_state(SSL *ssl)4075{4076return quic_get_stream_state(ssl, /*is_write=*/0);4077}40784079/*4080* SSL_get_stream_write_state4081* --------------------------4082*/4083int ossl_quic_get_stream_write_state(SSL *ssl)4084{4085return quic_get_stream_state(ssl, /*is_write=*/1);4086}40874088/*4089* SSL_get_stream_read_error_code4090* ------------------------------4091*/4092static int quic_get_stream_error_code(SSL *ssl, int is_write,4093uint64_t *app_error_code)4094{4095QCTX ctx;4096int state;40974098if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/-1, /*io=*/0, &ctx))4099return -1;41004101quic_classify_stream(ctx.qc, ctx.xso->stream, /*is_write=*/0,4102&state, app_error_code);41034104qctx_unlock(&ctx);4105switch (state) {4106case SSL_STREAM_STATE_FINISHED:4107return 0;4108case SSL_STREAM_STATE_RESET_LOCAL:4109case SSL_STREAM_STATE_RESET_REMOTE:4110return 1;4111default:4112return -1;4113}4114}41154116int ossl_quic_get_stream_read_error_code(SSL *ssl, uint64_t *app_error_code)4117{4118return quic_get_stream_error_code(ssl, /*is_write=*/0, app_error_code);4119}41204121/*4122* SSL_get_stream_write_error_code4123* -------------------------------4124*/4125int ossl_quic_get_stream_write_error_code(SSL *ssl, uint64_t *app_error_code)4126{4127return quic_get_stream_error_code(ssl, /*is_write=*/1, app_error_code);4128}41294130/*4131* Write buffer size mutation4132* --------------------------4133*/4134int ossl_quic_set_write_buffer_size(SSL *ssl, size_t size)4135{4136int ret = 0;4137QCTX ctx;41384139if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/-1, /*io=*/0, &ctx))4140return 0;41414142if (!ossl_quic_stream_has_send(ctx.xso->stream)) {4143/* Called on a unidirectional receive-only stream - error. */4144QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, NULL);4145goto out;4146}41474148if (!ossl_quic_stream_has_send_buffer(ctx.xso->stream)) {4149/*4150* If the stream has a send part but we have disposed of it because we4151* no longer need it, this is a no-op.4152*/4153ret = 1;4154goto out;4155}41564157if (!ossl_quic_sstream_set_buffer_size(ctx.xso->stream->sstream, size)) {4158QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL);4159goto out;4160}41614162ret = 1;41634164out:4165qctx_unlock(&ctx);4166return ret;4167}41684169/*4170* SSL_get_conn_close_info4171* -----------------------4172*/4173int ossl_quic_get_conn_close_info(SSL *ssl,4174SSL_CONN_CLOSE_INFO *info,4175size_t info_len)4176{4177QCTX ctx;4178const QUIC_TERMINATE_CAUSE *tc;41794180if (!expect_quic_conn_only(ssl, &ctx))4181return -1;41824183tc = ossl_quic_channel_get_terminate_cause(ctx.qc->ch);4184if (tc == NULL)4185return 0;41864187info->error_code = tc->error_code;4188info->frame_type = tc->frame_type;4189info->reason = tc->reason;4190info->reason_len = tc->reason_len;4191info->flags = 0;4192if (!tc->remote)4193info->flags |= SSL_CONN_CLOSE_FLAG_LOCAL;4194if (!tc->app)4195info->flags |= SSL_CONN_CLOSE_FLAG_TRANSPORT;4196return 1;4197}41984199/*4200* SSL_key_update4201* --------------4202*/4203int ossl_quic_key_update(SSL *ssl, int update_type)4204{4205QCTX ctx;42064207if (!expect_quic_conn_only(ssl, &ctx))4208return 0;42094210switch (update_type) {4211case SSL_KEY_UPDATE_NOT_REQUESTED:4212/*4213* QUIC signals peer key update implicily by triggering a local4214* spontaneous TXKU. Silently upgrade this to SSL_KEY_UPDATE_REQUESTED.4215*/4216case SSL_KEY_UPDATE_REQUESTED:4217break;42184219default:4220QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL);4221return 0;4222}42234224qctx_lock(&ctx);42254226/* Attempt to perform a TXKU. */4227if (!ossl_quic_channel_trigger_txku(ctx.qc->ch)) {4228QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_TOO_MANY_KEY_UPDATES, NULL);4229qctx_unlock(&ctx);4230return 0;4231}42324233qctx_unlock(&ctx);4234return 1;4235}42364237/*4238* SSL_get_key_update_type4239* -----------------------4240*/4241int ossl_quic_get_key_update_type(const SSL *s)4242{4243/*4244* We always handle key updates immediately so a key update is never4245* pending.4246*/4247return SSL_KEY_UPDATE_NONE;4248}42494250/**4251* @brief Allocates an SSL object for a user from a QUIC channel.4252*4253* This function creates a new QUIC_CONNECTION object based on an incoming4254* connection associated with the provided QUIC_LISTENER. If the connection4255* creation fails, the function returns NULL. Otherwise, it returns a pointer4256* to the SSL object associated with the newly created connection.4257*4258* Note: This function is a registered port callback made from4259* ossl_quic_new_listener and ossl_quic_new_listener_from, and allows for4260* pre-allocation of the user_ssl object when a channel is created, rather than4261* when it is accepted4262*4263* @param ch Pointer to the QUIC_CHANNEL representing the incoming connection.4264* @param arg Pointer to a QUIC_LISTENER used to create the connection.4265*4266* @return Pointer to the SSL object on success, or NULL on failure.4267*/4268static SSL *alloc_port_user_ssl(QUIC_CHANNEL *ch, void *arg)4269{4270QUIC_LISTENER *ql = arg;4271QUIC_CONNECTION *qc = create_qc_from_incoming_conn(ql, ch);42724273return (qc == NULL) ? NULL : &qc->obj.ssl;4274}42754276/*4277* QUIC Front-End I/O API: Listeners4278* =================================4279*/42804281/*4282* SSL_new_listener4283* ----------------4284*/4285SSL *ossl_quic_new_listener(SSL_CTX *ctx, uint64_t flags)4286{4287QUIC_LISTENER *ql = NULL;4288QUIC_ENGINE_ARGS engine_args = {0};4289QUIC_PORT_ARGS port_args = {0};42904291if ((ql = OPENSSL_zalloc(sizeof(*ql))) == NULL) {4292QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);4293goto err;4294}42954296#if defined(OPENSSL_THREADS)4297if ((ql->mutex = ossl_crypto_mutex_new()) == NULL) {4298QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);4299goto err;4300}4301#endif43024303engine_args.libctx = ctx->libctx;4304engine_args.propq = ctx->propq;4305#if defined(OPENSSL_THREADS)4306engine_args.mutex = ql->mutex;4307#endif43084309if (need_notifier_for_domain_flags(ctx->domain_flags))4310engine_args.reactor_flags |= QUIC_REACTOR_FLAG_USE_NOTIFIER;43114312if ((ql->engine = ossl_quic_engine_new(&engine_args)) == NULL) {4313QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);4314goto err;4315}43164317port_args.channel_ctx = ctx;4318port_args.is_multi_conn = 1;4319port_args.get_conn_user_ssl = alloc_port_user_ssl;4320port_args.user_ssl_arg = ql;4321if ((flags & SSL_LISTENER_FLAG_NO_VALIDATE) == 0)4322port_args.do_addr_validation = 1;4323ql->port = ossl_quic_engine_create_port(ql->engine, &port_args);4324if (ql->port == NULL) {4325QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);4326goto err;4327}43284329/* TODO(QUIC FUTURE): Implement SSL_LISTENER_FLAG_NO_ACCEPT */43304331ossl_quic_port_set_allow_incoming(ql->port, 1);43324333/* Initialise the QUIC_LISTENER's object header. */4334if (!ossl_quic_obj_init(&ql->obj, ctx, SSL_TYPE_QUIC_LISTENER, NULL,4335ql->engine, ql->port))4336goto err;43374338return &ql->obj.ssl;43394340err:4341if (ql != NULL)4342ossl_quic_engine_free(ql->engine);43434344#if defined(OPENSSL_THREADS)4345ossl_crypto_mutex_free(&ql->mutex);4346#endif4347OPENSSL_free(ql);4348return NULL;4349}43504351/*4352* SSL_new_listener_from4353* ---------------------4354*/4355SSL *ossl_quic_new_listener_from(SSL *ssl, uint64_t flags)4356{4357QCTX ctx;4358QUIC_LISTENER *ql = NULL;4359QUIC_PORT_ARGS port_args = {0};43604361if (!expect_quic_domain(ssl, &ctx))4362return NULL;43634364if (!SSL_up_ref(&ctx.qd->obj.ssl))4365return NULL;43664367qctx_lock(&ctx);43684369if ((ql = OPENSSL_zalloc(sizeof(*ql))) == NULL) {4370QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);4371goto err;4372}43734374port_args.channel_ctx = ssl->ctx;4375port_args.is_multi_conn = 1;4376port_args.get_conn_user_ssl = alloc_port_user_ssl;4377port_args.user_ssl_arg = ql;4378if ((flags & SSL_LISTENER_FLAG_NO_VALIDATE) == 0)4379port_args.do_addr_validation = 1;4380ql->port = ossl_quic_engine_create_port(ctx.qd->engine, &port_args);4381if (ql->port == NULL) {4382QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);4383goto err;4384}43854386ql->domain = ctx.qd;4387ql->engine = ctx.qd->engine;4388#if defined(OPENSSL_THREADS)4389ql->mutex = ctx.qd->mutex;4390#endif43914392/*4393* TODO(QUIC FUTURE): Implement SSL_LISTENER_FLAG_NO_ACCEPT4394* Given that we have apis to create client SSL objects from4395* server SSL objects (see SSL_new_from_listener), we have aspirations4396* to enable a flag that allows for the creation of the latter, but not4397* be used to do accept any connections. This is a placeholder for the4398* implementation of that flag4399*/44004401ossl_quic_port_set_allow_incoming(ql->port, 1);44024403/* Initialise the QUIC_LISTENER's object header. */4404if (!ossl_quic_obj_init(&ql->obj, ssl->ctx, SSL_TYPE_QUIC_LISTENER,4405&ctx.qd->obj.ssl, NULL, ql->port))4406goto err;44074408qctx_unlock(&ctx);4409return &ql->obj.ssl;44104411err:4412if (ql != NULL)4413ossl_quic_port_free(ql->port);44144415OPENSSL_free(ql);4416qctx_unlock(&ctx);4417SSL_free(&ctx.qd->obj.ssl);44184419return NULL;4420}44214422/*4423* SSL_new_from_listener4424* ---------------------4425* code here is derived from ossl_quic_new(). The `ssl` argument is4426* a listener object which already comes with QUIC port/engine. The newly4427* created QUIC connection object (QCSO) is going to share the port/engine4428* with listener (`ssl`). The `ssl` also becomes a parent of QCSO created4429* by this function. The caller uses QCSO instance to connect to4430* remote QUIC server.4431*4432* The QCSO created here requires us to also create a channel so we4433* can connect to remote server.4434*/4435SSL *ossl_quic_new_from_listener(SSL *ssl, uint64_t flags)4436{4437QCTX ctx;4438QUIC_CONNECTION *qc = NULL;4439QUIC_LISTENER *ql;4440SSL_CONNECTION *sc = NULL;44414442if (flags != 0)4443return NULL;44444445if (!expect_quic_listener(ssl, &ctx))4446return NULL;44474448if (!SSL_up_ref(&ctx.ql->obj.ssl))4449return NULL;44504451qctx_lock(&ctx);44524453ql = ctx.ql;44544455/*4456* listeners (server) contexts don't typically4457* allocate a token cache because they don't need4458* to store them, but here we are using a server side4459* ctx as a client, so we should allocate one now4460*/4461if (ssl->ctx->tokencache == NULL)4462if ((ssl->ctx->tokencache = ossl_quic_new_token_store()) == NULL)4463goto err;44644465if ((qc = OPENSSL_zalloc(sizeof(*qc))) == NULL) {4466QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);4467goto err;4468}44694470/*4471* NOTE: setting a listener here is needed so `qc_cleanup()` does the right4472* thing. Setting listener to ql avoids premature destruction of port in4473* qc_cleanup()4474*/4475qc->listener = ql;4476qc->engine = ql->engine;4477qc->port = ql->port;4478/* create channel */4479#if defined(OPENSSL_THREADS)4480/* this is the engine mutex */4481qc->mutex = ql->mutex;4482#endif4483#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)4484qc->is_thread_assisted4485= ((ql->obj.domain_flags & SSL_DOMAIN_FLAG_THREAD_ASSISTED) != 0);4486#endif44874488/* Create the handshake layer. */4489qc->tls = ossl_ssl_connection_new_int(ql->obj.ssl.ctx, NULL, TLS_method());4490if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL) {4491QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);4492goto err;4493}4494sc->s3.flags |= TLS1_FLAGS_QUIC | TLS1_FLAGS_QUIC_INTERNAL;44954496qc->default_ssl_options = OSSL_QUIC_PERMITTED_OPTIONS;4497qc->last_error = SSL_ERROR_NONE;44984499/*4500* This is QCSO, we don't expect to accept connections4501* on success the channel assumes ownership of tls, we need4502* to grab reference for qc.4503*/4504qc->ch = ossl_quic_port_create_outgoing(qc->port, qc->tls);45054506ossl_quic_channel_set_msg_callback(qc->ch, ql->obj.ssl.ctx->msg_callback, &qc->obj.ssl);4507ossl_quic_channel_set_msg_callback_arg(qc->ch, ql->obj.ssl.ctx->msg_callback_arg);45084509/*4510* We deliberately pass NULL for engine and port, because we don't want to4511* to turn QCSO we create here into an event leader, nor port leader.4512* Both those roles are occupied already by listener (`ssl`) we use4513* to create a new QCSO here.4514*/4515if (!ossl_quic_obj_init(&qc->obj, ql->obj.ssl.ctx,4516SSL_TYPE_QUIC_CONNECTION,4517&ql->obj.ssl, NULL, NULL)) {4518QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);4519goto err;4520}45214522/* Initialise libssl APL-related state. */4523qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;4524qc->default_ssl_mode = qc->obj.ssl.ctx->mode;4525qc->default_ssl_options = qc->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;4526qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;4527qc->last_error = SSL_ERROR_NONE;45284529qc_update_reject_policy(qc);45304531qctx_unlock(&ctx);45324533return &qc->obj.ssl;45344535err:4536if (qc != NULL) {4537qc_cleanup(qc, /* have_lock= */ 0);4538OPENSSL_free(qc);4539}4540qctx_unlock(&ctx);4541SSL_free(&ctx.ql->obj.ssl);45424543return NULL;4544}45454546/*4547* SSL_listen4548* ----------4549*/4550QUIC_NEEDS_LOCK4551static int ql_listen(QUIC_LISTENER *ql)4552{4553if (ql->listening)4554return 1;45554556ossl_quic_port_set_allow_incoming(ql->port, 1);4557ql->listening = 1;4558return 1;4559}45604561QUIC_TAKES_LOCK4562int ossl_quic_listen(SSL *ssl)4563{4564QCTX ctx;4565int ret;45664567if (!expect_quic_listener(ssl, &ctx))4568return 0;45694570qctx_lock_for_io(&ctx);45714572ret = ql_listen(ctx.ql);45734574qctx_unlock(&ctx);4575return ret;4576}45774578/*4579* SSL_accept_connection4580* ---------------------4581*/4582static int quic_accept_connection_wait(void *arg)4583{4584QUIC_PORT *port = arg;45854586if (!ossl_quic_port_is_running(port))4587return -1;45884589if (ossl_quic_port_have_incoming(port))4590return 1;45914592return 0;4593}45944595QUIC_TAKES_LOCK4596SSL *ossl_quic_accept_connection(SSL *ssl, uint64_t flags)4597{4598int ret;4599QCTX ctx;4600SSL *conn_ssl = NULL;4601SSL_CONNECTION *conn = NULL;4602QUIC_CHANNEL *new_ch = NULL;4603QUIC_CONNECTION *qc;4604int no_block = ((flags & SSL_ACCEPT_CONNECTION_NO_BLOCK) != 0);46054606if (!expect_quic_listener(ssl, &ctx))4607return NULL;46084609qctx_lock_for_io(&ctx);46104611if (!ql_listen(ctx.ql))4612goto out;46134614/* Wait for an incoming connection if needed. */4615new_ch = ossl_quic_port_pop_incoming(ctx.ql->port);4616if (new_ch == NULL && ossl_quic_port_is_running(ctx.ql->port)) {4617if (!no_block && qctx_blocking(&ctx)) {4618ret = block_until_pred(&ctx, quic_accept_connection_wait,4619ctx.ql->port, 0);4620if (ret < 1)4621goto out;4622} else {4623qctx_maybe_autotick(&ctx);4624}46254626if (!ossl_quic_port_is_running(ctx.ql->port))4627goto out;46284629new_ch = ossl_quic_port_pop_incoming(ctx.ql->port);4630}46314632if (new_ch == NULL && ossl_quic_port_is_running(ctx.ql->port)) {4633/* No connections already queued. */4634ossl_quic_reactor_tick(ossl_quic_engine_get0_reactor(ctx.ql->engine), 0);46354636new_ch = ossl_quic_port_pop_incoming(ctx.ql->port);4637}46384639/*4640* port_make_channel pre-allocates our user_ssl for us for each newly4641* created channel, so once we pop the new channel from the port above4642* we just need to extract it4643*/4644if (new_ch == NULL4645|| (conn_ssl = ossl_quic_channel_get0_tls(new_ch)) == NULL4646|| (conn = SSL_CONNECTION_FROM_SSL(conn_ssl)) == NULL4647|| (conn_ssl = SSL_CONNECTION_GET_USER_SSL(conn)) == NULL)4648goto out;4649qc = (QUIC_CONNECTION *)conn_ssl;4650qc->listener = ctx.ql;4651qc->pending = 0;4652if (!SSL_up_ref(&ctx.ql->obj.ssl)) {4653SSL_free(conn_ssl);4654SSL_free(ossl_quic_channel_get0_tls(new_ch));4655conn_ssl = NULL;4656}46574658out:4659qctx_unlock(&ctx);4660return conn_ssl;4661}46624663static QUIC_CONNECTION *create_qc_from_incoming_conn(QUIC_LISTENER *ql, QUIC_CHANNEL *ch)4664{4665QUIC_CONNECTION *qc = NULL;46664667if ((qc = OPENSSL_zalloc(sizeof(*qc))) == NULL) {4668QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);4669goto err;4670}46714672if (!ossl_quic_obj_init(&qc->obj, ql->obj.ssl.ctx,4673SSL_TYPE_QUIC_CONNECTION,4674&ql->obj.ssl, NULL, NULL)) {4675QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);4676goto err;4677}46784679ossl_quic_channel_get_peer_addr(ch, &qc->init_peer_addr); /* best effort */4680qc->pending = 1;4681qc->engine = ql->engine;4682qc->port = ql->port;4683qc->ch = ch;4684#if defined(OPENSSL_THREADS)4685qc->mutex = ql->mutex;4686#endif4687qc->tls = ossl_quic_channel_get0_tls(ch);4688qc->started = 1;4689qc->as_server = 1;4690qc->as_server_state = 1;4691qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;4692qc->default_ssl_options = ql->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;4693qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;4694qc->last_error = SSL_ERROR_NONE;4695qc_update_reject_policy(qc);4696return qc;46974698err:4699OPENSSL_free(qc);4700return NULL;4701}47024703DEFINE_LHASH_OF_EX(QUIC_TOKEN);47044705struct ssl_token_store_st {4706LHASH_OF(QUIC_TOKEN) *cache;4707CRYPTO_REF_COUNT references;4708CRYPTO_MUTEX *mutex;4709};47104711static unsigned long quic_token_hash(const QUIC_TOKEN *item)4712{4713return (unsigned long)ossl_fnv1a_hash(item->hashkey, item->hashkey_len);4714}47154716static int quic_token_cmp(const QUIC_TOKEN *a, const QUIC_TOKEN *b)4717{4718if (a->hashkey_len != b->hashkey_len)4719return 1;4720return memcmp(a->hashkey, b->hashkey, a->hashkey_len);4721}47224723SSL_TOKEN_STORE *ossl_quic_new_token_store(void)4724{4725int ok = 0;4726SSL_TOKEN_STORE *newcache = OPENSSL_zalloc(sizeof(SSL_TOKEN_STORE));47274728if (newcache == NULL)4729goto out;47304731newcache->cache = lh_QUIC_TOKEN_new(quic_token_hash, quic_token_cmp);4732if (newcache->cache == NULL)4733goto out;47344735#if defined(OPENSSL_THREADS)4736if ((newcache->mutex = ossl_crypto_mutex_new()) == NULL)4737goto out;4738#endif47394740if (!CRYPTO_NEW_REF(&newcache->references, 1))4741goto out;47424743ok = 1;4744out:4745if (!ok) {4746ossl_quic_free_token_store(newcache);4747newcache = NULL;4748}4749return newcache;4750}47514752static void free_this_token(QUIC_TOKEN *tok)4753{4754ossl_quic_free_peer_token(tok);4755}47564757void ossl_quic_free_token_store(SSL_TOKEN_STORE *hdl)4758{4759int refs;47604761if (hdl == NULL)4762return;47634764if (!CRYPTO_DOWN_REF(&hdl->references, &refs))4765return;47664767if (refs > 0)4768return;47694770/* last reference, we can clean up */4771ossl_crypto_mutex_free(&hdl->mutex);4772lh_QUIC_TOKEN_doall(hdl->cache, free_this_token);4773lh_QUIC_TOKEN_free(hdl->cache);4774CRYPTO_FREE_REF(&hdl->references);4775OPENSSL_free(hdl);4776return;4777}47784779/**4780* @brief build a new QUIC_TOKEN4781*4782* This function creates a new token storage structure for saving in our4783* tokencache4784*4785* In an effort to make allocation and freeing of these tokens a bit faster4786* We do them in a single allocation in this format4787* +---------------+ --\4788* | hashkey * |---| |4789* | hashkey_len | | | QUIC_TOKEN4790* | token * |---|--| |4791* | token_len | | | |4792* +---------------+<--| | --/4793* | hashkey buf | |4794* | | |4795* |---------------|<-----|4796* | token buf |4797* | |4798* +---------------+4799*4800* @param peer - the peer address that sent the token4801* @param token - the buffer holding the token4802* @param token_len - the size of token4803*4804* @returns a QUIC_TOKEN pointer or NULL on error4805*/4806static QUIC_TOKEN *ossl_quic_build_new_token(BIO_ADDR *peer, uint8_t *token,4807size_t token_len)4808{4809QUIC_TOKEN *new_token;4810size_t hashkey_len = 0;4811size_t addr_len = 0;4812int family;4813unsigned short port;4814int *famptr;4815unsigned short *portptr;4816uint8_t *addrptr;48174818if ((token != NULL && token_len == 0) || (token == NULL && token_len != 0))4819return NULL;48204821if (!BIO_ADDR_rawaddress(peer, NULL, &addr_len))4822return NULL;4823family = BIO_ADDR_family(peer);4824port = BIO_ADDR_rawport(peer);48254826hashkey_len += sizeof(int); /* hashkey(family) */4827hashkey_len += sizeof(unsigned short); /* hashkey(port) */4828hashkey_len += addr_len; /* hashkey(address) */48294830new_token = OPENSSL_zalloc(sizeof(QUIC_TOKEN) + hashkey_len + token_len);4831if (new_token == NULL)4832return NULL;48334834if (!CRYPTO_NEW_REF(&new_token->references, 1)) {4835OPENSSL_free(new_token);4836return NULL;4837}48384839new_token->hashkey_len = hashkey_len;4840/* hashkey is allocated inline, immediately after the QUIC_TOKEN struct */4841new_token->hashkey = (uint8_t *)(new_token + 1);4842/* token buffer follows the hashkey in the inline allocation */4843new_token->token = new_token->hashkey + hashkey_len;4844new_token->token_len = token_len;4845famptr = (int *)new_token->hashkey;4846portptr = (unsigned short *)(famptr + 1);4847addrptr = (uint8_t *)(portptr + 1);4848*famptr = family;4849*portptr = port;4850if (!BIO_ADDR_rawaddress(peer, addrptr, NULL)) {4851ossl_quic_free_peer_token(new_token);4852return NULL;4853}4854if (token != NULL)4855memcpy(new_token->token, token, token_len);4856return new_token;4857}48584859int ossl_quic_set_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,4860const uint8_t *token, size_t token_len)4861{4862SSL_TOKEN_STORE *c = ctx->tokencache;4863QUIC_TOKEN *tok, *old = NULL;48644865if (ctx->tokencache == NULL)4866return 0;48674868tok = ossl_quic_build_new_token(peer, (uint8_t *)token, token_len);4869if (tok == NULL)4870return 0;48714872/* we might be sharing this cache, lock it */4873ossl_crypto_mutex_lock(c->mutex);48744875old = lh_QUIC_TOKEN_retrieve(c->cache, tok);4876if (old != NULL) {4877lh_QUIC_TOKEN_delete(c->cache, old);4878ossl_quic_free_peer_token(old);4879}4880lh_QUIC_TOKEN_insert(c->cache, tok);48814882ossl_crypto_mutex_unlock(c->mutex);4883return 1;4884}48854886int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,4887QUIC_TOKEN **token)4888{4889SSL_TOKEN_STORE *c = ctx->tokencache;4890QUIC_TOKEN *key = NULL;4891QUIC_TOKEN *tok = NULL;4892int ret;4893int rc = 0;48944895if (c == NULL)4896return 0;48974898key = ossl_quic_build_new_token(peer, NULL, 0);4899if (key == NULL)4900return 0;49014902ossl_crypto_mutex_lock(c->mutex);4903tok = lh_QUIC_TOKEN_retrieve(c->cache, key);4904if (tok != NULL) {4905*token = tok;4906CRYPTO_UP_REF(&tok->references, &ret);4907rc = 1;4908}49094910ossl_crypto_mutex_unlock(c->mutex);4911ossl_quic_free_peer_token(key);4912return rc;4913}49144915void ossl_quic_free_peer_token(QUIC_TOKEN *token)4916{4917int refs = 0;49184919if (!CRYPTO_DOWN_REF(&token->references, &refs))4920return;49214922if (refs > 0)4923return;49244925CRYPTO_FREE_REF(&token->references);4926OPENSSL_free(token);4927}49284929/*4930* SSL_get_accept_connection_queue_len4931* -----------------------------------4932*/4933QUIC_TAKES_LOCK4934size_t ossl_quic_get_accept_connection_queue_len(SSL *ssl)4935{4936QCTX ctx;4937int ret;49384939if (!expect_quic_listener(ssl, &ctx))4940return 0;49414942qctx_lock(&ctx);49434944ret = ossl_quic_port_get_num_incoming_channels(ctx.ql->port);49454946qctx_unlock(&ctx);4947return ret;4948}49494950/*4951* QUIC Front-End I/O API: Domains4952* ===============================4953*/49544955/*4956* SSL_new_domain4957* --------------4958*/4959SSL *ossl_quic_new_domain(SSL_CTX *ctx, uint64_t flags)4960{4961QUIC_DOMAIN *qd = NULL;4962QUIC_ENGINE_ARGS engine_args = {0};4963uint64_t domain_flags;49644965domain_flags = ctx->domain_flags;4966if ((flags & (SSL_DOMAIN_FLAG_SINGLE_THREAD4967| SSL_DOMAIN_FLAG_MULTI_THREAD4968| SSL_DOMAIN_FLAG_THREAD_ASSISTED)) != 0)4969domain_flags = flags;4970else4971domain_flags = ctx->domain_flags | flags;49724973if (!ossl_adjust_domain_flags(domain_flags, &domain_flags))4974return NULL;49754976if ((qd = OPENSSL_zalloc(sizeof(*qd))) == NULL) {4977QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);4978return NULL;4979}49804981#if defined(OPENSSL_THREADS)4982if ((qd->mutex = ossl_crypto_mutex_new()) == NULL) {4983QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);4984goto err;4985}4986#endif49874988engine_args.libctx = ctx->libctx;4989engine_args.propq = ctx->propq;4990#if defined(OPENSSL_THREADS)4991engine_args.mutex = qd->mutex;4992#endif49934994if (need_notifier_for_domain_flags(domain_flags))4995engine_args.reactor_flags |= QUIC_REACTOR_FLAG_USE_NOTIFIER;49964997if ((qd->engine = ossl_quic_engine_new(&engine_args)) == NULL) {4998QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);4999goto err;5000}50015002/* Initialise the QUIC_DOMAIN's object header. */5003if (!ossl_quic_obj_init(&qd->obj, ctx, SSL_TYPE_QUIC_DOMAIN, NULL,5004qd->engine, NULL))5005goto err;50065007ossl_quic_obj_set_domain_flags(&qd->obj, domain_flags);5008return &qd->obj.ssl;50095010err:5011ossl_quic_engine_free(qd->engine);5012#if defined(OPENSSL_THREADS)5013ossl_crypto_mutex_free(&qd->mutex);5014#endif5015OPENSSL_free(qd);5016return NULL;5017}50185019/*5020* QUIC Front-End I/O API: SSL_CTX Management5021* ==========================================5022*/50235024long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)5025{5026switch (cmd) {5027default:5028return ssl3_ctx_ctrl(ctx, cmd, larg, parg);5029}5030}50315032long ossl_quic_callback_ctrl(SSL *s, int cmd, void (*fp) (void))5033{5034QCTX ctx;50355036if (!expect_quic_conn_only(s, &ctx))5037return 0;50385039switch (cmd) {5040case SSL_CTRL_SET_MSG_CALLBACK:5041ossl_quic_channel_set_msg_callback(ctx.qc->ch, (ossl_msg_cb)fp,5042&ctx.qc->obj.ssl);5043/* This callback also needs to be set on the internal SSL object */5044return ssl3_callback_ctrl(ctx.qc->tls, cmd, fp);;50455046default:5047/* Probably a TLS related ctrl. Defer to our internal SSL object */5048return ssl3_callback_ctrl(ctx.qc->tls, cmd, fp);5049}5050}50515052long ossl_quic_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))5053{5054return ssl3_ctx_callback_ctrl(ctx, cmd, fp);5055}50565057int ossl_quic_renegotiate_check(SSL *ssl, int initok)5058{5059/* We never do renegotiation. */5060return 0;5061}50625063const SSL_CIPHER *ossl_quic_get_cipher_by_char(const unsigned char *p)5064{5065const SSL_CIPHER *ciph = ssl3_get_cipher_by_char(p);50665067if ((ciph->algorithm2 & SSL_QUIC) == 0)5068return NULL;50695070return ciph;5071}50725073/*5074* These functions define the TLSv1.2 (and below) ciphers that are supported by5075* the SSL_METHOD. Since QUIC only supports TLSv1.3 we don't support any.5076*/50775078int ossl_quic_num_ciphers(void)5079{5080return 0;5081}50825083const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u)5084{5085return NULL;5086}50875088/*5089* SSL_get_shutdown()5090* ------------------5091*/5092int ossl_quic_get_shutdown(const SSL *s)5093{5094QCTX ctx;5095int shut = 0;50965097if (!expect_quic_conn_only(s, &ctx))5098return 0;50995100if (ossl_quic_channel_is_term_any(ctx.qc->ch)) {5101shut |= SSL_SENT_SHUTDOWN;5102if (!ossl_quic_channel_is_closing(ctx.qc->ch))5103shut |= SSL_RECEIVED_SHUTDOWN;5104}51055106return shut;5107}51085109/*5110* QUIC Polling Support APIs5111* =========================5112*/51135114/* Do we have the R (read) condition? */5115QUIC_NEEDS_LOCK5116static int test_poll_event_r(QUIC_XSO *xso)5117{5118int fin = 0;5119size_t avail = 0;51205121/*5122* If a stream has had the fin bit set on the last packet5123* received, then we need to return a 1 here to raise5124* SSL_POLL_EVENT_R, so that the stream can have its completion5125* detected and closed gracefully by an application.5126* However, if the client reads the data via SSL_read[_ex], that api5127* provides no stream status, and as a result the stream state moves to5128* QUIC_RSTREAM_STATE_DATA_READ, and the receive buffer is freed, which5129* stored the fin state, so its not directly know-able here. Instead5130* check for the stream state being QUIC_RSTREAM_STATE_DATA_READ, which5131* is only set if the last stream frame received had the fin bit set, and5132* the client read the data. This catches our poll/read/poll case5133*/5134if (xso->stream->recv_state == QUIC_RSTREAM_STATE_DATA_READ)5135return 1;51365137return ossl_quic_stream_has_recv_buffer(xso->stream)5138&& ossl_quic_rstream_available(xso->stream->rstream, &avail, &fin)5139&& (avail > 0 || (fin && !xso->retired_fin));5140}51415142/* Do we have the ER (exception: read) condition? */5143QUIC_NEEDS_LOCK5144static int test_poll_event_er(QUIC_XSO *xso)5145{5146return ossl_quic_stream_has_recv(xso->stream)5147&& ossl_quic_stream_recv_is_reset(xso->stream)5148&& !xso->retired_fin;5149}51505151/* Do we have the W (write) condition? */5152QUIC_NEEDS_LOCK5153static int test_poll_event_w(QUIC_XSO *xso)5154{5155return !xso->conn->shutting_down5156&& ossl_quic_stream_has_send_buffer(xso->stream)5157&& ossl_quic_sstream_get_buffer_avail(xso->stream->sstream)5158&& !ossl_quic_sstream_get_final_size(xso->stream->sstream, NULL)5159&& ossl_quic_txfc_get_cwm(&xso->stream->txfc)5160> ossl_quic_sstream_get_cur_size(xso->stream->sstream)5161&& quic_mutation_allowed(xso->conn, /*req_active=*/1);5162}51635164/* Do we have the EW (exception: write) condition? */5165QUIC_NEEDS_LOCK5166static int test_poll_event_ew(QUIC_XSO *xso)5167{5168return ossl_quic_stream_has_send(xso->stream)5169&& xso->stream->peer_stop_sending5170&& !xso->requested_reset5171&& !xso->conn->shutting_down;5172}51735174/* Do we have the EC (exception: connection) condition? */5175QUIC_NEEDS_LOCK5176static int test_poll_event_ec(QUIC_CONNECTION *qc)5177{5178return ossl_quic_channel_is_term_any(qc->ch);5179}51805181/* Do we have the ECD (exception: connection drained) condition? */5182QUIC_NEEDS_LOCK5183static int test_poll_event_ecd(QUIC_CONNECTION *qc)5184{5185return ossl_quic_channel_is_terminated(qc->ch);5186}51875188/* Do we have the IS (incoming: stream) condition? */5189QUIC_NEEDS_LOCK5190static int test_poll_event_is(QUIC_CONNECTION *qc, int is_uni)5191{5192return ossl_quic_stream_map_get_accept_queue_len(ossl_quic_channel_get_qsm(qc->ch),5193is_uni);5194}51955196/* Do we have the OS (outgoing: stream) condition? */5197QUIC_NEEDS_LOCK5198static int test_poll_event_os(QUIC_CONNECTION *qc, int is_uni)5199{5200/* Is it currently possible for us to make an outgoing stream? */5201return quic_mutation_allowed(qc, /*req_active=*/1)5202&& ossl_quic_channel_get_local_stream_count_avail(qc->ch, is_uni) > 0;5203}52045205/* Do we have the EL (exception: listener) condition? */5206QUIC_NEEDS_LOCK5207static int test_poll_event_el(QUIC_LISTENER *ql)5208{5209return !ossl_quic_port_is_running(ql->port);5210}52115212/* Do we have the IC (incoming: connection) condition? */5213QUIC_NEEDS_LOCK5214static int test_poll_event_ic(QUIC_LISTENER *ql)5215{5216return ossl_quic_port_get_num_incoming_channels(ql->port) > 0;5217}52185219QUIC_TAKES_LOCK5220int ossl_quic_conn_poll_events(SSL *ssl, uint64_t events, int do_tick,5221uint64_t *p_revents)5222{5223QCTX ctx;5224uint64_t revents = 0;52255226if (!expect_quic_csl(ssl, &ctx))5227return 0;52285229qctx_lock(&ctx);52305231if (ctx.qc != NULL && !ctx.qc->started) {5232/* We can only try to write on non-started connection. */5233if ((events & SSL_POLL_EVENT_W) != 0)5234revents |= SSL_POLL_EVENT_W;5235goto end;5236}52375238if (do_tick)5239ossl_quic_reactor_tick(ossl_quic_obj_get0_reactor(ctx.obj), 0);52405241if (ctx.xso != NULL) {5242/* SSL object has a stream component. */52435244if ((events & SSL_POLL_EVENT_R) != 05245&& test_poll_event_r(ctx.xso))5246revents |= SSL_POLL_EVENT_R;52475248if ((events & SSL_POLL_EVENT_ER) != 05249&& test_poll_event_er(ctx.xso))5250revents |= SSL_POLL_EVENT_ER;52515252if ((events & SSL_POLL_EVENT_W) != 05253&& test_poll_event_w(ctx.xso))5254revents |= SSL_POLL_EVENT_W;52555256if ((events & SSL_POLL_EVENT_EW) != 05257&& test_poll_event_ew(ctx.xso))5258revents |= SSL_POLL_EVENT_EW;5259}52605261if (ctx.qc != NULL && !ctx.is_stream) {5262if ((events & SSL_POLL_EVENT_EC) != 05263&& test_poll_event_ec(ctx.qc))5264revents |= SSL_POLL_EVENT_EC;52655266if ((events & SSL_POLL_EVENT_ECD) != 05267&& test_poll_event_ecd(ctx.qc))5268revents |= SSL_POLL_EVENT_ECD;52695270if ((events & SSL_POLL_EVENT_ISB) != 05271&& test_poll_event_is(ctx.qc, /*uni=*/0))5272revents |= SSL_POLL_EVENT_ISB;52735274if ((events & SSL_POLL_EVENT_ISU) != 05275&& test_poll_event_is(ctx.qc, /*uni=*/1))5276revents |= SSL_POLL_EVENT_ISU;52775278if ((events & SSL_POLL_EVENT_OSB) != 05279&& test_poll_event_os(ctx.qc, /*uni=*/0))5280revents |= SSL_POLL_EVENT_OSB;52815282if ((events & SSL_POLL_EVENT_OSU) != 05283&& test_poll_event_os(ctx.qc, /*uni=*/1))5284revents |= SSL_POLL_EVENT_OSU;5285}52865287if (ctx.is_listener) {5288if ((events & SSL_POLL_EVENT_EL) != 05289&& test_poll_event_el(ctx.ql))5290revents |= SSL_POLL_EVENT_EL;52915292if ((events & SSL_POLL_EVENT_IC) != 05293&& test_poll_event_ic(ctx.ql))5294revents |= SSL_POLL_EVENT_IC;5295}52965297end:5298qctx_unlock(&ctx);5299*p_revents = revents;5300return 1;5301}53025303QUIC_TAKES_LOCK5304int ossl_quic_get_notifier_fd(SSL *ssl)5305{5306QCTX ctx;5307QUIC_REACTOR *rtor;5308RIO_NOTIFIER *nfy;5309int nfd = -1;53105311if (!expect_quic_any(ssl, &ctx))5312return -1;53135314qctx_lock(&ctx);5315rtor = ossl_quic_obj_get0_reactor(ctx.obj);5316nfy = ossl_quic_reactor_get0_notifier(rtor);5317if (nfy == NULL)5318goto end;5319nfd = ossl_rio_notifier_as_fd(nfy);53205321end:5322qctx_unlock(&ctx);5323return nfd;5324}53255326QUIC_TAKES_LOCK5327void ossl_quic_enter_blocking_section(SSL *ssl, QUIC_REACTOR_WAIT_CTX *wctx)5328{5329QCTX ctx;5330QUIC_REACTOR *rtor;53315332if (!expect_quic_any(ssl, &ctx))5333return;53345335qctx_lock(&ctx);5336rtor = ossl_quic_obj_get0_reactor(ctx.obj);5337ossl_quic_reactor_wait_ctx_enter(wctx, rtor);5338qctx_unlock(&ctx);5339}53405341QUIC_TAKES_LOCK5342void ossl_quic_leave_blocking_section(SSL *ssl, QUIC_REACTOR_WAIT_CTX *wctx)5343{5344QCTX ctx;5345QUIC_REACTOR *rtor;53465347if (!expect_quic_any(ssl, &ctx))5348return;53495350qctx_lock(&ctx);5351rtor = ossl_quic_obj_get0_reactor(ctx.obj);5352ossl_quic_reactor_wait_ctx_leave(wctx, rtor);5353qctx_unlock(&ctx);5354}53555356/*5357* Internal Testing APIs5358* =====================5359*/53605361QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s)5362{5363QCTX ctx;53645365if (!expect_quic_conn_only(s, &ctx))5366return NULL;53675368return ctx.qc->ch;5369}53705371int ossl_quic_set_diag_title(SSL_CTX *ctx, const char *title)5372{5373#ifndef OPENSSL_NO_QLOG5374OPENSSL_free(ctx->qlog_title);5375ctx->qlog_title = NULL;53765377if (title == NULL)5378return 1;53795380if ((ctx->qlog_title = OPENSSL_strdup(title)) == NULL)5381return 0;5382#endif53835384return 1;5385}538653875388