# HG changeset patch # User Roman Arutyunyan <a...@nginx.com> # Date 1679925333 -14400 # Mon Mar 27 17:55:33 2023 +0400 # Branch quic # Node ID f76e83412133085a6c82fce2c3e15b2c34a6e959 # Parent 5fd628b89bb7fb5c95afa1dc914385f7ab79f6a3 QUIC: changed path validation timeout.
Path validation packets containing PATH_CHALLENGE frames are sent separately from regular frame queue, because of the need to use a decicated path and pad the packets. The packets are also resent separately from the regular probe/lost detection mechanism. A path validation packet is resent 3 times, each time after PTO expiration. Assuming constant PTO, the overall maximum waiting time is 3 * PTO. According to RFC 9000, 8.2.4. Failed Path Validation, the following value is recommended as a validation timeout: A value of three times the larger of the current PTO or the PTO for the new path (using kInitialRtt, as defined in [QUIC-RECOVERY]) is RECOMMENDED. The change adds PTO of the new path to the equation as the lower bound. Also, max_ack_delay is now always accounted for, unlike previously, when it was only used when there are packets in flight. As mentioned before, PACH_CHALLENGE is not considered in-flight by nginx since it's processed separately, but technically it is. diff --git a/src/event/quic/ngx_event_quic_migration.c b/src/event/quic/ngx_event_quic_migration.c --- a/src/event/quic/ngx_event_quic_migration.c +++ b/src/event/quic/ngx_event_quic_migration.c @@ -14,6 +14,7 @@ static void ngx_quic_set_connection_path ngx_quic_path_t *path); static ngx_int_t ngx_quic_validate_path(ngx_connection_t *c, ngx_quic_path_t *path); +static ngx_msec_t ngx_quic_path_pto(ngx_connection_t *c); static ngx_int_t ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path); static ngx_quic_path_t *ngx_quic_get_path(ngx_connection_t *c, ngx_uint_t tag); @@ -487,7 +488,6 @@ static ngx_int_t ngx_quic_validate_path(ngx_connection_t *c, ngx_quic_path_t *path) { ngx_msec_t pto; - ngx_quic_send_ctx_t *ctx; ngx_quic_connection_t *qc; qc = ngx_quic_get_connection(c); @@ -509,8 +509,7 @@ ngx_quic_validate_path(ngx_connection_t return NGX_ERROR; } - ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); - pto = ngx_quic_pto(c, ctx); + pto = ngx_quic_path_pto(c); path->expires = ngx_current_msec + pto; path->tries = NGX_QUIC_PATH_RETRIES; @@ -523,6 +522,33 @@ ngx_quic_validate_path(ngx_connection_t } +static ngx_msec_t +ngx_quic_path_pto(ngx_connection_t *c) +{ + + ngx_msec_t duration; + ngx_quic_connection_t *qc; + + /* + * RFC 9000, 8.2.4. Failed Path Validation + * + * A value of three times the larger of the current PTO + * or the PTO for the new path (using kInitialRtt, as defined + * in [QUIC-RECOVERY]) is RECOMMENDED. + */ + + qc = ngx_quic_get_connection(c); + + duration = qc->avg_rtt + 4 * qc->rttvar; + + if (duration < 1000) { + duration = 1000; + } + + return duration + qc->ctp.max_ack_delay; +} + + static ngx_int_t ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path) { @@ -571,14 +597,12 @@ ngx_quic_path_validation_handler(ngx_eve ngx_msec_int_t left, next, pto; ngx_quic_path_t *path, *bkp; ngx_connection_t *c; - ngx_quic_send_ctx_t *ctx; ngx_quic_connection_t *qc; c = ev->data; qc = ngx_quic_get_connection(c); - ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); - pto = ngx_quic_pto(c, ctx); + pto = ngx_quic_path_pto(c); next = -1; now = ngx_current_msec; _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel