Path: blob/main/crypto/openssl/ssl/quic/quic_obj.c
48266 views
/*1* Copyright 2024-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 "quic_obj_local.h"10#include "quic_local.h"11#include "internal/ssl_unwrap.h"1213static int obj_update_cache(QUIC_OBJ *obj);1415int ossl_quic_obj_init(QUIC_OBJ *obj,16SSL_CTX *ctx,17int type,18SSL *parent_obj,19QUIC_ENGINE *engine,20QUIC_PORT *port)21{22int is_event_leader = (engine != NULL);23int is_port_leader = (port != NULL);2425if (!ossl_assert(obj != NULL && !obj->init_done && SSL_TYPE_IS_QUIC(type)26&& (parent_obj == NULL || IS_QUIC(parent_obj))))27return 0;2829/* Event leader is always the root object. */30if (!ossl_assert(!is_event_leader || parent_obj == NULL))31return 0;3233if (!ossl_ssl_init(&obj->ssl, ctx, ctx->method, type))34goto err;3536obj->domain_flags = ctx->domain_flags;37obj->parent_obj = (QUIC_OBJ *)parent_obj;38obj->is_event_leader = is_event_leader;39obj->is_port_leader = is_port_leader;40obj->engine = engine;41obj->port = port;42obj->req_blocking_mode = QUIC_BLOCKING_MODE_INHERIT;43if (!obj_update_cache(obj))44goto err;4546obj->init_done = 1;47return 1;4849err:50obj->is_event_leader = 0;51obj->is_port_leader = 0;52return 0;53}5455static int obj_update_cache(QUIC_OBJ *obj)56{57QUIC_OBJ *p;5859for (p = obj; p != NULL && !p->is_event_leader;60p = p->parent_obj)61if (!ossl_assert(p == obj || p->init_done))62return 0;6364if (!ossl_assert(p != NULL))65return 0;6667/*68* Offset of ->ssl is guaranteed to be 0 but the NULL check makes ubsan69* happy.70*/71obj->cached_event_leader = p;72obj->engine = p->engine;7374for (p = obj; p != NULL && !p->is_port_leader;75p = p->parent_obj);7677obj->cached_port_leader = p;78obj->port = (p != NULL) ? p->port : NULL;79return 1;80}8182SSL_CONNECTION *ossl_quic_obj_get0_handshake_layer(QUIC_OBJ *obj)83{84assert(obj != NULL && obj->init_done);8586if (obj->ssl.type != SSL_TYPE_QUIC_CONNECTION)87return NULL;8889return SSL_CONNECTION_FROM_SSL_ONLY(((QUIC_CONNECTION *)obj)->tls);90}9192/* (Returns a cached result.) */93int ossl_quic_obj_can_support_blocking(const QUIC_OBJ *obj)94{95QUIC_REACTOR *rtor;9697assert(obj != NULL);98rtor = ossl_quic_obj_get0_reactor(obj);99100if ((obj->domain_flags101& (SSL_DOMAIN_FLAG_LEGACY_BLOCKING | SSL_DOMAIN_FLAG_BLOCKING)) == 0)102return 0;103104return ossl_quic_reactor_can_poll_r(rtor)105|| ossl_quic_reactor_can_poll_w(rtor);106}107108int ossl_quic_obj_desires_blocking(const QUIC_OBJ *obj)109{110unsigned int req_blocking_mode;111112assert(obj != NULL);113for (; (req_blocking_mode = obj->req_blocking_mode) == QUIC_BLOCKING_MODE_INHERIT114&& obj->parent_obj != NULL; obj = obj->parent_obj);115116return req_blocking_mode != QUIC_BLOCKING_MODE_NONBLOCKING;117}118119int ossl_quic_obj_blocking(const QUIC_OBJ *obj)120{121assert(obj != NULL);122123if (!ossl_quic_obj_desires_blocking(obj))124return 0;125126ossl_quic_engine_update_poll_descriptors(ossl_quic_obj_get0_engine(obj),127/*force=*/0);128return ossl_quic_obj_can_support_blocking(obj);129}130131void ossl_quic_obj_set_blocking_mode(QUIC_OBJ *obj, unsigned int mode)132{133assert(obj != NULL);134135obj->req_blocking_mode = mode;136}137138139