ms = ossl_time2ms(delta);
-
/*
* Amount of time we want to wait is too long for the 32-bit argument to
* the Win32 API, so just wait as long as possible.
*cv_p = NULL;
}
-#endif
+# endif
void ossl_crypto_mem_barrier(void)
{
QUIC Thread Assisted Mode Synchronisation Requirements
======================================================
-In thread assisted mode, we spin up a background thread to ensure that periodic
+In thread assisted mode, we create a background thread to ensure that periodic
QUIC processing is handled in a timely fashion regardless of whether an
application is frequently calling (or blocked in) SSL API I/O functions.
*
* Precondition: must not hold channel mutex (unchecked)
* Postcondition: channel mutex is not held (by calling thread)
- *
*/
# define QUIC_TAKES_LOCK
#define INIT_CRYPTO_BUF_LEN 8192
#define INIT_APP_BUF_LEN 8192
+/*
+ * Interval before we force a PING to ensure NATs don't timeout. This is based
+ * on the lowest commonly seen value of 30 seconds as cited in RFC 9000 s.
+ * 10.1.2.
+ */
+#define MAX_NAT_INTERVAL (ossl_ms2time(25000))
+
static void ch_rx_pre(QUIC_CHANNEL *ch);
static int ch_rx(QUIC_CHANNEL *ch);
static int ch_tx(QUIC_CHANNEL *ch);
{
OSSL_TIME now, deadline;
QUIC_CHANNEL *ch = arg;
- int channel_only = ((flags & QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY) != 0);
+ int channel_only = (flags & QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY) != 0;
/*
* When we tick the QUIC connection, we do everything we need to do
{
if (ch->max_idle_timeout > 0) {
/*
- * Maximum amount of time without traffic before we send a PING to
- * keep the connection open. Usually we use max_idle_timeout/2, but
- * ensure the period never exceeds 25 seconds to ensure NAT devices
- * don't have their state time out (RFC 9000 s. 10.1.2).
+ * Maximum amount of time without traffic before we send a PING to keep
+ * the connection open. Usually we use max_idle_timeout/2, but ensure
+ * the period never exceeds the assumed NAT interval to ensure NAT
+ * devices don't have their state time out (RFC 9000 s. 10.1.2).
*/
OSSL_TIME max_span
= ossl_time_divide(ossl_ms2time(ch->max_idle_timeout), 2);
- max_span = ossl_time_min(max_span, ossl_ms2time(25000));
+ max_span = ossl_time_min(max_span, MAX_NAT_INTERVAL);
ch->ping_deadline = ossl_time_add(get_time(ch), max_span);
} else {
/* Note: SSL_free calls OPENSSL_free(qc) for us */
SSL_free(qc->tls);
- ossl_crypto_mutex_free(&qc->mutex);
+ ossl_crypto_mutex_free(&qc->mutex); /* freed while still locked */
}
/* SSL method init */
quic_lock(qc);
- if (qc->ch == NULL)
+ if (qc->ch == NULL) {
+ quic_unlock(qc);
return 0;
+ }
ret = ossl_quic_reactor_net_read_desired(ossl_quic_channel_get_reactor(qc->ch));
quic_unlock(qc);
quic_lock(qc);
- if (qc->ch == NULL)
+ if (qc->ch == NULL) {
+ quic_unlock(qc);
return 0;
+ }
ret = ossl_quic_reactor_net_write_desired(ossl_quic_channel_get_reactor(qc->ch));
quic_unlock(qc);
/* Initial peer L4 address. */
BIO_ADDR init_peer_addr;
-#ifndef OPENSSL_NO_QUIC_THREAD_ASSIST
+# ifndef OPENSSL_NO_QUIC_THREAD_ASSIST
/* Manages thread for QUIC thread assisted mode. */
QUIC_THREAD_ASSIST thread_assist;
-#endif
+# endif
/* If non-NULL, used instead of ossl_time_now(). Used for testing. */
OSSL_TIME (*override_now_cb)(void *arg);
return 0;
if (mutex != NULL)
- CRYPTO_THREAD_unlock(mutex);
+ ossl_crypto_mutex_unlock(mutex);
do {
/*
pres = select(maxfd + 1, &rfd_set, &wfd_set, &efd_set, ptv);
} while (pres == -1 && get_last_socket_error_is_eintr());
- if (mutex != NULL && !CRYPTO_THREAD_write_lock(mutex))
- return 0;
+ if (mutex != NULL)
+ ossl_crypto_mutex_lock(mutex);
return pres < 0 ? 0 : 1;
#else
return 0;
if (mutex != NULL)
- CRYPTO_THREAD_unlock(mutex);
+ ossl_crypto_mutex_unlock(mutex);
do {
if (ossl_time_is_infinite(deadline)) {
pres = poll(pfds, npfd, timeout_ms);
} while (pres == -1 && get_last_socket_error_is_eintr());
- if (mutex != NULL && !CRYPTO_THREAD_write_lock(mutex))
- return 0;
+ if (mutex != NULL)
+ ossl_crypto_mutex_lock(mutex);
return pres < 0 ? 0 : 1;
#endif
srv->args = *args;
- if ((srv->mutex = CRYPTO_THREAD_lock_new()) == NULL)
+ if ((srv->mutex = ossl_crypto_mutex_new()) == NULL)
goto err;
srv->ctx = SSL_CTX_new_ex(srv->args.libctx, srv->args.propq, TLS_method());
return srv;
err:
- if (srv != NULL)
+ if (srv != NULL) {
ossl_quic_channel_free(srv->ch);
+ ossl_crypto_mutex_free(&srv->mutex);
+ }
OPENSSL_free(srv);
return NULL;
BIO_free(srv->args.net_wbio);
SSL_free(srv->tls);
SSL_CTX_free(srv->ctx);
- CRYPTO_THREAD_lock_free(srv->mutex);
+ ossl_crypto_mutex_free(&srv->mutex);
OPENSSL_free(srv);
}
static int test_tserver(int idx)
{
- int use_thread_assist, use_inject;
+ int thread_assisted, use_fake_time, use_inject;
- use_thread_assist = idx % 2;
+ thread_assisted = idx % 2;
idx /= 2;
use_inject = idx % 2;
+ idx /= 2;
- return test_tserver_actual(use_thread_assist, use_inject);
-}
-
-static int test_tserver_simple(void)
-{
- return do_test(/*thread_assisted=*/0, /*fake_time=*/0, /*use_inject=*/0);
-}
+ use_fake_time = idx % 2;
-static int test_tserver_thread(void)
-{
- return do_test(/*thread_assisted=*/1, /*fake_time=*/0, /*use_inject=*/0);
-}
+ if (use_fake_time && !thread_assisted)
+ return 1;
-static int test_tserver_thread_fake_time(void)
-{
- return do_test(/*thread_assisted=*/1, /*fake_time=*/1, /*use_inject=*/0);
+ return do_test(thread_assisted, use_fake_time, use_inject);
}
OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
if ((fake_time_lock = CRYPTO_THREAD_lock_new()) == NULL)
return 0;
- ADD_TEST(test_tserver_simple);
- ADD_TEST(test_tserver_thread);
- ADD_TEST(test_tserver_thread_fake_time);
+ ADD_ALL_TESTS(test_tserver, 2 * 2 * 2);
return 1;
}