# HG changeset patch # User Roman Arutyunyan # Date 1712124414 -14400 # Wed Apr 03 10:06:54 2024 +0400 # Node ID a1764cabbf54757af85069aceb638da6d7ce63bf # Parent 99e7050ac886f7c70a4048691e46846b930b1e28 QUIC: do not block ACKs by congestion control (ticket #2621). diff --git a/src/event/quic/ngx_event_quic_output.c b/src/event/quic/ngx_event_quic_output.c --- a/src/event/quic/ngx_event_quic_output.c +++ b/src/event/quic/ngx_event_quic_output.c @@ -55,7 +55,8 @@ static ssize_t ngx_quic_send_segments(ng size_t len, struct sockaddr *sockaddr, socklen_t socklen, size_t segment); #endif static ssize_t ngx_quic_output_packet(ngx_connection_t *c, - ngx_quic_send_ctx_t *ctx, u_char *data, size_t max, size_t min); + ngx_quic_send_ctx_t *ctx, u_char *data, size_t max, size_t min, + ngx_uint_t non_ack_eliciting); static void ngx_quic_init_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, ngx_quic_header_t *pkt, ngx_quic_path_t *path); static ngx_uint_t ngx_quic_get_padding_level(ngx_connection_t *c); @@ -116,7 +117,7 @@ ngx_quic_create_datagrams(ngx_connection ssize_t n; u_char *p; uint64_t preserved_pnum[NGX_QUIC_SEND_CTX_LAST]; - ngx_uint_t i, pad; + ngx_uint_t i, pad, non_ack_eliciting; ngx_quic_path_t *path; ngx_quic_send_ctx_t *ctx; ngx_quic_congestion_t *cg; @@ -127,7 +128,7 @@ ngx_quic_create_datagrams(ngx_connection cg = &qc->congestion; path = qc->path; - while (cg->in_flight < cg->window) { + for ( ;; ) { p = dst; @@ -135,6 +136,8 @@ ngx_quic_create_datagrams(ngx_connection pad = ngx_quic_get_padding_level(c); + non_ack_eliciting = (cg->in_flight < cg->window) ? 0 : 1; + for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { ctx = &qc->send_ctx[i]; @@ -159,7 +162,7 @@ ngx_quic_create_datagrams(ngx_connection return NGX_OK; } - n = ngx_quic_output_packet(c, ctx, p, len, min); + n = ngx_quic_output_packet(c, ctx, p, len, min, non_ack_eliciting); if (n == NGX_ERROR) { return NGX_ERROR; } @@ -312,7 +315,7 @@ ngx_quic_create_segments(ngx_connection_ ssize_t n; u_char *p, *end; uint64_t preserved_pnum; - ngx_uint_t nseg; + ngx_uint_t nseg, non_ack_eliciting; ngx_quic_path_t *path; ngx_quic_send_ctx_t *ctx; ngx_quic_congestion_t *cg; @@ -341,9 +344,11 @@ ngx_quic_create_segments(ngx_connection_ len = ngx_min(segsize, (size_t) (end - p)); - if (len && cg->in_flight + (p - dst) < cg->window) { + if (len) { + non_ack_eliciting = (cg->in_flight + (p - dst) < cg->window) + ? 0 : 1; - n = ngx_quic_output_packet(c, ctx, p, len, len); + n = ngx_quic_output_packet(c, ctx, p, len, len, non_ack_eliciting); if (n == NGX_ERROR) { return NGX_ERROR; } @@ -501,7 +506,7 @@ ngx_quic_get_padding_level(ngx_connectio static ssize_t ngx_quic_output_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, - u_char *data, size_t max, size_t min) + u_char *data, size_t max, size_t min, ngx_uint_t non_ack_eliciting) { size_t len, pad, min_payload, max_payload; u_char *p; @@ -569,6 +574,10 @@ ngx_quic_output_packet(ngx_connection_t break; } + if (non_ack_eliciting && f->need_ack) { + break; + } + if (len + f->len > max_payload) { rc = ngx_quic_split_frame(c, f, max_payload - len);