Mercurial > hg > nginx
comparison src/event/quic/ngx_event_quic_output.c @ 9147:58afcd72446f
QUIC: path MTU discovery.
MTU selection starts by doubling the initial MTU until the first failure.
Then binary search is used to find the path MTU.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 14 Aug 2023 09:21:27 +0400 |
parents | f3412ec3b6d1 |
children | 60c4e8d3151f |
comparison
equal
deleted
inserted
replaced
9146:f3412ec3b6d1 | 9147:58afcd72446f |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_event_quic_connection.h> | 10 #include <ngx_event_quic_connection.h> |
11 | 11 |
12 | |
13 #define NGX_QUIC_MAX_UDP_PAYLOAD_OUT 1252 | |
14 #define NGX_QUIC_MAX_UDP_PAYLOAD_OUT6 1232 | |
15 | 12 |
16 #define NGX_QUIC_MAX_UDP_SEGMENT_BUF 65487 /* 65K - IPv6 header */ | 13 #define NGX_QUIC_MAX_UDP_SEGMENT_BUF 65487 /* 65K - IPv6 header */ |
17 #define NGX_QUIC_MAX_SEGMENTS 64 /* UDP_MAX_SEGMENTS */ | 14 #define NGX_QUIC_MAX_SEGMENTS 64 /* UDP_MAX_SEGMENTS */ |
18 | 15 |
19 #define NGX_QUIC_RETRY_TOKEN_LIFETIME 3 /* seconds */ | 16 #define NGX_QUIC_RETRY_TOKEN_LIFETIME 3 /* seconds */ |
59 ngx_quic_send_ctx_t *ctx); | 56 ngx_quic_send_ctx_t *ctx); |
60 static size_t ngx_quic_path_limit(ngx_connection_t *c, ngx_quic_path_t *path, | 57 static size_t ngx_quic_path_limit(ngx_connection_t *c, ngx_quic_path_t *path, |
61 size_t size); | 58 size_t size); |
62 | 59 |
63 | 60 |
64 size_t | |
65 ngx_quic_max_udp_payload(ngx_connection_t *c) | |
66 { | |
67 /* TODO: path MTU discovery */ | |
68 | |
69 #if (NGX_HAVE_INET6) | |
70 if (c->sockaddr->sa_family == AF_INET6) { | |
71 return NGX_QUIC_MAX_UDP_PAYLOAD_OUT6; | |
72 } | |
73 #endif | |
74 | |
75 return NGX_QUIC_MAX_UDP_PAYLOAD_OUT; | |
76 } | |
77 | |
78 | |
79 ngx_int_t | 61 ngx_int_t |
80 ngx_quic_output(ngx_connection_t *c) | 62 ngx_quic_output(ngx_connection_t *c) |
81 { | 63 { |
82 size_t in_flight; | 64 size_t in_flight; |
83 ngx_int_t rc; | 65 ngx_int_t rc; |
140 | 122 |
141 while (cg->in_flight < cg->window) { | 123 while (cg->in_flight < cg->window) { |
142 | 124 |
143 p = dst; | 125 p = dst; |
144 | 126 |
145 len = ngx_min(qc->ctp.max_udp_payload_size, | 127 len = ngx_quic_path_limit(c, path, path->mtu); |
146 NGX_QUIC_MAX_UDP_PAYLOAD_SIZE); | |
147 | |
148 len = ngx_quic_path_limit(c, path, len); | |
149 | 128 |
150 pad = ngx_quic_get_padding_level(c); | 129 pad = ngx_quic_get_padding_level(c); |
151 | 130 |
152 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { | 131 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { |
153 | 132 |
297 } | 276 } |
298 | 277 |
299 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); | 278 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); |
300 | 279 |
301 bytes = 0; | 280 bytes = 0; |
302 | 281 len = ngx_min(qc->path->mtu, NGX_QUIC_MAX_UDP_SEGMENT_BUF); |
303 len = ngx_min(qc->ctp.max_udp_payload_size, | |
304 NGX_QUIC_MAX_UDP_SEGMENT_BUF); | |
305 | 282 |
306 for (q = ngx_queue_head(&ctx->frames); | 283 for (q = ngx_queue_head(&ctx->frames); |
307 q != ngx_queue_sentinel(&ctx->frames); | 284 q != ngx_queue_sentinel(&ctx->frames); |
308 q = ngx_queue_next(q)) | 285 q = ngx_queue_next(q)) |
309 { | 286 { |
343 | 320 |
344 if (ngx_quic_generate_ack(c, ctx) != NGX_OK) { | 321 if (ngx_quic_generate_ack(c, ctx) != NGX_OK) { |
345 return NGX_ERROR; | 322 return NGX_ERROR; |
346 } | 323 } |
347 | 324 |
348 segsize = ngx_min(qc->ctp.max_udp_payload_size, | 325 segsize = ngx_min(path->mtu, NGX_QUIC_MAX_UDP_SEGMENT_BUF); |
349 NGX_QUIC_MAX_UDP_SEGMENT_BUF); | |
350 p = dst; | 326 p = dst; |
351 end = dst + sizeof(dst); | 327 end = dst + sizeof(dst); |
352 | 328 |
353 nseg = 0; | 329 nseg = 0; |
354 | 330 |