# include <openssl/ssl.h>
# include <openssl/bio.h>
+# include "internal/refcount.h"
# include "internal/quic_record_rx.h" /* OSSL_QRX */
# include "internal/quic_ackm.h" /* OSSL_ACKM */
# include "internal/quic_channel.h" /* QUIC_CHANNEL */
__owur SSL *ossl_quic_new_from_listener(SSL *ssl, uint64_t flags);
__owur SSL *ossl_quic_new_domain(SSL_CTX *ctx, uint64_t flags);
-typedef void QTOK;
+/*
+ * Datatype returned from ossl_quic_get_peer_token
+ */
+typedef struct quic_token_st {
+ CRYPTO_REF_COUNT references;
+ uint8_t *hashkey;
+ size_t hashkey_len;
+ uint8_t *token;
+ size_t token_len;
+} QUIC_TOKEN;
+
SSL_TOKEN_STORE_HANDLE *ossl_quic_new_token_store(void);
void ossl_quic_free_token_store(SSL_TOKEN_STORE_HANDLE *hdl);
SSL_TOKEN_STORE_HANDLE *ossl_quic_get0_token_store(SSL_CTX *ctx);
int ossl_quic_set_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,
const uint8_t *token, size_t token_len);
int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,
- uint8_t **token, size_t *token_len,
- QTOK **token_free_ptr);
-void ossl_quic_free_peer_token(QTOK *token);
+ QUIC_TOKEN **token);
+void ossl_quic_free_peer_token(QUIC_TOKEN *token);
__owur int ossl_quic_init(SSL *s);
void ossl_quic_deinit(SSL *s);
ch->handshake_complete = 1;
if (ch->pending_new_token != NULL) {
+ /*
+ * Note this is a best effort operation here
+ * If scheduling a new token fails, the worst outcome is that
+ * a client, not having received it, will just have to go through
+ * an extra roundtrip on a subsequent connection via the retry frame
+ * path, at which point we get another opportunity to schedule another
+ * new token. As a result, we don't need to handle any errors here
+ */
ossl_quic_channel_schedule_new_token(ch,
ch->pending_new_token,
ch->pending_new_token_len);
static void free_peer_token(const unsigned char *token,
size_t token_len, void *arg)
{
- ossl_quic_free_peer_token((QTOK *)arg);
+ ossl_quic_free_peer_token((QUIC_TOKEN *)arg);
}
int ossl_quic_channel_start(QUIC_CHANNEL *ch)
{
- uint8_t *token;
- size_t token_len;
- QTOK *token_ptr;
+ QUIC_TOKEN *token;
if (ch->is_server)
/*
if (!ch->is_server
&& ossl_quic_get_peer_token(ch->port->channel_ctx,
&ch->cur_peer_addr,
- &token, &token_len,
- &token_ptr)
- && !ossl_quic_tx_packetiser_set_initial_token(ch->txp, token,
- token_len,
+ &token)
+ && !ossl_quic_tx_packetiser_set_initial_token(ch->txp, token->token,
+ token->token_len,
free_peer_token,
- token_ptr))
- free_peer_token(NULL, 0, token_ptr);
+ token))
+ free_peer_token(NULL, 0, token);
/* Plug in secrets for the Initial EL. */
if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,
return NULL;
}
-/*
- * Token store management
- */
-typedef struct quic_token_st {
- CRYPTO_REF_COUNT references;
- uint8_t *hashkey;
- size_t hashkey_len;
- uint8_t *token;
- size_t token_len;
-} QUIC_TOKEN;
-
DEFINE_LHASH_OF_EX(QUIC_TOKEN);
typedef struct ssl_token_store_st {
static void free_this_token(QUIC_TOKEN *tok)
{
- ossl_quic_free_peer_token((QTOK *)tok);
+ ossl_quic_free_peer_token(tok);
}
void ossl_quic_free_token_store(SSL_TOKEN_STORE_HANDLE *hdl)
*famptr = family;
*portptr = port;
if (!BIO_ADDR_rawaddress(peer, addrptr, NULL)) {
- ossl_quic_free_peer_token((QTOK *)new_token);
+ ossl_quic_free_peer_token(new_token);
return NULL;
}
if (token != NULL)
old = lh_QUIC_TOKEN_retrieve(c->cache, tok);
if (old != NULL) {
lh_QUIC_TOKEN_delete(c->cache, old);
- ossl_quic_free_peer_token((QTOK *)old);
+ ossl_quic_free_peer_token(old);
}
lh_QUIC_TOKEN_insert(c->cache, tok);
}
int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,
- uint8_t **token, size_t *token_len,
- QTOK **token_free_ptr)
+ QUIC_TOKEN **token)
{
SSL_TOKEN_STORE *c = ctx->tokencache;
QUIC_TOKEN *key = NULL;
ossl_crypto_mutex_lock(c->mutex);
tok = lh_QUIC_TOKEN_retrieve(c->cache, key);
if (tok != NULL) {
- *token = tok->token;
- *token_len = tok->token_len;
- *token_free_ptr = (QTOK *)tok;
+ *token = tok;
CRYPTO_UP_REF(&tok->references, &ret);
rc = 1;
}
ossl_crypto_mutex_unlock(c->mutex);
- ossl_quic_free_peer_token((QTOK *)key);
+ ossl_quic_free_peer_token(key);
return rc;
}
-void ossl_quic_free_peer_token(QTOK *token)
+void ossl_quic_free_peer_token(QUIC_TOKEN *token)
{
- QUIC_TOKEN *tok = (QUIC_TOKEN *)token;
int refs = 0;
- if (!CRYPTO_DOWN_REF(&tok->references, &refs))
+ if (!CRYPTO_DOWN_REF(&token->references, &refs))
return;
if (refs > 0)
return;
- CRYPTO_FREE_REF(&tok->references);
- OPENSSL_free(tok);
+ CRYPTO_FREE_REF(&token->references);
+ OPENSSL_free(token);
}
/*
# ifndef OPENSSL_NO_QUIC
/* only create a cache for client CTX-es */
if (meth == OSSL_QUIC_client_method())
- ret->tokencache = ossl_quic_new_token_store();
+ if ((ret->tokencache = ossl_quic_new_token_store()) == NULL)
+ goto err;
ret->domain_flags = 0;
if (IS_QUIC_METHOD(meth)) {
# if defined(OPENSSL_THREADS)