goto end;
fake_now = ossl_ms2time(1);
- if (!ossl_quic_conn_set_override_now_cb(client, fake_now_cb, NULL))
+ if (!ossl_quic_set_override_now_cb(client, fake_now_cb, NULL))
goto end;
peer_addr = BIO_ADDR_new();
*/
CRYPTO_MUTEX *mutex;
- OSSL_TIME (*now_cb)(void *arg);
- void *now_cb_arg;
-
/* Flags to pass when initialising the reactor. */
uint64_t reactor_flags;
} QUIC_ENGINE_ARGS;
/* Gets the current time. */
OSSL_TIME ossl_quic_engine_get_time(QUIC_ENGINE *qeng);
+/*
+ * Some use cases really need actual time rather than "fake" time. Convert a
+ * fake time into a real time. If tm is before the current fake time then the
+ * current time is returned.
+ */
+OSSL_TIME ossl_quic_engine_make_real_time(QUIC_ENGINE *qeng, OSSL_TIME tm);
+
+/* Override the callback for getting the current time */
+void ossl_quic_engine_set_time_cb(QUIC_ENGINE *qeng,
+ OSSL_TIME (*now_cb)(void *arg),
+ void *now_cb_arg);
+
/* For testing use. While enabled, ticking is not performed. */
void ossl_quic_engine_set_inhibit_tick(QUIC_ENGINE *qeng, int inhibit);
* overridden at any time, expect strange results if you change it after
* connecting.
*/
-int ossl_quic_conn_set_override_now_cb(SSL *s,
- OSSL_TIME (*now_cb)(void *arg),
- void *now_cb_arg);
+int ossl_quic_set_override_now_cb(SSL *s,
+ OSSL_TIME (*now_cb)(void *arg),
+ void *now_cb_arg);
/*
* Condvar waiting in the assist thread doesn't support time faking as it relies
CRYPTO_CONDVAR *cv;
CRYPTO_THREAD *t;
int teardown, joined;
- OSSL_TIME (*now_cb)(void *arg);
- void *now_cb_arg;
} QUIC_THREAD_ASSIST;
/*
* not affect the state of the mutex.
*/
int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta,
- QUIC_CHANNEL *ch,
- OSSL_TIME (*now_cb)(void *arg),
- void *now_cb_arg);
+ QUIC_CHANNEL *ch);
/*
* Request the thread assist helper to begin stopping the assist thread. This
qeng->libctx = args->libctx;
qeng->propq = args->propq;
qeng->mutex = args->mutex;
- qeng->now_cb = args->now_cb;
- qeng->now_cb_arg = args->now_cb_arg;
if (!qeng_init(qeng, args->reactor_flags)) {
OPENSSL_free(qeng);
return qeng->now_cb(qeng->now_cb_arg);
}
+OSSL_TIME ossl_quic_engine_make_real_time(QUIC_ENGINE *qeng, OSSL_TIME tm)
+{
+ OSSL_TIME offset;
+
+ if (qeng->now_cb != NULL
+ && !ossl_time_is_zero(tm)
+ && !ossl_time_is_infinite(tm)) {
+
+ offset = qeng->now_cb(qeng->now_cb_arg);
+
+ /* If tm is earlier than offset then tm will end up as "now" */
+ tm = ossl_time_add(ossl_time_subtract(tm, offset), ossl_time_now());
+ }
+
+ return tm;
+}
+
+void ossl_quic_engine_set_time_cb(QUIC_ENGINE *qeng,
+ OSSL_TIME (*now_cb)(void *arg),
+ void *now_cb_arg)
+{
+ qeng->now_cb = now_cb;
+ qeng->now_cb_arg = now_cb_arg;
+}
+
void ossl_quic_engine_set_inhibit_tick(QUIC_ENGINE *qeng, int inhibit)
{
qeng->inhibit_tick = (inhibit != 0);
static void qctx_maybe_autotick(QCTX *ctx);
static int qctx_should_autotick(QCTX *ctx);
-/*
- * QUIC Front-End I/O API: Common Utilities
- * ========================================
- */
-
-static OSSL_TIME get_time(QUIC_CONNECTION *qc)
-{
- if (qc->override_now_cb != NULL)
- return qc->override_now_cb(qc->override_now_cb_arg);
- else
- return ossl_time_now();
-}
-
-static OSSL_TIME get_time_cb(void *arg)
-{
- QUIC_CONNECTION *qc = arg;
-
- return get_time(qc);
-}
-
/*
* QCTX is a utility structure which provides information we commonly wish to
* unwrap upon an API call being dispatched to us, namely:
return 0;
}
-int ossl_quic_conn_set_override_now_cb(SSL *s,
- OSSL_TIME (*now_cb)(void *arg),
- void *now_cb_arg)
+int ossl_quic_set_override_now_cb(SSL *s,
+ OSSL_TIME (*now_cb)(void *arg),
+ void *now_cb_arg)
{
QCTX ctx;
- if (!expect_quic_conn_only(s, &ctx))
+ if (!expect_quic_any(s, &ctx))
return 0;
qctx_lock(&ctx);
- ctx.qc->override_now_cb = now_cb;
- ctx.qc->override_now_cb_arg = now_cb_arg;
+ ossl_quic_engine_set_time_cb(ctx.obj->engine, now_cb, now_cb_arg);
qctx_unlock(&ctx);
return 1;
return 1;
}
- /*
- * TODO(QUIC SERVER): The clock override callback belongs at the engine
- * (DOMAIN) not the QC layer, which would make `basetime` independent of
- * the object type.
- */
- if (ctx.qc)
- basetime = get_time(ctx.qc);
- else
- basetime = ossl_time_now();
+ basetime = ossl_quic_engine_get_time(ctx.obj->engine);
qctx_unlock(&ctx);
#if defined(OPENSSL_THREADS)
engine_args.mutex = qc->mutex;
#endif
- engine_args.now_cb = get_time_cb;
- engine_args.now_cb_arg = qc;
+
if (need_notifier_for_domain_flags(ctx->domain_flags))
engine_args.reactor_flags |= QUIC_REACTOR_FLAG_USE_NOTIFIER;
#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)
if (qc->is_thread_assisted)
- if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch,
- qc->override_now_cb,
- qc->override_now_cb_arg)) {
+ if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch)) {
QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR,
"failed to start assist thread");
return 0;
#if defined(OPENSSL_THREADS)
engine_args.mutex = ql->mutex;
#endif
+
if (need_notifier_for_domain_flags(ctx->domain_flags))
engine_args.reactor_flags |= QUIC_REACTOR_FLAG_USE_NOTIFIER;
#if defined(OPENSSL_THREADS)
engine_args.mutex = qd->mutex;
#endif
+
if (need_notifier_for_domain_flags(domain_flags))
engine_args.reactor_flags |= QUIC_REACTOR_FLAG_USE_NOTIFIER;
QUIC_THREAD_ASSIST thread_assist;
# endif
- /* If non-NULL, used instead of ossl_time_now(). Used for testing. */
- OSSL_TIME (*override_now_cb)(void *arg);
- void *override_now_cb_arg;
-
/* Number of XSOs allocated. Includes the default XSO, if any. */
size_t num_xso;
QUIC_THREAD_ASSIST *qta = arg;
CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch);
QUIC_REACTOR *rtor;
+ QUIC_ENGINE *eng = ossl_quic_channel_get0_engine(qta->ch);
ossl_crypto_mutex_lock(m);
break;
deadline = ossl_quic_reactor_get_tick_deadline(rtor);
- if (qta->now_cb != NULL
- && !ossl_time_is_zero(deadline)
- && !ossl_time_is_infinite(deadline)) {
- /*
- * ossl_crypto_condvar_wait_timeout needs to use real time for the
- * deadline
- */
- deadline = ossl_time_add(ossl_time_subtract(deadline,
- qta->now_cb(qta->now_cb_arg)),
- ossl_time_now());
- }
+ /*
+ * ossl_crypto_condvar_wait_timeout needs to use real time for the
+ * deadline
+ */
+ deadline = ossl_quic_engine_make_real_time(eng, deadline);
ossl_crypto_condvar_wait_timeout(qta->cv, m, deadline);
/*
}
int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta,
- QUIC_CHANNEL *ch,
- OSSL_TIME (*now_cb)(void *arg),
- void *now_cb_arg)
+ QUIC_CHANNEL *ch)
{
CRYPTO_MUTEX *mutex = ossl_quic_channel_get_mutex(ch);
qta->ch = ch;
qta->teardown = 0;
qta->joined = 0;
- qta->now_cb = now_cb;
- qta->now_cb_arg = now_cb_arg;
qta->cv = ossl_crypto_condvar_new();
if (qta->cv == NULL)
engine_args.libctx = srv->args.libctx;
engine_args.propq = srv->args.propq;
engine_args.mutex = srv->mutex;
- engine_args.now_cb = srv->args.now_cb;
- engine_args.now_cb_arg = srv->args.now_cb_arg;
if ((srv->engine = ossl_quic_engine_new(&engine_args)) == NULL)
goto err;
+ ossl_quic_engine_set_time_cb(srv->engine, srv->args.now_cb,
+ srv->args.now_cb_arg);
+
port_args.channel_ctx = srv->ctx;
port_args.is_multi_conn = 1;
using_fake_time = 1;
qtest_reset_time();
tserver_args.now_cb = fake_now_cb;
- (void)ossl_quic_conn_set_override_now_cb(*cssl, fake_now_cb, NULL);
+ (void)ossl_quic_set_override_now_cb(*cssl, fake_now_cb, NULL);
} else {
using_fake_time = 0;
}
goto err;
/* Use custom time function for virtual time skip. */
- if (!TEST_true(ossl_quic_conn_set_override_now_cb(h->c_conn, get_time, h)))
+ if (!TEST_true(ossl_quic_set_override_now_cb(h->c_conn, get_time, h)))
goto err;
/* Takes ownership of our reference to the BIO. */
goto err;
if (use_fake_time)
- if (!TEST_true(ossl_quic_conn_set_override_now_cb(c_ssl, fake_now, NULL)))
+ if (!TEST_true(ossl_quic_set_override_now_cb(c_ssl, fake_now, NULL)))
goto err;
/* 0 is a success for SSL_set_alpn_protos() */