summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/internal/quic_channel.h7
-rw-r--r--include/internal/quic_ssl.h8
-rw-r--r--include/internal/quic_tserver.h2
-rw-r--r--ssl/quic/quic_channel.c26
-rw-r--r--ssl/quic/quic_channel_local.h6
-rw-r--r--ssl/quic/quic_impl.c12
-rw-r--r--ssl/quic/quic_local.h4
-rw-r--r--ssl/quic/quic_tserver.c2
8 files changed, 58 insertions, 9 deletions
diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h
index 1f7ef71ed4..bba7256d03 100644
--- a/include/internal/quic_channel.h
+++ b/include/internal/quic_channel.h
@@ -111,6 +111,13 @@ typedef struct quic_channel_args_st {
* mutex primitive or using its RW mutex primitive.
*/
CRYPTO_MUTEX *mutex;
+
+ /*
+ * Optional function pointer to use to retrieve the current time. If NULL,
+ * ossl_time_now() is used.
+ */
+ OSSL_TIME (*now_cb)(void *arg);
+ void *now_cb_arg;
} QUIC_CHANNEL_ARGS;
typedef struct quic_channel_st QUIC_CHANNEL;
diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h
index 3cf32e0944..e4af2c57be 100644
--- a/include/internal/quic_ssl.h
+++ b/include/internal/quic_ssl.h
@@ -65,6 +65,14 @@ BIO *ossl_quic_conn_get_net_wbio(const QUIC_CONNECTION *qc);
__owur int ossl_quic_conn_set_initial_peer_addr(QUIC_CONNECTION *qc,
const BIO_ADDR *peer_addr);
+/*
+ * Used to override ossl_time_now() for debug purposes. Must be called before
+ * connecting.
+ */
+void ossl_quic_conn_set_override_now_cb(SSL *s,
+ OSSL_TIME (*now_cb)(void *arg),
+ void *now_cb_arg);
+
# endif
#endif
diff --git a/include/internal/quic_tserver.h b/include/internal/quic_tserver.h
index a7fbb393f2..4545630a90 100644
--- a/include/internal/quic_tserver.h
+++ b/include/internal/quic_tserver.h
@@ -37,6 +37,8 @@ typedef struct quic_tserver_args_st {
OSSL_LIB_CTX *libctx;
const char *propq;
BIO *net_rbio, *net_wbio;
+ OSSL_TIME (*now_cb)(void *arg);
+ void *now_cb_arg;
} QUIC_TSERVER_ARGS;
QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args,
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index 16b158d8a9..2774329e5c 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -133,7 +133,7 @@ static int ch_init(QUIC_CHANNEL *ch)
if (!ossl_quic_rxfc_init(&ch->conn_rxfc, NULL,
2 * 1024 * 1024,
10 * 1024 * 1024,
- get_time, NULL))
+ get_time, ch))
goto err;
if (!ossl_statm_init(&ch->statm))
@@ -144,7 +144,7 @@ static int ch_init(QUIC_CHANNEL *ch)
if ((ch->cc_data = ch->cc_method->new(NULL, NULL, NULL)) == NULL)
goto err;
- if ((ch->ackm = ossl_ackm_new(get_time, NULL, &ch->statm,
+ if ((ch->ackm = ossl_ackm_new(get_time, ch, &ch->statm,
ch->cc_method, ch->cc_data)) == NULL)
goto err;
@@ -166,6 +166,7 @@ static int ch_init(QUIC_CHANNEL *ch)
txp_args.cc_method = ch->cc_method;
txp_args.cc_data = ch->cc_data;
txp_args.now = get_time;
+ txp_args.now_arg = ch;
for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) {
ch->crypto_send[pn_space] = ossl_quic_sstream_new(INIT_CRYPTO_BUF_LEN);
if (ch->crypto_send[pn_space] == NULL)
@@ -180,7 +181,7 @@ static int ch_init(QUIC_CHANNEL *ch)
if ((ch->demux = ossl_quic_demux_new(/*BIO=*/NULL,
/*Short CID Len=*/rx_short_cid_len,
- get_time, NULL)) == NULL)
+ get_time, ch)) == NULL)
goto err;
/*
@@ -232,7 +233,7 @@ static int ch_init(QUIC_CHANNEL *ch)
if (!ossl_quic_rxfc_init(&ch->stream0->rxfc, &ch->conn_rxfc,
1 * 1024 * 1024,
5 * 1024 * 1024,
- get_time, NULL))
+ get_time, ch))
goto err;
/* Plug in the TLS handshake layer. */
@@ -332,6 +333,8 @@ QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args)
ch->is_server = args->is_server;
ch->tls = args->tls;
ch->mutex = args->mutex;
+ ch->now_cb = args->now_cb;
+ ch->now_cb_arg = args->now_cb_arg;
if (!ch_init(ch)) {
OPENSSL_free(ch);
@@ -457,7 +460,12 @@ CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch)
/* Used by various components. */
static OSSL_TIME get_time(void *arg)
{
- return ossl_time_now();
+ QUIC_CHANNEL *ch = arg;
+
+ if (ch->now_cb == NULL)
+ return ossl_time_now();
+
+ return ch->now_cb(ch->now_cb_arg);
}
/* Used by QSM. */
@@ -1237,7 +1245,7 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags)
* expired.
*/
if (ossl_quic_channel_is_terminating(ch)) {
- now = ossl_time_now();
+ now = get_time(ch);
if (ossl_time_compare(now, ch->terminate_deadline) >= 0) {
ch_on_terminating_timeout(ch);
@@ -1279,7 +1287,7 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags)
* ACKM ACK generation deadline is polled by TXP, so we don't need to handle
* it here.
*/
- now = ossl_time_now();
+ now = get_time(ch);
if (ossl_time_compare(now, ch->idle_deadline) >= 0) {
/*
* Idle timeout differs from normal protocol violation because we do not
@@ -1934,7 +1942,7 @@ static void ch_start_terminating(QUIC_CHANNEL *ch,
ch->state = tcause->remote ? QUIC_CHANNEL_STATE_TERMINATING_DRAINING
: QUIC_CHANNEL_STATE_TERMINATING_CLOSING;
ch->terminate_deadline
- = ossl_time_add(ossl_time_now(),
+ = ossl_time_add(get_time(ch),
ossl_time_multiply(ossl_ackm_get_pto_duration(ch->ackm),
3));
@@ -2038,7 +2046,7 @@ static void ch_update_idle(QUIC_CHANNEL *ch)
if (ch->max_idle_timeout == 0)
ch->idle_deadline = ossl_time_infinite();
else
- ch->idle_deadline = ossl_time_add(ossl_time_now(),
+ ch->idle_deadline = ossl_time_add(get_time(ch),
ossl_ms2time(ch->max_idle_timeout));
}
diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h
index e1e60bf2b4..57db9792a9 100644
--- a/ssl/quic/quic_channel_local.h
+++ b/ssl/quic/quic_channel_local.h
@@ -34,6 +34,12 @@ struct quic_channel_st {
CRYPTO_RWLOCK *mutex;
/*
+ * Callback used to get the current time.
+ */
+ OSSL_TIME (*now_cb)(void *arg);
+ void *now_cb_arg;
+
+ /*
* 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).
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index b478e7c4f2..766a88633a 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -246,6 +246,16 @@ int ossl_quic_clear(SSL *s)
return 1;
}
+void ossl_quic_conn_set_override_now_cb(SSL *s,
+ OSSL_TIME (*now_cb)(void *arg),
+ void *now_cb_arg)
+{
+ QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+
+ qc->override_now_cb = now_cb;
+ qc->override_now_cb_arg = now_cb_arg;
+}
+
/*
* QUIC Front-End I/O API: Network BIO Configuration
* =================================================
@@ -683,6 +693,8 @@ static int ensure_channel(QUIC_CONNECTION *qc)
args.is_server = 0;
args.tls = qc->tls;
args.mutex = qc->mutex;
+ args.now_cb = qc->override_now_cb;
+ args.now_cb_arg = qc->override_now_cb_arg;
qc->ch = ossl_quic_channel_new(&args);
if (qc->ch == NULL)
diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h
index d405052674..a20e92df2a 100644
--- a/ssl/quic/quic_local.h
+++ b/ssl/quic/quic_local.h
@@ -71,6 +71,10 @@ struct quic_conn_st {
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;
+
/* Have we started? */
unsigned int started : 1;
diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c
index 4278f13f09..110e34a837 100644
--- a/ssl/quic/quic_tserver.c
+++ b/ssl/quic/quic_tserver.c
@@ -94,6 +94,8 @@ QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args,
ch_args.tls = srv->tls;
ch_args.mutex = srv->mutex;
ch_args.is_server = 1;
+ ch_args.now_cb = srv->args.now_cb;
+ ch_args.now_cb_arg = srv->args.now_cb_arg;
if ((srv->ch = ossl_quic_channel_new(&ch_args)) == NULL)
goto err;