comparison src/event/ngx_event_quic_transport.c @ 8560:d0d3fc0697a0 quic

QUIC: packet processing refactoring. All packet header parsing is now performed by ngx_quic_parse_packet() function, located in the ngx_quic_transport.c file. The packet processing is centralized in the ngx_quic_process_packet() function which decides if the packet should be accepted, ignored or connection should be closed, depending on the connection state. As a result of refactoring, behavior has changed in some places: - minimal size of Initial packet is now always tested - connection IDs are always tested in existing connections - old keys are discarded on encryption level switch
author Vladimir Homutov <vl@nginx.com>
date Wed, 30 Sep 2020 15:14:09 +0300
parents a89a58c642ef
children b31c02454539
comparison
equal deleted inserted replaced
8559:a89a58c642ef 8560:d0d3fc0697a0
64 static u_char *ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value); 64 static u_char *ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value);
65 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len, 65 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len,
66 u_char **out); 66 u_char **out);
67 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len, 67 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len,
68 u_char *dst); 68 u_char *dst);
69
70 static ngx_int_t ngx_quic_parse_long_header(ngx_quic_header_t *pkt);
71 static ngx_int_t ngx_quic_parse_short_header(ngx_quic_header_t *pkt,
72 size_t dcid_len);
73 static ngx_int_t ngx_quic_parse_initial_header(ngx_quic_header_t *pkt);
74 static ngx_int_t ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt);
69 75
70 static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt, 76 static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt,
71 ngx_uint_t frame_type); 77 ngx_uint_t frame_type);
72 static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack); 78 static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack);
73 static size_t ngx_quic_create_stop_sending(u_char *p, 79 static size_t ngx_quic_create_stop_sending(u_char *p,
243 return (u_char *) ngx_quic_errors[error_code]; 249 return (u_char *) ngx_quic_errors[error_code];
244 } 250 }
245 251
246 252
247 ngx_int_t 253 ngx_int_t
254 ngx_quic_parse_packet(ngx_quic_header_t *pkt)
255 {
256 if (!ngx_quic_long_pkt(pkt->flags)) {
257 pkt->level = ssl_encryption_application;
258
259 return ngx_quic_parse_short_header(pkt, NGX_QUIC_SERVER_CID_LEN);
260 }
261
262 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
263 return NGX_DECLINED;
264 }
265
266 if (pkt->version != NGX_QUIC_VERSION) {
267 return NGX_ABORT;
268 }
269
270 if (ngx_quic_pkt_in(pkt->flags)) {
271
272 if (pkt->len < NGX_QUIC_MIN_INITIAL_SIZE) {
273 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
274 "quic UDP datagram is too small for initial packet");
275 return NGX_DECLINED;
276 }
277
278 pkt->level = ssl_encryption_initial;
279
280 return ngx_quic_parse_initial_header(pkt);
281 }
282
283 if (ngx_quic_pkt_hs(pkt->flags)) {
284 pkt->level = ssl_encryption_handshake;
285
286 } else if (ngx_quic_pkt_zrtt(pkt->flags)) {
287 pkt->level = ssl_encryption_early_data;
288
289 } else {
290 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
291 "quic unknown long packet type");
292 return NGX_DECLINED;
293 }
294
295 return ngx_quic_parse_handshake_header(pkt);
296 }
297
298
299 static ngx_int_t
248 ngx_quic_parse_long_header(ngx_quic_header_t *pkt) 300 ngx_quic_parse_long_header(ngx_quic_header_t *pkt)
249 { 301 {
250 u_char *p, *end; 302 u_char *p, *end;
251 uint8_t idlen; 303 uint8_t idlen;
252 304
454 506
455 return p - out; 507 return p - out;
456 } 508 }
457 509
458 510
459 ngx_int_t 511 static ngx_int_t
460 ngx_quic_parse_short_header(ngx_quic_header_t *pkt, ngx_str_t *dcid) 512 ngx_quic_parse_short_header(ngx_quic_header_t *pkt, size_t dcid_len)
461 { 513 {
462 u_char *p, *end; 514 u_char *p, *end;
463 515
464 p = pkt->raw->pos; 516 p = pkt->raw->pos;
465 end = pkt->data + pkt->len; 517 end = pkt->data + pkt->len;
470 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { 522 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) {
471 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); 523 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set");
472 return NGX_ERROR; 524 return NGX_ERROR;
473 } 525 }
474 526
475 if (ngx_memcmp(p, dcid->data, dcid->len) != 0) { 527 pkt->dcid.len = dcid_len;
476 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "unexpected quic dcid"); 528
477 return NGX_ERROR; 529 p = ngx_quic_read_bytes(p, end, dcid_len, &pkt->dcid.data);
478 }
479
480 pkt->dcid.len = dcid->len;
481
482 p = ngx_quic_read_bytes(p, end, dcid->len, &pkt->dcid.data);
483 if (p == NULL) { 530 if (p == NULL) {
484 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, 531 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
485 "quic packet is too small to read dcid"); 532 "quic packet is too small to read dcid");
486 return NGX_ERROR; 533 return NGX_ERROR;
487 } 534 }
490 537
491 return NGX_OK; 538 return NGX_OK;
492 } 539 }
493 540
494 541
495 ngx_int_t 542 static ngx_int_t
496 ngx_quic_parse_initial_header(ngx_quic_header_t *pkt) 543 ngx_quic_parse_initial_header(ngx_quic_header_t *pkt)
497 { 544 {
498 u_char *p, *end; 545 u_char *p, *end;
499 uint64_t varint; 546 uint64_t varint;
500 547
546 593
547 return NGX_OK; 594 return NGX_OK;
548 } 595 }
549 596
550 597
551 ngx_int_t 598 static ngx_int_t
552 ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt) 599 ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt)
553 { 600 {
554 u_char *p, *end; 601 u_char *p, *end;
555 uint64_t plen; 602 uint64_t plen;
556 603