comparison src/event/quic/ngx_event_quic_migration.c @ 9192:efcdaa66df2e

QUIC: congestion control in ngx_quic_frame_sendto(). Previously ngx_quic_frame_sendto() ignored congestion control and did not contribute to in_flight counter. Now congestion control window is checked unless ignore_congestion flag is set. Also, in_flight counter is incremented and the frame is stored in ctx->sent queue if it's ack-eliciting. This behavior is now similar to ngx_quic_output_packet().
author Roman Arutyunyan <arut@nginx.com>
date Wed, 29 Nov 2023 21:41:29 +0400
parents 618132842e7c
children a6f79f044de5
comparison
equal deleted inserted replaced
9191:618132842e7c 9192:efcdaa66df2e
35 ngx_int_t 35 ngx_int_t
36 ngx_quic_handle_path_challenge_frame(ngx_connection_t *c, 36 ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
37 ngx_quic_header_t *pkt, ngx_quic_path_challenge_frame_t *f) 37 ngx_quic_header_t *pkt, ngx_quic_path_challenge_frame_t *f)
38 { 38 {
39 size_t min; 39 size_t min;
40 ngx_quic_frame_t frame, *fp; 40 ngx_quic_frame_t *fp;
41 ngx_quic_connection_t *qc; 41 ngx_quic_connection_t *qc;
42 42
43 if (pkt->level != ssl_encryption_application || pkt->path_challenged) { 43 if (pkt->level != ssl_encryption_application || pkt->path_challenged) {
44 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, 44 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
45 "quic ignoring PATH_CHALLENGE"); 45 "quic ignoring PATH_CHALLENGE");
48 48
49 pkt->path_challenged = 1; 49 pkt->path_challenged = 1;
50 50
51 qc = ngx_quic_get_connection(c); 51 qc = ngx_quic_get_connection(c);
52 52
53 ngx_memzero(&frame, sizeof(ngx_quic_frame_t)); 53 fp = ngx_quic_alloc_frame(c);
54 54 if (fp == NULL) {
55 frame.level = ssl_encryption_application; 55 return NGX_ERROR;
56 frame.type = NGX_QUIC_FT_PATH_RESPONSE; 56 }
57 frame.u.path_response = *f; 57
58 fp->level = ssl_encryption_application;
59 fp->type = NGX_QUIC_FT_PATH_RESPONSE;
60 fp->u.path_response = *f;
58 61
59 /* 62 /*
60 * RFC 9000, 8.2.2. Path Validation Responses 63 * RFC 9000, 8.2.2. Path Validation Responses
61 * 64 *
62 * A PATH_RESPONSE frame MUST be sent on the network path where the 65 * A PATH_RESPONSE frame MUST be sent on the network path where the
71 * PATH_RESPONSE if the resulting data exceeds the anti-amplification limit. 74 * PATH_RESPONSE if the resulting data exceeds the anti-amplification limit.
72 */ 75 */
73 76
74 min = (ngx_quic_path_limit(c, pkt->path, 1200) < 1200) ? 0 : 1200; 77 min = (ngx_quic_path_limit(c, pkt->path, 1200) < 1200) ? 0 : 1200;
75 78
76 if (ngx_quic_frame_sendto(c, &frame, min, pkt->path) == NGX_ERROR) { 79 if (ngx_quic_frame_sendto(c, fp, min, pkt->path) == NGX_ERROR) {
77 return NGX_ERROR; 80 return NGX_ERROR;
78 } 81 }
79 82
80 if (pkt->path == qc->path) { 83 if (pkt->path == qc->path) {
81 /* 84 /*
544 547
545 548
546 static ngx_int_t 549 static ngx_int_t
547 ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path) 550 ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path)
548 { 551 {
549 size_t min; 552 size_t min;
550 ngx_uint_t n; 553 ngx_uint_t n;
551 ngx_quic_frame_t frame; 554 ngx_quic_frame_t *frame;
552 555
553 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 556 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
554 "quic path seq:%uL send path_challenge tries:%ui", 557 "quic path seq:%uL send path_challenge tries:%ui",
555 path->seqnum, path->tries); 558 path->seqnum, path->tries);
556 559
557 ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
558
559 frame.level = ssl_encryption_application;
560 frame.type = NGX_QUIC_FT_PATH_CHALLENGE;
561
562 for (n = 0; n < 2; n++) { 560 for (n = 0; n < 2; n++) {
563 561
564 ngx_memcpy(frame.u.path_challenge.data, path->challenge[n], 8); 562 frame = ngx_quic_alloc_frame(c);
563 if (frame == NULL) {
564 return NGX_ERROR;
565 }
566
567 frame->level = ssl_encryption_application;
568 frame->type = NGX_QUIC_FT_PATH_CHALLENGE;
569
570 ngx_memcpy(frame->u.path_challenge.data, path->challenge[n], 8);
565 571
566 /* 572 /*
567 * RFC 9000, 8.2.1. Initiating Path Validation 573 * RFC 9000, 8.2.1. Initiating Path Validation
568 * 574 *
569 * An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame 575 * An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
572 * sending a datagram of this size. 578 * sending a datagram of this size.
573 */ 579 */
574 580
575 min = (ngx_quic_path_limit(c, path, 1200) < 1200) ? 0 : 1200; 581 min = (ngx_quic_path_limit(c, path, 1200) < 1200) ? 0 : 1200;
576 582
577 if (ngx_quic_frame_sendto(c, &frame, min, path) == NGX_ERROR) { 583 if (ngx_quic_frame_sendto(c, frame, min, path) == NGX_ERROR) {
578 return NGX_ERROR; 584 return NGX_ERROR;
579 } 585 }
580 } 586 }
581 587
582 return NGX_OK; 588 return NGX_OK;
881 ngx_quic_send_path_mtu_probe(ngx_connection_t *c, ngx_quic_path_t *path) 887 ngx_quic_send_path_mtu_probe(ngx_connection_t *c, ngx_quic_path_t *path)
882 { 888 {
883 size_t mtu; 889 size_t mtu;
884 ngx_int_t rc; 890 ngx_int_t rc;
885 ngx_uint_t log_error; 891 ngx_uint_t log_error;
886 ngx_quic_frame_t frame; 892 ngx_quic_frame_t *frame;
887 ngx_quic_send_ctx_t *ctx; 893 ngx_quic_send_ctx_t *ctx;
888 ngx_quic_connection_t *qc; 894 ngx_quic_connection_t *qc;
889 895
890 ngx_memzero(&frame, sizeof(ngx_quic_frame_t)); 896 frame = ngx_quic_alloc_frame(c);
891 897 if (frame == NULL) {
892 frame.level = ssl_encryption_application; 898 return NGX_ERROR;
893 frame.type = NGX_QUIC_FT_PING; 899 }
900
901 frame->level = ssl_encryption_application;
902 frame->type = NGX_QUIC_FT_PING;
894 903
895 qc = ngx_quic_get_connection(c); 904 qc = ngx_quic_get_connection(c);
896 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); 905 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application);
897 path->mtu_pnum[path->tries] = ctx->pnum; 906 path->mtu_pnum[path->tries] = ctx->pnum;
898 907
905 c->log_error = NGX_ERROR_IGNORE_EMSGSIZE; 914 c->log_error = NGX_ERROR_IGNORE_EMSGSIZE;
906 915
907 mtu = path->mtu; 916 mtu = path->mtu;
908 path->mtu = path->mtud; 917 path->mtu = path->mtud;
909 918
910 rc = ngx_quic_frame_sendto(c, &frame, path->mtud, path); 919 rc = ngx_quic_frame_sendto(c, frame, path->mtud, path);
911 920
912 path->mtu = mtu; 921 path->mtu = mtu;
913 c->log_error = log_error; 922 c->log_error = log_error;
914 923
915 if (rc == NGX_ERROR) { 924 if (rc == NGX_ERROR) {