comparison src/event/quic/ngx_event_quic_migration.c @ 9084:d565cf69ff5d quic

QUIC: reschedule path validation on path insertion/removal. Two issues fixed: - new path validation could be scheduled late - a validated path could leave a spurious timer
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 09 May 2023 19:42:40 +0400
parents a9fef6ca45a8
children 9462c514a653
comparison
equal deleted inserted replaced
9083:a9fef6ca45a8 9084:d565cf69ff5d
14 ngx_quic_path_t *path); 14 ngx_quic_path_t *path);
15 static ngx_int_t ngx_quic_validate_path(ngx_connection_t *c, 15 static ngx_int_t ngx_quic_validate_path(ngx_connection_t *c,
16 ngx_quic_path_t *path); 16 ngx_quic_path_t *path);
17 static ngx_int_t ngx_quic_send_path_challenge(ngx_connection_t *c, 17 static ngx_int_t ngx_quic_send_path_challenge(ngx_connection_t *c,
18 ngx_quic_path_t *path); 18 ngx_quic_path_t *path);
19 static void ngx_quic_set_path_timer(ngx_connection_t *c);
19 static ngx_quic_path_t *ngx_quic_get_path(ngx_connection_t *c, ngx_uint_t tag); 20 static ngx_quic_path_t *ngx_quic_get_path(ngx_connection_t *c, ngx_uint_t tag);
20 21
21 22
22 ngx_int_t 23 ngx_int_t
23 ngx_quic_handle_path_challenge_frame(ngx_connection_t *c, 24 ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
167 168
168 path->validated = 1; 169 path->validated = 1;
169 path->validating = 0; 170 path->validating = 0;
170 path->limited = 0; 171 path->limited = 0;
171 172
173 ngx_quic_set_path_timer(c);
174
172 return NGX_OK; 175 return NGX_OK;
173 } 176 }
174 177
175 178
176 ngx_quic_path_t * 179 ngx_quic_path_t *
513 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); 516 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application);
514 pto = ngx_max(ngx_quic_pto(c, ctx), 1000); 517 pto = ngx_max(ngx_quic_pto(c, ctx), 1000);
515 518
516 path->expires = ngx_current_msec + pto; 519 path->expires = ngx_current_msec + pto;
517 520
518 if (!qc->path_validation.timer_set) { 521 ngx_quic_set_path_timer(c);
519 ngx_add_timer(&qc->path_validation, pto);
520 }
521 522
522 return NGX_OK; 523 return NGX_OK;
523 } 524 }
524 525
525 526
561 562
562 return NGX_OK; 563 return NGX_OK;
563 } 564 }
564 565
565 566
567 static void
568 ngx_quic_set_path_timer(ngx_connection_t *c)
569 {
570 ngx_msec_t now;
571 ngx_queue_t *q;
572 ngx_msec_int_t left, next;
573 ngx_quic_path_t *path;
574 ngx_quic_connection_t *qc;
575
576 qc = ngx_quic_get_connection(c);
577
578 now = ngx_current_msec;
579 next = -1;
580
581 for (q = ngx_queue_head(&qc->paths);
582 q != ngx_queue_sentinel(&qc->paths);
583 q = ngx_queue_next(q))
584 {
585 path = ngx_queue_data(q, ngx_quic_path_t, queue);
586
587 if (!path->validating) {
588 continue;
589 }
590
591 left = path->expires - now;
592 left = ngx_max(left, 1);
593
594 if (next == -1 || left < next) {
595 next = left;
596 }
597 }
598
599 if (next != -1) {
600 ngx_add_timer(&qc->path_validation, next);
601
602 } else if (qc->path_validation.timer_set) {
603 ngx_del_timer(&qc->path_validation);
604 }
605 }
606
607
566 void 608 void
567 ngx_quic_path_validation_handler(ngx_event_t *ev) 609 ngx_quic_path_validation_handler(ngx_event_t *ev)
568 { 610 {
569 ngx_msec_t now; 611 ngx_msec_t now;
570 ngx_queue_t *q; 612 ngx_queue_t *q;