From: Hugo Landau Date: Tue, 21 Feb 2023 10:18:59 +0000 (+0000) Subject: Add channel-only tick mode and use it for thread assisted mode X-Git-Tag: openssl-3.2.0-alpha1~1064 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ccd31037713ad1cdfd88c85a169bd18b08579813;p=thirdparty%2Fopenssl.git Add channel-only tick mode and use it for thread assisted mode Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/20348) --- diff --git a/include/internal/quic_reactor.h b/include/internal/quic_reactor.h index e978dac8ff6..6a8ebbe29db 100644 --- a/include/internal/quic_reactor.h +++ b/include/internal/quic_reactor.h @@ -85,7 +85,7 @@ typedef struct quic_reactor_st { BIO_POLL_DESCRIPTOR poll_r, poll_w; OSSL_TIME tick_deadline; /* ossl_time_infinite() if none currently applicable */ - void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg); + void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg, uint32_t flags); void *tick_cb_arg; /* @@ -97,7 +97,8 @@ typedef struct quic_reactor_st { } QUIC_REACTOR; void ossl_quic_reactor_init(QUIC_REACTOR *rtor, - void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg), + void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg, + uint32_t flags), void *tick_cb_arg, OSSL_TIME initial_tick_deadline); @@ -121,8 +122,13 @@ OSSL_TIME ossl_quic_reactor_get_tick_deadline(QUIC_REACTOR *rtor); * Do whatever work can be done, and as much work as can be done. This involves * e.g. seeing if we can read anything from the network (if we want to), seeing * if we can write anything to the network (if we want to), etc. + * + * If the CHANNEL_ONLY flag is set, this indicates that we should only + * touch state which is synchronised by the channel mutex. */ -int ossl_quic_reactor_tick(QUIC_REACTOR *rtor); +#define QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY (1U << 0) + +int ossl_quic_reactor_tick(QUIC_REACTOR *rtor, uint32_t flags); /* * Blocking I/O Adaptation Layer diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 07c680511c8..16b158d8a93 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -31,7 +31,7 @@ static void ch_rx_pre(QUIC_CHANNEL *ch); static int ch_rx(QUIC_CHANNEL *ch); static int ch_tx(QUIC_CHANNEL *ch); -static void ch_tick(QUIC_TICK_RESULT *res, void *arg); +static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags); static void ch_rx_handle_packet(QUIC_CHANNEL *ch); static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch); static int ch_retry(QUIC_CHANNEL *ch, @@ -1207,10 +1207,11 @@ err: * at least everything network I/O related. Best effort - not allowed to fail * "loudly". */ -static void ch_tick(QUIC_TICK_RESULT *res, void *arg) +static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) { OSSL_TIME now, deadline; QUIC_CHANNEL *ch = arg; + int channel_only = ((flags & QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY) != 0); /* * When we tick the QUIC connection, we do everything we need to do @@ -1259,7 +1260,8 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg) * new outgoing data. */ ch->have_new_rx_secret = 0; - ossl_quic_tls_tick(ch->qtls); + if (!channel_only) + ossl_quic_tls_tick(ch->qtls); /* * If the handshake layer gave us a new secret, we need to do RX again @@ -1753,7 +1755,7 @@ int ossl_quic_channel_start(QUIC_CHANNEL *ch) if (!ossl_quic_tls_tick(ch->qtls)) return 0; - ossl_quic_reactor_tick(&ch->rtor); /* best effort */ + ossl_quic_reactor_tick(&ch->rtor, 0); /* best effort */ return 1; } diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 73071d4a730..4286c526b76 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -450,7 +450,7 @@ int ossl_quic_tick(QUIC_CONNECTION *qc) return 1; } - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch)); + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); quic_unlock(qc); return 1; } @@ -587,7 +587,7 @@ int ossl_quic_conn_shutdown(QUIC_CONNECTION *qc, uint64_t flags, if (blocking_mode(qc) && (flags & SSL_SHUTDOWN_FLAG_RAPID) == 0) block_until_pred(qc, quic_shutdown_wait, qc, 0); else - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch)); + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); ret = ossl_quic_channel_is_terminated(qc->ch); quic_unlock(qc); @@ -783,7 +783,7 @@ static int quic_do_handshake(QUIC_CONNECTION *qc) return 1; } else { /* Try to advance the reactor. */ - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch)); + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); if (ossl_quic_channel_is_handshake_complete(qc->ch)) /* The handshake is now done. */ @@ -895,7 +895,7 @@ static void quic_post_write(QUIC_CONNECTION *qc, int did_append, int do_tick) * plus we should eventually consider Nagle's algorithm. */ if (do_tick) - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch)); + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); } struct quic_write_again_args { @@ -1282,7 +1282,7 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek * Even though we succeeded, tick the reactor here to ensure we are * handling other aspects of the QUIC connection. */ - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch)); + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); ret = 1; } else if (blocking_mode(qc)) { /* diff --git a/ssl/quic/quic_reactor.c b/ssl/quic/quic_reactor.c index 864ba3281c1..cae8dffe0eb 100644 --- a/ssl/quic/quic_reactor.c +++ b/ssl/quic/quic_reactor.c @@ -14,7 +14,8 @@ * ========================== */ void ossl_quic_reactor_init(QUIC_REACTOR *rtor, - void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg), + void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg, + uint32_t flags), void *tick_cb_arg, OSSL_TIME initial_tick_deadline) { @@ -63,7 +64,7 @@ OSSL_TIME ossl_quic_reactor_get_tick_deadline(QUIC_REACTOR *rtor) return rtor->tick_deadline; } -int ossl_quic_reactor_tick(QUIC_REACTOR *rtor) +int ossl_quic_reactor_tick(QUIC_REACTOR *rtor, uint32_t flags) { QUIC_TICK_RESULT res = {0}; @@ -74,7 +75,7 @@ int ossl_quic_reactor_tick(QUIC_REACTOR *rtor) * best effort. If something fatal happens with a connection we can report * it on the next actual application I/O call. */ - rtor->tick_cb(&res, rtor->tick_cb_arg); + rtor->tick_cb(&res, rtor->tick_cb_arg, flags); rtor->net_read_desired = res.net_read_desired; rtor->net_write_desired = res.net_write_desired; @@ -315,7 +316,7 @@ int ossl_quic_reactor_block_until_pred(QUIC_REACTOR *rtor, flags &= ~SKIP_FIRST_TICK; else /* best effort */ - ossl_quic_reactor_tick(rtor); + ossl_quic_reactor_tick(rtor, 0); if ((res = pred(pred_arg)) != 0) return res; diff --git a/ssl/quic/quic_thread_assist.c b/ssl/quic/quic_thread_assist.c index 6b2c2199826..4f760ea99cf 100644 --- a/ssl/quic/quic_thread_assist.c +++ b/ssl/quic/quic_thread_assist.c @@ -49,7 +49,7 @@ static unsigned int assist_thread_main(void *arg) if (qta->teardown) break; - ossl_quic_reactor_tick(rtor); + ossl_quic_reactor_tick(rtor, QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY); } CRYPTO_THREAD_unlock(m); diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c index 158abf705bc..4278f13f096 100644 --- a/ssl/quic/quic_tserver.c +++ b/ssl/quic/quic_tserver.c @@ -153,7 +153,7 @@ int ossl_quic_tserver_set_handshake_mutator(QUIC_TSERVER *srv, int ossl_quic_tserver_tick(QUIC_TSERVER *srv) { - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch)); + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch), 0); if (ossl_quic_channel_is_active(srv->ch)) srv->connected = 1;