# HG changeset patch # User Sergey Kandaurov # Date 1683646959 -14400 # Node ID c6db94ec38419b1590f7ef6b855306635219e9e9 # Parent 52cddd44ec11b62904fb13bee6a30dc23e40e36c QUIC: separated path validation retransmit backoff. 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 sent periodically, separately from the regular probe/lost detection mechanism. A path validation packet is resent up to 3 times, each time after PTO expiration, with increasing per-path PTO backoff. diff --git a/src/event/quic/ngx_event_quic_ack.c b/src/event/quic/ngx_event_quic_ack.c --- a/src/event/quic/ngx_event_quic_ack.c +++ b/src/event/quic/ngx_event_quic_ack.c @@ -736,7 +736,8 @@ ngx_quic_set_lost_timer(ngx_connection_t q = ngx_queue_last(&ctx->sent); f = ngx_queue_data(q, ngx_quic_frame_t, queue); - w = (ngx_msec_int_t) (f->last + ngx_quic_pto(c, ctx) - now); + w = (ngx_msec_int_t) (f->last + (ngx_quic_pto(c, ctx) << qc->pto_count) + - now); if (w < 0) { w = 0; @@ -785,10 +786,9 @@ ngx_quic_pto(ngx_connection_t *c, ngx_qu duration = qc->avg_rtt; duration += ngx_max(4 * qc->rttvar, NGX_QUIC_TIME_GRANULARITY); - duration <<= qc->pto_count; if (ctx->level == ssl_encryption_application && c->ssl->handshaked) { - duration += qc->ctp.max_ack_delay << qc->pto_count; + duration += qc->ctp.max_ack_delay; } return duration; @@ -846,7 +846,9 @@ ngx_quic_pto_handler(ngx_event_t *ev) continue; } - if ((ngx_msec_int_t) (f->last + ngx_quic_pto(c, ctx) - now) > 0) { + if ((ngx_msec_int_t) (f->last + (ngx_quic_pto(c, ctx) << qc->pto_count) + - now) > 0) + { continue; } 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 @@ -496,6 +496,7 @@ ngx_quic_validate_path(ngx_connection_t "quic initiated validation of path seq:%uL", path->seqnum); path->validating = 1; + path->tries = 0; if (RAND_bytes(path->challenge1, 8) != 1) { return NGX_ERROR; @@ -513,7 +514,6 @@ ngx_quic_validate_path(ngx_connection_t pto = ngx_quic_pto(c, ctx); path->expires = ngx_current_msec + pto; - path->tries = NGX_QUIC_PATH_RETRIES; if (!qc->path_validation.timer_set) { ngx_add_timer(&qc->path_validation, pto); @@ -578,7 +578,6 @@ ngx_quic_path_validation_handler(ngx_eve qc = ngx_quic_get_connection(c); ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); - pto = ngx_quic_pto(c, ctx); next = -1; now = ngx_current_msec; @@ -605,7 +604,9 @@ ngx_quic_path_validation_handler(ngx_eve continue; } - if (--path->tries) { + if (++path->tries < NGX_QUIC_PATH_RETRIES) { + pto = ngx_quic_pto(c, ctx) << path->tries; + path->expires = ngx_current_msec + pto; if (next == -1 || pto < next) {