diff options
author | Hugo Landau <hlandau@openssl.org> | 2023-02-21 11:18:58 +0100 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-03-30 12:14:07 +0200 |
commit | fb2245c44b58b41a378eb47422221edd49ba9091 (patch) | |
tree | 7e7b828e8f62868f2cb93834b99f0618432a73dd | |
parent | QUIC Reactor: Allow a mutex to be released during waits (diff) | |
download | openssl-fb2245c44b58b41a378eb47422221edd49ba9091.tar.xz openssl-fb2245c44b58b41a378eb47422221edd49ba9091.zip |
QUIC Channel: Add a mutex
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20348)
-rw-r--r-- | include/internal/quic_channel.h | 36 | ||||
-rw-r--r-- | include/internal/quic_ssl.h | 1 | ||||
-rw-r--r-- | ssl/quic/quic_channel.c | 20 | ||||
-rw-r--r-- | ssl/quic/quic_channel_local.h | 6 |
4 files changed, 63 insertions, 0 deletions
diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h index f08252d1f9..13cd83bff1 100644 --- a/include/internal/quic_channel.h +++ b/include/internal/quic_channel.h @@ -47,6 +47,16 @@ * demuxers). Since we only use server-side functionality for dummy test servers * for now, which only need to handle one connection at a time, this is not * currently modelled. + * + * Synchronisation + * --------------- + * + * To support thread assisted mode, QUIC_CHANNEL can be used by multiple + * threads. **It is the caller's responsibility to ensure that the QUIC_CHANNEL + * is only accessed (whether via its methods or via direct access to its state) + * while the QUIC_CHANNEL mutex is held**, except for methods explicitly marked + * as not requiring prior locking. See ossl_quic_channel_get_mutex() for more + * information. This is an unchecked precondition. */ # define QUIC_CHANNEL_STATE_IDLE 0 @@ -198,6 +208,32 @@ QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch); SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch); +/* + * Retreves the channel mutex, which can be used to synchronise access to + * channel functions and internal data. In order to allow locks to be acquired + * and released with the correct granularity, it is the caller's responsibility + * to ensure this lock is held for write while calling any QUIC_CHANNEL method. + * + * This method is thread safe and does not require prior locking. It can also be + * called while the lock is already held. + */ +CRYPTO_RWLOCK *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch); + +/* + * Locks the channel mutex. It is roughly analagous to locking the mutex + * returned by ossl_quic_channel_get_mutex() but might be able to avoid locking + * where thread assisted mode is not being used, thus it is recommended that + * these methods are used uniformly rather than locking the channel mutex + * directly. + * + * This method is (obviously) thread safe and does not require prior locking. It + * must not be called while the lock is already held. + */ +int ossl_quic_channel_lock(QUIC_CHANNEL *ch); + +/* Unlocks the channel mutex. */ +void ossl_quic_channel_unlock(QUIC_CHANNEL *ch); + # endif #endif diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h index 7b89534c22..3cf32e0944 100644 --- a/include/internal/quic_ssl.h +++ b/include/internal/quic_ssl.h @@ -46,6 +46,7 @@ void ossl_quic_set_accept_state(QUIC_CONNECTION *qc); __owur int ossl_quic_has_pending(const QUIC_CONNECTION *qc); __owur int ossl_quic_tick(QUIC_CONNECTION *qc); __owur int ossl_quic_get_tick_timeout(QUIC_CONNECTION *qc, struct timeval *tv); +OSSL_TIME ossl_quic_get_tick_deadline(QUIC_CONNECTION *qc); __owur int ossl_quic_get_rpoll_descriptor(QUIC_CONNECTION *qc, BIO_POLL_DESCRIPTOR *d); __owur int ossl_quic_get_wpoll_descriptor(QUIC_CONNECTION *qc, BIO_POLL_DESCRIPTOR *d); __owur int ossl_quic_get_net_read_desired(QUIC_CONNECTION *qc); diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 86eed313ab..efe8ca6def 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -115,6 +115,10 @@ static int ch_init(QUIC_CHANNEL *ch) qtx_args.mdpl = QUIC_MIN_INITIAL_DGRAM_LEN; ch->rx_max_udp_payload_size = qtx_args.mdpl; + ch->mutex = CRYPTO_THREAD_lock_new(); + if (ch->mutex == NULL) + goto err; + ch->qtx = ossl_qtx_new(&qtx_args); if (ch->qtx == NULL) goto err; @@ -318,6 +322,7 @@ static void ch_cleanup(QUIC_CHANNEL *ch) ossl_qrx_free(ch->qrx); ossl_quic_demux_free(ch->demux); OPENSSL_free(ch->local_transport_params); + CRYPTO_THREAD_lock_free(ch->mutex); } QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args) @@ -443,6 +448,21 @@ QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch) return ch->demux; } +CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch) +{ + return ch->mutex; +} + +int ossl_quic_channel_lock(QUIC_CHANNEL *ch) +{ + return ossl_crypto_mutex_lock(ch->mutex); +} + +void ossl_quic_channel_unlock(QUIC_CHANNEL *ch) +{ + ossl_crypto_mutex_unlock(ch->mutex); +} + /* * QUIC Channel: Callbacks from Miscellaneous Subsidiary Components * ================================================================ diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h index fa2618bce5..2f63119cef 100644 --- a/ssl/quic/quic_channel_local.h +++ b/ssl/quic/quic_channel_local.h @@ -26,6 +26,12 @@ struct quic_channel_st { const char *propq; /* + * Master synchronisation mutex used for thread assisted mode + * synchronisation. + */ + CRYPTO_RWLOCK *mutex; + + /* * The associated TLS 1.3 connection data. Used to provide the handshake * layer; its 'network' side is plugged into the crypto stream for each EL * (other than the 0-RTT EL). |