Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic_output.c @ 8758:e72db9162180 quic
QUIC: got rid of excessive "qsock" argument in ngx_quic_output.c.
The output is always sent to the active path, which is stored in the
quic connection. There is no need to pass it in arguments.
When output has to be send to to a specific path (in rare cases, such as
path probing), a separate method exists (ngx_quic_frame_sendto()).
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 27 Dec 2021 13:52:57 +0300 |
parents | 0433e69f5425 |
children | 19e063e955bf |
comparison
equal
deleted
inserted
replaced
8757:b7284807b4fa | 8758:e72db9162180 |
---|---|
36 #define NGX_QUIC_CC_MIN_INTERVAL 1000 /* 1s */ | 36 #define NGX_QUIC_CC_MIN_INTERVAL 1000 /* 1s */ |
37 | 37 |
38 #define NGX_QUIC_SOCKET_RETRY_DELAY 10 /* ms, for NGX_AGAIN on write */ | 38 #define NGX_QUIC_SOCKET_RETRY_DELAY 10 /* ms, for NGX_AGAIN on write */ |
39 | 39 |
40 | 40 |
41 static ngx_int_t ngx_quic_socket_output(ngx_connection_t *c, | 41 static ngx_int_t ngx_quic_create_datagrams(ngx_connection_t *c); |
42 ngx_quic_socket_t *qsock); | |
43 static ngx_int_t ngx_quic_create_datagrams(ngx_connection_t *c, | |
44 ngx_quic_socket_t *qsock); | |
45 static void ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx); | 42 static void ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx); |
46 static void ngx_quic_revert_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, | 43 static void ngx_quic_revert_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, |
47 uint64_t pnum); | 44 uint64_t pnum); |
48 #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) | 45 #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) |
49 static ngx_uint_t ngx_quic_allow_segmentation(ngx_connection_t *c, | 46 static ngx_uint_t ngx_quic_allow_segmentation(ngx_connection_t *c); |
50 ngx_quic_socket_t *qsock); | 47 static ngx_int_t ngx_quic_create_segments(ngx_connection_t *c); |
51 static ngx_int_t ngx_quic_create_segments(ngx_connection_t *c, | |
52 ngx_quic_socket_t *qsock); | |
53 static ssize_t ngx_quic_send_segments(ngx_connection_t *c, u_char *buf, | 48 static ssize_t ngx_quic_send_segments(ngx_connection_t *c, u_char *buf, |
54 size_t len, struct sockaddr *sockaddr, socklen_t socklen, size_t segment); | 49 size_t len, struct sockaddr *sockaddr, socklen_t socklen, size_t segment); |
55 #endif | 50 #endif |
56 static ssize_t ngx_quic_output_packet(ngx_connection_t *c, | 51 static ssize_t ngx_quic_output_packet(ngx_connection_t *c, |
57 ngx_quic_send_ctx_t *ctx, u_char *data, size_t max, size_t min, | 52 ngx_quic_send_ctx_t *ctx, u_char *data, size_t max, size_t min); |
58 ngx_quic_socket_t *qsock); | |
59 static void ngx_quic_init_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, | 53 static void ngx_quic_init_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, |
60 ngx_quic_socket_t *qsock, ngx_quic_header_t *pkt); | 54 ngx_quic_header_t *pkt); |
61 static ngx_uint_t ngx_quic_get_padding_level(ngx_connection_t *c); | 55 static ngx_uint_t ngx_quic_get_padding_level(ngx_connection_t *c); |
62 static ssize_t ngx_quic_send(ngx_connection_t *c, u_char *buf, size_t len, | 56 static ssize_t ngx_quic_send(ngx_connection_t *c, u_char *buf, size_t len, |
63 struct sockaddr *sockaddr, socklen_t socklen); | 57 struct sockaddr *sockaddr, socklen_t socklen); |
64 static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt, | 58 static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt, |
65 ngx_quic_send_ctx_t *ctx); | 59 ngx_quic_send_ctx_t *ctx); |
83 | 77 |
84 | 78 |
85 ngx_int_t | 79 ngx_int_t |
86 ngx_quic_output(ngx_connection_t *c) | 80 ngx_quic_output(ngx_connection_t *c) |
87 { | 81 { |
88 ngx_quic_connection_t *qc; | |
89 | |
90 qc = ngx_quic_get_connection(c); | |
91 | |
92 if (ngx_quic_socket_output(c, qc->socket) != NGX_OK) { | |
93 return NGX_ERROR; | |
94 } | |
95 | |
96 ngx_quic_set_lost_timer(c); | |
97 | |
98 return NGX_OK; | |
99 } | |
100 | |
101 | |
102 static ngx_int_t | |
103 ngx_quic_socket_output(ngx_connection_t *c, ngx_quic_socket_t *qsock) | |
104 { | |
105 size_t in_flight; | 82 size_t in_flight; |
106 ngx_int_t rc; | 83 ngx_int_t rc; |
107 ngx_quic_congestion_t *cg; | 84 ngx_quic_congestion_t *cg; |
108 ngx_quic_connection_t *qc; | 85 ngx_quic_connection_t *qc; |
109 | 86 |
113 cg = &qc->congestion; | 90 cg = &qc->congestion; |
114 | 91 |
115 in_flight = cg->in_flight; | 92 in_flight = cg->in_flight; |
116 | 93 |
117 #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) | 94 #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) |
118 if (ngx_quic_allow_segmentation(c, qsock)) { | 95 if (ngx_quic_allow_segmentation(c)) { |
119 rc = ngx_quic_create_segments(c, qsock); | 96 rc = ngx_quic_create_segments(c); |
120 } else | 97 } else |
121 #endif | 98 #endif |
122 { | 99 { |
123 rc = ngx_quic_create_datagrams(c, qsock); | 100 rc = ngx_quic_create_datagrams(c); |
124 } | 101 } |
125 | 102 |
126 if (rc != NGX_OK) { | 103 if (rc != NGX_OK) { |
127 return NGX_ERROR; | 104 return NGX_ERROR; |
128 } | 105 } |
130 if (in_flight != cg->in_flight && !qc->send_timer_set && !qc->closing) { | 107 if (in_flight != cg->in_flight && !qc->send_timer_set && !qc->closing) { |
131 qc->send_timer_set = 1; | 108 qc->send_timer_set = 1; |
132 ngx_add_timer(c->read, qc->tp.max_idle_timeout); | 109 ngx_add_timer(c->read, qc->tp.max_idle_timeout); |
133 } | 110 } |
134 | 111 |
112 ngx_quic_set_lost_timer(c); | |
113 | |
135 return NGX_OK; | 114 return NGX_OK; |
136 } | 115 } |
137 | 116 |
138 | 117 |
139 static ngx_int_t | 118 static ngx_int_t |
140 ngx_quic_create_datagrams(ngx_connection_t *c, ngx_quic_socket_t *qsock) | 119 ngx_quic_create_datagrams(ngx_connection_t *c) |
141 { | 120 { |
142 size_t len, min; | 121 size_t len, min; |
143 ssize_t n; | 122 ssize_t n; |
144 u_char *p; | 123 u_char *p; |
145 uint64_t preserved_pnum[NGX_QUIC_SEND_CTX_LAST]; | 124 uint64_t preserved_pnum[NGX_QUIC_SEND_CTX_LAST]; |
150 ngx_quic_connection_t *qc; | 129 ngx_quic_connection_t *qc; |
151 static u_char dst[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; | 130 static u_char dst[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; |
152 | 131 |
153 qc = ngx_quic_get_connection(c); | 132 qc = ngx_quic_get_connection(c); |
154 cg = &qc->congestion; | 133 cg = &qc->congestion; |
155 path = qsock->path; | 134 path = qc->socket->path; |
156 | 135 |
157 while (cg->in_flight < cg->window) { | 136 while (cg->in_flight < cg->window) { |
158 | 137 |
159 p = dst; | 138 p = dst; |
160 | 139 |
180 | 159 |
181 if (min > len) { | 160 if (min > len) { |
182 continue; | 161 continue; |
183 } | 162 } |
184 | 163 |
185 n = ngx_quic_output_packet(c, ctx, p, len, min, qsock); | 164 n = ngx_quic_output_packet(c, ctx, p, len, min); |
186 if (n == NGX_ERROR) { | 165 if (n == NGX_ERROR) { |
187 return NGX_ERROR; | 166 return NGX_ERROR; |
188 } | 167 } |
189 | 168 |
190 p += n; | 169 p += n; |
274 | 253 |
275 | 254 |
276 #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) | 255 #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) |
277 | 256 |
278 static ngx_uint_t | 257 static ngx_uint_t |
279 ngx_quic_allow_segmentation(ngx_connection_t *c, ngx_quic_socket_t *qsock) | 258 ngx_quic_allow_segmentation(ngx_connection_t *c) |
280 { | 259 { |
281 size_t bytes, len; | 260 size_t bytes, len; |
282 ngx_queue_t *q; | 261 ngx_queue_t *q; |
283 ngx_quic_frame_t *f; | 262 ngx_quic_frame_t *f; |
284 ngx_quic_send_ctx_t *ctx; | 263 ngx_quic_send_ctx_t *ctx; |
288 | 267 |
289 if (!qc->conf->gso_enabled) { | 268 if (!qc->conf->gso_enabled) { |
290 return 0; | 269 return 0; |
291 } | 270 } |
292 | 271 |
293 if (qsock->path->limited) { | 272 if (qc->socket->path->limited) { |
294 /* don't even try to be faster on non-validated paths */ | 273 /* don't even try to be faster on non-validated paths */ |
295 return 0; | 274 return 0; |
296 } | 275 } |
297 | 276 |
298 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_initial); | 277 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_initial); |
329 return 0; | 308 return 0; |
330 } | 309 } |
331 | 310 |
332 | 311 |
333 static ngx_int_t | 312 static ngx_int_t |
334 ngx_quic_create_segments(ngx_connection_t *c, ngx_quic_socket_t *qsock) | 313 ngx_quic_create_segments(ngx_connection_t *c) |
335 { | 314 { |
336 size_t len, segsize; | 315 size_t len, segsize; |
337 ssize_t n; | 316 ssize_t n; |
338 u_char *p, *end; | 317 u_char *p, *end; |
339 uint64_t preserved_pnum; | 318 uint64_t preserved_pnum; |
344 ngx_quic_connection_t *qc; | 323 ngx_quic_connection_t *qc; |
345 static u_char dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF]; | 324 static u_char dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF]; |
346 | 325 |
347 qc = ngx_quic_get_connection(c); | 326 qc = ngx_quic_get_connection(c); |
348 cg = &qc->congestion; | 327 cg = &qc->congestion; |
349 path = qsock->path; | 328 path = qc->socket->path; |
350 | 329 |
351 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); | 330 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); |
352 | 331 |
353 if (ngx_quic_generate_ack(c, ctx) != NGX_OK) { | 332 if (ngx_quic_generate_ack(c, ctx) != NGX_OK) { |
354 return NGX_ERROR; | 333 return NGX_ERROR; |
367 | 346 |
368 len = ngx_min(segsize, (size_t) (end - p)); | 347 len = ngx_min(segsize, (size_t) (end - p)); |
369 | 348 |
370 if (len && cg->in_flight < cg->window) { | 349 if (len && cg->in_flight < cg->window) { |
371 | 350 |
372 n = ngx_quic_output_packet(c, ctx, p, len, len, qsock); | 351 n = ngx_quic_output_packet(c, ctx, p, len, len); |
373 if (n == NGX_ERROR) { | 352 if (n == NGX_ERROR) { |
374 return NGX_ERROR; | 353 return NGX_ERROR; |
375 } | 354 } |
376 | 355 |
377 if (n) { | 356 if (n) { |
522 } | 501 } |
523 | 502 |
524 | 503 |
525 static ssize_t | 504 static ssize_t |
526 ngx_quic_output_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, | 505 ngx_quic_output_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, |
527 u_char *data, size_t max, size_t min, ngx_quic_socket_t *qsock) | 506 u_char *data, size_t max, size_t min) |
528 { | 507 { |
529 size_t len, pad, min_payload, max_payload; | 508 size_t len, pad, min_payload, max_payload; |
530 u_char *p; | 509 u_char *p; |
531 ssize_t flen; | 510 ssize_t flen; |
532 ngx_str_t res; | 511 ngx_str_t res; |
540 | 519 |
541 if (ngx_queue_empty(&ctx->frames)) { | 520 if (ngx_queue_empty(&ctx->frames)) { |
542 return 0; | 521 return 0; |
543 } | 522 } |
544 | 523 |
545 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | 524 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
546 "quic output sock #%uL %s packet max:%uz min:%uz", | 525 "quic output %s packet max:%uz min:%uz", |
547 qsock->sid.seqnum, ngx_quic_level_name(ctx->level), | 526 ngx_quic_level_name(ctx->level), max, min); |
548 max, min); | 527 |
549 | 528 ngx_quic_init_packet(c, ctx, &pkt); |
550 ngx_quic_init_packet(c, ctx, qsock, &pkt); | |
551 | 529 |
552 min_payload = ngx_quic_payload_size(&pkt, min); | 530 min_payload = ngx_quic_payload_size(&pkt, min); |
553 max_payload = ngx_quic_payload_size(&pkt, max); | 531 max_payload = ngx_quic_payload_size(&pkt, max); |
554 | 532 |
555 /* RFC 9001, 5.4.2. Header Protection Sample */ | 533 /* RFC 9001, 5.4.2. Header Protection Sample */ |
688 } | 666 } |
689 | 667 |
690 | 668 |
691 static void | 669 static void |
692 ngx_quic_init_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, | 670 ngx_quic_init_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, |
693 ngx_quic_socket_t *qsock, ngx_quic_header_t *pkt) | 671 ngx_quic_header_t *pkt) |
694 { | 672 { |
673 ngx_quic_socket_t *qsock; | |
695 ngx_quic_connection_t *qc; | 674 ngx_quic_connection_t *qc; |
696 | 675 |
697 qc = ngx_quic_get_connection(c); | 676 qc = ngx_quic_get_connection(c); |
677 | |
678 qsock = qc->socket; | |
698 | 679 |
699 ngx_memzero(pkt, sizeof(ngx_quic_header_t)); | 680 ngx_memzero(pkt, sizeof(ngx_quic_header_t)); |
700 | 681 |
701 pkt->flags = NGX_QUIC_PKT_FIXED_BIT; | 682 pkt->flags = NGX_QUIC_PKT_FIXED_BIT; |
702 | 683 |
1219 static u_char dst[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; | 1200 static u_char dst[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; |
1220 | 1201 |
1221 qc = ngx_quic_get_connection(c); | 1202 qc = ngx_quic_get_connection(c); |
1222 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); | 1203 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); |
1223 | 1204 |
1224 ngx_quic_init_packet(c, ctx, qc->socket, &pkt); | 1205 ngx_quic_init_packet(c, ctx, &pkt); |
1225 | 1206 |
1226 min = ngx_quic_path_limit(c, path, min); | 1207 min = ngx_quic_path_limit(c, path, min); |
1227 | 1208 |
1228 min_payload = min ? ngx_quic_payload_size(&pkt, min) : 0; | 1209 min_payload = min ? ngx_quic_payload_size(&pkt, min) : 0; |
1229 | 1210 |