Mercurial > hg > nginx
comparison src/event/quic/ngx_event_quic_migration.c @ 9189:fcec773dd249
QUIC: avoid partial expansion of PATH_CHALLENGE/PATH_RESPONSE.
By default packets with these frames are expanded to 1200 bytes. Previously,
if anti-amplification limit did not allow this expansion, it was limited to
whatever size was allowed. However RFC 9000 clearly states no partial
expansion should happen in both cases.
Section 8.2.1. Initiating Path Validation:
An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
to at least the smallest allowed maximum datagram size of 1200 bytes,
unless the anti-amplification limit for the path does not permit
sending a datagram of this size.
Section 8.2.2. Path Validation Responses:
An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame
to at least the smallest allowed maximum datagram size of 1200 bytes.
...
However, an endpoint MUST NOT expand the datagram containing the
PATH_RESPONSE if the resulting data exceeds the anti-amplification limit.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 29 Nov 2023 18:13:25 +0400 |
parents | f6b6f3dd7ca0 |
children | 3a67dd34b6cc |
comparison
equal
deleted
inserted
replaced
9188:b05c622715fa | 9189:fcec773dd249 |
---|---|
34 | 34 |
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 ngx_quic_frame_t frame, *fp; | 40 ngx_quic_frame_t frame, *fp; |
40 ngx_quic_connection_t *qc; | 41 ngx_quic_connection_t *qc; |
41 | 42 |
42 qc = ngx_quic_get_connection(c); | 43 qc = ngx_quic_get_connection(c); |
43 | 44 |
55 */ | 56 */ |
56 | 57 |
57 /* | 58 /* |
58 * An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame | 59 * An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame |
59 * to at least the smallest allowed maximum datagram size of 1200 bytes. | 60 * to at least the smallest allowed maximum datagram size of 1200 bytes. |
60 */ | 61 * ... |
61 if (ngx_quic_frame_sendto(c, &frame, 1200, pkt->path) == NGX_ERROR) { | 62 * However, an endpoint MUST NOT expand the datagram containing the |
63 * PATH_RESPONSE if the resulting data exceeds the anti-amplification limit. | |
64 */ | |
65 | |
66 min = (ngx_quic_path_limit(c, pkt->path, 1200) < 1200) ? 0 : 1200; | |
67 | |
68 if (ngx_quic_frame_sendto(c, &frame, min, pkt->path) == NGX_ERROR) { | |
62 return NGX_ERROR; | 69 return NGX_ERROR; |
63 } | 70 } |
64 | 71 |
65 if (pkt->path == qc->path) { | 72 if (pkt->path == qc->path) { |
66 /* | 73 /* |
111 | 118 |
112 if (path->state != NGX_QUIC_PATH_VALIDATING) { | 119 if (path->state != NGX_QUIC_PATH_VALIDATING) { |
113 continue; | 120 continue; |
114 } | 121 } |
115 | 122 |
116 if (ngx_memcmp(path->challenge1, f->data, sizeof(f->data)) == 0 | 123 if (ngx_memcmp(path->challenge[0], f->data, sizeof(f->data)) == 0 |
117 || ngx_memcmp(path->challenge2, f->data, sizeof(f->data)) == 0) | 124 || ngx_memcmp(path->challenge[1], f->data, sizeof(f->data)) == 0) |
118 { | 125 { |
119 goto valid; | 126 goto valid; |
120 } | 127 } |
121 } | 128 } |
122 | 129 |
508 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 515 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
509 "quic initiated validation of path seq:%uL", path->seqnum); | 516 "quic initiated validation of path seq:%uL", path->seqnum); |
510 | 517 |
511 path->tries = 0; | 518 path->tries = 0; |
512 | 519 |
513 if (RAND_bytes(path->challenge1, 8) != 1) { | 520 if (RAND_bytes((u_char *) path->challenge, sizeof(path->challenge)) != 1) { |
514 return NGX_ERROR; | |
515 } | |
516 | |
517 if (RAND_bytes(path->challenge2, 8) != 1) { | |
518 return NGX_ERROR; | 521 return NGX_ERROR; |
519 } | 522 } |
520 | 523 |
521 (void) ngx_quic_send_path_challenge(c, path); | 524 (void) ngx_quic_send_path_challenge(c, path); |
522 | 525 |
533 | 536 |
534 | 537 |
535 static ngx_int_t | 538 static ngx_int_t |
536 ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path) | 539 ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path) |
537 { | 540 { |
541 size_t min; | |
542 ngx_uint_t n; | |
538 ngx_quic_frame_t frame; | 543 ngx_quic_frame_t frame; |
539 | 544 |
540 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 545 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
541 "quic path seq:%uL send path_challenge tries:%ui", | 546 "quic path seq:%uL send path_challenge tries:%ui", |
542 path->seqnum, path->tries); | 547 path->seqnum, path->tries); |
544 ngx_memzero(&frame, sizeof(ngx_quic_frame_t)); | 549 ngx_memzero(&frame, sizeof(ngx_quic_frame_t)); |
545 | 550 |
546 frame.level = ssl_encryption_application; | 551 frame.level = ssl_encryption_application; |
547 frame.type = NGX_QUIC_FT_PATH_CHALLENGE; | 552 frame.type = NGX_QUIC_FT_PATH_CHALLENGE; |
548 | 553 |
549 ngx_memcpy(frame.u.path_challenge.data, path->challenge1, 8); | 554 for (n = 0; n < 2; n++) { |
550 | 555 |
551 /* | 556 ngx_memcpy(frame.u.path_challenge.data, path->challenge[n], 8); |
552 * RFC 9000, 8.2.1. Initiating Path Validation | 557 |
553 * | 558 /* |
554 * An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame | 559 * RFC 9000, 8.2.1. Initiating Path Validation |
555 * to at least the smallest allowed maximum datagram size of 1200 bytes, | 560 * |
556 * unless the anti-amplification limit for the path does not permit | 561 * An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame |
557 * sending a datagram of this size. | 562 * to at least the smallest allowed maximum datagram size of 1200 bytes, |
558 */ | 563 * unless the anti-amplification limit for the path does not permit |
559 | 564 * sending a datagram of this size. |
560 /* same applies to PATH_RESPONSE frames */ | 565 */ |
561 if (ngx_quic_frame_sendto(c, &frame, 1200, path) == NGX_ERROR) { | 566 |
562 return NGX_ERROR; | 567 min = (ngx_quic_path_limit(c, path, 1200) < 1200) ? 0 : 1200; |
563 } | 568 |
564 | 569 if (ngx_quic_frame_sendto(c, &frame, min, path) == NGX_ERROR) { |
565 ngx_memcpy(frame.u.path_challenge.data, path->challenge2, 8); | 570 return NGX_ERROR; |
566 | 571 } |
567 if (ngx_quic_frame_sendto(c, &frame, 1200, path) == NGX_ERROR) { | |
568 return NGX_ERROR; | |
569 } | 572 } |
570 | 573 |
571 return NGX_OK; | 574 return NGX_OK; |
572 } | 575 } |
573 | 576 |