# HG changeset patch # User Sergey Kandaurov # Date 1692957098 -14400 # Node ID 2880f60a80c3e2706151dc7b48dc1267e39c47a9 # Parent 933f372732825d906ff9e9c177d0176c81067d69 QUIC: posted generating TLS Key Update next keys. Since at least f9fbeb4ee0de and certainly after 924882f42dea, which TLS Key Update support predates, queued data output is deferred to a posted push handler. To address timing signals after these changes, generating next keys is now posted to run after the push handler. diff --git a/src/event/quic/ngx_event_quic.c b/src/event/quic/ngx_event_quic.c --- a/src/event/quic/ngx_event_quic.c +++ b/src/event/quic/ngx_event_quic.c @@ -283,6 +283,10 @@ ngx_quic_new_connection(ngx_connection_t qc->path_validation.data = c; qc->path_validation.handler = ngx_quic_path_handler; + qc->key_update.log = c->log; + qc->key_update.data = c; + qc->key_update.handler = ngx_quic_keys_update; + qc->conf = conf; if (ngx_quic_init_transport_params(&qc->tp, conf) != NGX_OK) { @@ -562,6 +566,10 @@ ngx_quic_close_connection(ngx_connection ngx_delete_posted_event(&qc->push); } + if (qc->key_update.posted) { + ngx_delete_posted_event(&qc->key_update); + } + if (qc->close.timer_set) { return; } @@ -1055,7 +1063,9 @@ ngx_quic_handle_payload(ngx_connection_t return rc; } - return ngx_quic_keys_update(c, qc->keys); + ngx_post_event(&qc->key_update, &ngx_posted_events); + + return NGX_OK; } diff --git a/src/event/quic/ngx_event_quic_connection.h b/src/event/quic/ngx_event_quic_connection.h --- a/src/event/quic/ngx_event_quic_connection.h +++ b/src/event/quic/ngx_event_quic_connection.h @@ -230,6 +230,8 @@ struct ngx_quic_connection_s { ngx_event_t pto; ngx_event_t close; ngx_event_t path_validation; + ngx_event_t key_update; + ngx_msec_t last_cc; ngx_msec_t first_rtt; diff --git a/src/event/quic/ngx_event_quic_protection.c b/src/event/quic/ngx_event_quic_protection.c --- a/src/event/quic/ngx_event_quic_protection.c +++ b/src/event/quic/ngx_event_quic_protection.c @@ -700,23 +700,32 @@ ngx_quic_keys_switch(ngx_connection_t *c } -ngx_int_t -ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys) +void +ngx_quic_keys_update(ngx_event_t *ev) { - ngx_uint_t i; - ngx_quic_hkdf_t seq[6]; - ngx_quic_ciphers_t ciphers; - ngx_quic_secrets_t *current, *next; + ngx_uint_t i; + ngx_quic_hkdf_t seq[6]; + ngx_quic_keys_t *keys; + ngx_connection_t *c; + ngx_quic_ciphers_t ciphers; + ngx_quic_secrets_t *current, *next; + ngx_quic_connection_t *qc; + + c = ev->data; + qc = ngx_quic_get_connection(c); + keys = qc->keys; current = &keys->secrets[ssl_encryption_application]; next = &keys->next_key; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic key update"); + c->log->action = "updating keys"; + if (ngx_quic_ciphers(keys->cipher, &ciphers, ssl_encryption_application) == NGX_ERROR) { - return NGX_ERROR; + goto failed; } next->client.secret.len = current->client.secret.len; @@ -744,11 +753,15 @@ ngx_quic_keys_update(ngx_connection_t *c for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) { - return NGX_ERROR; + goto failed; } } - return NGX_OK; + return; + +failed: + + ngx_quic_close_connection(c, NGX_ERROR); } diff --git a/src/event/quic/ngx_event_quic_protection.h b/src/event/quic/ngx_event_quic_protection.h --- a/src/event/quic/ngx_event_quic_protection.h +++ b/src/event/quic/ngx_event_quic_protection.h @@ -99,7 +99,7 @@ ngx_uint_t ngx_quic_keys_available(ngx_q void ngx_quic_keys_discard(ngx_quic_keys_t *keys, enum ssl_encryption_level_t level); void ngx_quic_keys_switch(ngx_connection_t *c, ngx_quic_keys_t *keys); -ngx_int_t ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys); +void ngx_quic_keys_update(ngx_event_t *ev); ngx_int_t ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_str_t *res); ngx_int_t ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn); void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn); diff --git a/src/event/quic/ngx_event_quic_ssl.c b/src/event/quic/ngx_event_quic_ssl.c --- a/src/event/quic/ngx_event_quic_ssl.c +++ b/src/event/quic/ngx_event_quic_ssl.c @@ -482,9 +482,7 @@ ngx_quic_crypto_input(ngx_connection_t * * Generating next keys before a key update is received. */ - if (ngx_quic_keys_update(c, qc->keys) != NGX_OK) { - return NGX_ERROR; - } + ngx_post_event(&qc->key_update, &ngx_posted_events); /* * RFC 9001, 4.9.2. Discarding Handshake Keys