"port version negotiation send failed");
}
+/**
+ * @brief defintions of token lifetimes
+ *
+ * RETRY tokens are only valid for 10 seconds
+ * NEW_TOKEN tokens have a lifetime of 3600 sec (1 hour)
+ */
+
+#define RETRY_LIFETIME 10
+#define NEW_TOKEN_LIFETIME 3600
/**
* @brief Validates a received token in a QUIC packet header.
*
*/
static int port_validate_token(QUIC_PKT_HDR *hdr, QUIC_PORT *port,
BIO_ADDR *peer, QUIC_CONN_ID *odcid,
- QUIC_CONN_ID *scid)
+ QUIC_CONN_ID *scid, uint8_t *gen_new_token)
{
int ret = 0;
QUIC_VALIDATION_TOKEN token = { 0 };
- unsigned long long time_diff;
+ uint64_t time_diff;
size_t remote_addr_len, dec_token_len;
unsigned char *remote_addr = NULL, dec_token[MARSHALLED_TOKEN_MAX_LEN];
OSSL_TIME now = ossl_time_now();
+ *gen_new_token = 0;
+
if (!decrypt_validation_token(port, hdr->token, hdr->token_len, NULL,
&dec_token_len)
|| dec_token_len > MARSHALLED_TOKEN_MAX_LEN
goto err;
time_diff = ossl_time2seconds(ossl_time_abs_difference(token.timestamp,
now));
- if ((token.is_retry && time_diff > 10)
- || (!token.is_retry && time_diff > 3600))
+ if ((token.is_retry && time_diff > RETRY_LIFETIME)
+ || (!token.is_retry && time_diff > NEW_TOKEN_LIFETIME))
goto err;
/* Validate remote address */
*scid = hdr->src_conn_id;
}
+ /*
+ * Determine if we need to send a NEW_TOKEN frame
+ * If we validated a retry token, we should always
+ * send a NEW_TOKEN frame to the client
+ *
+ * If however, we validated a NEW_TOKEN, which may be
+ * reused multiple times, only send a NEW_TOKEN frame
+ * if the existing received token has 10% of its lifetime
+ * remaining. This prevents us from constantly sending
+ * NEW_TOKEN frames on every connection when not needed
+ */
+ if (token.is_retry) {
+ *gen_new_token = 1;
+ } else {
+ if (time_diff > ((NEW_TOKEN_LIFETIME * 9) / 10))
+ *gen_new_token = 1;
+ }
+
ret = 1;
err:
cleanup_validation_token(&token);
QUIC_PKT_HDR hdr;
QUIC_CHANNEL *ch = NULL, *new_ch = NULL;
QUIC_CONN_ID odcid, scid;
+ uint8_t gen_new_token = 0;
uint64_t cause_flags = 0;
/* Don't handle anything if we are no longer running. */
*/
if (hdr.token != NULL) {
if (port_validate_token(&hdr, port, &e->peer,
- &odcid, &scid) == 0) {
+ &odcid, &scid, &gen_new_token) == 0) {
/*
* RFC 9000 s 8.1.3
* When a server receives an Initial packet with an address
/*
* Generate a token for sending in a later NEW_TOKEN frame
*/
- generate_new_token(new_ch, &e->peer);
+ if (gen_new_token == 1)
+ generate_new_token(new_ch, &e->peer);
/*
* The channel will do all the LCID registration needed, but as an