Mercurial > hg > nginx
comparison src/event/ngx_event_quic_transport.c @ 8640:46374c3fee3f quic
QUIC: sorted header parsing functions in order of appearance.
No functional changes.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Tue, 17 Nov 2020 21:31:51 +0000 |
parents | ad7ca043edf5 |
children | fe53def49945 |
comparison
equal
deleted
inserted
replaced
8639:9d28e9028aa5 | 8640:46374c3fee3f |
---|---|
72 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len, | 72 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len, |
73 u_char **out); | 73 u_char **out); |
74 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len, | 74 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len, |
75 u_char *dst); | 75 u_char *dst); |
76 | 76 |
77 static ngx_int_t ngx_quic_parse_long_header(ngx_quic_header_t *pkt); | |
78 static ngx_int_t ngx_quic_parse_short_header(ngx_quic_header_t *pkt, | 77 static ngx_int_t ngx_quic_parse_short_header(ngx_quic_header_t *pkt, |
79 size_t dcid_len); | 78 size_t dcid_len); |
79 static ngx_int_t ngx_quic_parse_long_header(ngx_quic_header_t *pkt); | |
80 static ngx_int_t ngx_quic_supported_version(uint32_t version); | |
80 static ngx_int_t ngx_quic_parse_initial_header(ngx_quic_header_t *pkt); | 81 static ngx_int_t ngx_quic_parse_initial_header(ngx_quic_header_t *pkt); |
81 static ngx_int_t ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt); | 82 static ngx_int_t ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt); |
82 static ngx_int_t ngx_quic_supported_version(uint32_t version); | |
83 | 83 |
84 static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt, | 84 static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt, |
85 ngx_uint_t frame_type); | 85 ngx_uint_t frame_type); |
86 static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack); | 86 static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack); |
87 static size_t ngx_quic_create_stop_sending(u_char *p, | 87 static size_t ngx_quic_create_stop_sending(u_char *p, |
326 | 326 |
327 return NGX_OK; | 327 return NGX_OK; |
328 } | 328 } |
329 | 329 |
330 | 330 |
331 static ngx_int_t | |
332 ngx_quic_parse_short_header(ngx_quic_header_t *pkt, size_t dcid_len) | |
333 { | |
334 u_char *p, *end; | |
335 | |
336 p = pkt->raw->pos; | |
337 end = pkt->data + pkt->len; | |
338 | |
339 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
340 "quic packet rx short flags:%xd", pkt->flags); | |
341 | |
342 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { | |
343 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); | |
344 return NGX_ERROR; | |
345 } | |
346 | |
347 pkt->dcid.len = dcid_len; | |
348 | |
349 p = ngx_quic_read_bytes(p, end, dcid_len, &pkt->dcid.data); | |
350 if (p == NULL) { | |
351 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
352 "quic packet is too small to read dcid"); | |
353 return NGX_ERROR; | |
354 } | |
355 | |
356 pkt->raw->pos = p; | |
357 | |
358 return NGX_OK; | |
359 } | |
360 | |
361 | |
362 static ngx_int_t | |
363 ngx_quic_parse_long_header(ngx_quic_header_t *pkt) | |
364 { | |
365 u_char *p, *end; | |
366 uint8_t idlen; | |
367 | |
368 p = pkt->raw->pos; | |
369 end = pkt->data + pkt->len; | |
370 | |
371 p = ngx_quic_read_uint32(p, end, &pkt->version); | |
372 if (p == NULL) { | |
373 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
374 "quic packet is too small to read version"); | |
375 return NGX_ERROR; | |
376 } | |
377 | |
378 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
379 "quic packet rx long flags:%xd version:%xD", | |
380 pkt->flags, pkt->version); | |
381 | |
382 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { | |
383 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); | |
384 return NGX_ERROR; | |
385 } | |
386 | |
387 p = ngx_quic_read_uint8(p, end, &idlen); | |
388 if (p == NULL) { | |
389 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
390 "quic packet is too small to read dcid len"); | |
391 return NGX_ERROR; | |
392 } | |
393 | |
394 if (idlen > NGX_QUIC_CID_LEN_MAX) { | |
395 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
396 "quic packet dcid is too long"); | |
397 return NGX_ERROR; | |
398 } | |
399 | |
400 pkt->dcid.len = idlen; | |
401 | |
402 p = ngx_quic_read_bytes(p, end, idlen, &pkt->dcid.data); | |
403 if (p == NULL) { | |
404 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
405 "quic packet is too small to read dcid"); | |
406 return NGX_ERROR; | |
407 } | |
408 | |
409 p = ngx_quic_read_uint8(p, end, &idlen); | |
410 if (p == NULL) { | |
411 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
412 "quic packet is too small to read scid len"); | |
413 return NGX_ERROR; | |
414 } | |
415 | |
416 if (idlen > NGX_QUIC_CID_LEN_MAX) { | |
417 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
418 "quic packet scid is too long"); | |
419 return NGX_ERROR; | |
420 } | |
421 | |
422 pkt->scid.len = idlen; | |
423 | |
424 p = ngx_quic_read_bytes(p, end, idlen, &pkt->scid.data); | |
425 if (p == NULL) { | |
426 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
427 "quic packet is too small to read scid"); | |
428 return NGX_ERROR; | |
429 } | |
430 | |
431 pkt->raw->pos = p; | |
432 | |
433 return NGX_OK; | |
434 } | |
435 | |
436 | |
437 static ngx_int_t | |
438 ngx_quic_supported_version(uint32_t version) | |
439 { | |
440 ngx_uint_t i; | |
441 | |
442 for (i = 0; i < NGX_QUIC_NVERSIONS; i++) { | |
443 if (ngx_quic_versions[i] == version) { | |
444 return 1; | |
445 } | |
446 } | |
447 | |
448 return 0; | |
449 } | |
450 | |
451 | |
452 static ngx_int_t | |
453 ngx_quic_parse_initial_header(ngx_quic_header_t *pkt) | |
454 { | |
455 u_char *p, *end; | |
456 uint64_t varint; | |
457 | |
458 p = pkt->raw->pos; | |
459 | |
460 end = pkt->raw->last; | |
461 | |
462 pkt->log->action = "parsing quic initial header"; | |
463 | |
464 p = ngx_quic_parse_int(p, end, &varint); | |
465 if (p == NULL) { | |
466 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
467 "quic failed to parse token length"); | |
468 return NGX_ERROR; | |
469 } | |
470 | |
471 pkt->token.len = varint; | |
472 | |
473 p = ngx_quic_read_bytes(p, end, pkt->token.len, &pkt->token.data); | |
474 if (p == NULL) { | |
475 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
476 "quic packet too small to read token data"); | |
477 return NGX_ERROR; | |
478 } | |
479 | |
480 p = ngx_quic_parse_int(p, end, &varint); | |
481 if (p == NULL) { | |
482 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic bad packet length"); | |
483 return NGX_ERROR; | |
484 } | |
485 | |
486 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
487 "quic packet rx initial len:%uL", varint); | |
488 | |
489 if (varint > (uint64_t) ((pkt->data + pkt->len) - p)) { | |
490 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
491 "quic truncated initial packet"); | |
492 return NGX_ERROR; | |
493 } | |
494 | |
495 pkt->raw->pos = p; | |
496 pkt->len = p + varint - pkt->data; | |
497 | |
498 #ifdef NGX_QUIC_DEBUG_PACKETS | |
499 ngx_quic_hexdump(pkt->log, "quic DCID", pkt->dcid.data, pkt->dcid.len); | |
500 ngx_quic_hexdump(pkt->log, "quic SCID", pkt->scid.data, pkt->scid.len); | |
501 ngx_quic_hexdump(pkt->log, "quic token", pkt->token.data, pkt->token.len); | |
502 #endif | |
503 | |
504 return NGX_OK; | |
505 } | |
506 | |
507 | |
508 static ngx_int_t | |
509 ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt) | |
510 { | |
511 u_char *p, *end; | |
512 uint64_t plen; | |
513 | |
514 p = pkt->raw->pos; | |
515 end = pkt->raw->last; | |
516 | |
517 pkt->log->action = "parsing quic handshake header"; | |
518 | |
519 p = ngx_quic_parse_int(p, end, &plen); | |
520 if (p == NULL) { | |
521 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic bad packet length"); | |
522 return NGX_ERROR; | |
523 } | |
524 | |
525 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
526 "quic packet rx handshake len:%uL", plen); | |
527 | |
528 if (plen > (uint64_t)((pkt->data + pkt->len) - p)) { | |
529 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
530 "quic truncated handshake packet"); | |
531 return NGX_ERROR; | |
532 } | |
533 | |
534 pkt->raw->pos = p; | |
535 pkt->len = p + plen - pkt->data; | |
536 | |
537 return NGX_OK; | |
538 } | |
539 | |
540 | |
331 ngx_int_t | 541 ngx_int_t |
332 ngx_quic_get_packet_dcid(ngx_log_t *log, u_char *data, size_t n, | 542 ngx_quic_get_packet_dcid(ngx_log_t *log, u_char *data, size_t n, |
333 ngx_str_t *dcid) | 543 ngx_str_t *dcid) |
334 { | 544 { |
335 size_t len, offset; | 545 size_t len, offset; |
363 failed: | 573 failed: |
364 | 574 |
365 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0, "quic malformed packet"); | 575 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0, "quic malformed packet"); |
366 | 576 |
367 return NGX_ERROR; | 577 return NGX_ERROR; |
368 } | |
369 | |
370 | |
371 static ngx_int_t | |
372 ngx_quic_parse_long_header(ngx_quic_header_t *pkt) | |
373 { | |
374 u_char *p, *end; | |
375 uint8_t idlen; | |
376 | |
377 p = pkt->raw->pos; | |
378 end = pkt->data + pkt->len; | |
379 | |
380 p = ngx_quic_read_uint32(p, end, &pkt->version); | |
381 if (p == NULL) { | |
382 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
383 "quic packet is too small to read version"); | |
384 return NGX_ERROR; | |
385 } | |
386 | |
387 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
388 "quic packet rx long flags:%xd version:%xD", | |
389 pkt->flags, pkt->version); | |
390 | |
391 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { | |
392 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); | |
393 return NGX_ERROR; | |
394 } | |
395 | |
396 p = ngx_quic_read_uint8(p, end, &idlen); | |
397 if (p == NULL) { | |
398 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
399 "quic packet is too small to read dcid len"); | |
400 return NGX_ERROR; | |
401 } | |
402 | |
403 if (idlen > NGX_QUIC_CID_LEN_MAX) { | |
404 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
405 "quic packet dcid is too long"); | |
406 return NGX_ERROR; | |
407 } | |
408 | |
409 pkt->dcid.len = idlen; | |
410 | |
411 p = ngx_quic_read_bytes(p, end, idlen, &pkt->dcid.data); | |
412 if (p == NULL) { | |
413 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
414 "quic packet is too small to read dcid"); | |
415 return NGX_ERROR; | |
416 } | |
417 | |
418 p = ngx_quic_read_uint8(p, end, &idlen); | |
419 if (p == NULL) { | |
420 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
421 "quic packet is too small to read scid len"); | |
422 return NGX_ERROR; | |
423 } | |
424 | |
425 if (idlen > NGX_QUIC_CID_LEN_MAX) { | |
426 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
427 "quic packet scid is too long"); | |
428 return NGX_ERROR; | |
429 } | |
430 | |
431 pkt->scid.len = idlen; | |
432 | |
433 p = ngx_quic_read_bytes(p, end, idlen, &pkt->scid.data); | |
434 if (p == NULL) { | |
435 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
436 "quic packet is too small to read scid"); | |
437 return NGX_ERROR; | |
438 } | |
439 | |
440 pkt->raw->pos = p; | |
441 | |
442 return NGX_OK; | |
443 } | 578 } |
444 | 579 |
445 | 580 |
446 size_t | 581 size_t |
447 ngx_quic_create_version_negotiation(ngx_quic_header_t *pkt, u_char *out) | 582 ngx_quic_create_version_negotiation(ngx_quic_header_t *pkt, u_char *out) |
585 p = ngx_cpymem(p, pkt->scid.data, pkt->scid.len); | 720 p = ngx_cpymem(p, pkt->scid.data, pkt->scid.len); |
586 | 721 |
587 p = ngx_cpymem(p, pkt->token.data, pkt->token.len); | 722 p = ngx_cpymem(p, pkt->token.data, pkt->token.len); |
588 | 723 |
589 return p - out; | 724 return p - out; |
590 } | |
591 | |
592 | |
593 static ngx_int_t | |
594 ngx_quic_parse_short_header(ngx_quic_header_t *pkt, size_t dcid_len) | |
595 { | |
596 u_char *p, *end; | |
597 | |
598 p = pkt->raw->pos; | |
599 end = pkt->data + pkt->len; | |
600 | |
601 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
602 "quic packet rx short flags:%xd", pkt->flags); | |
603 | |
604 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { | |
605 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); | |
606 return NGX_ERROR; | |
607 } | |
608 | |
609 pkt->dcid.len = dcid_len; | |
610 | |
611 p = ngx_quic_read_bytes(p, end, dcid_len, &pkt->dcid.data); | |
612 if (p == NULL) { | |
613 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
614 "quic packet is too small to read dcid"); | |
615 return NGX_ERROR; | |
616 } | |
617 | |
618 pkt->raw->pos = p; | |
619 | |
620 return NGX_OK; | |
621 } | |
622 | |
623 | |
624 static ngx_int_t | |
625 ngx_quic_parse_initial_header(ngx_quic_header_t *pkt) | |
626 { | |
627 u_char *p, *end; | |
628 uint64_t varint; | |
629 | |
630 p = pkt->raw->pos; | |
631 | |
632 end = pkt->raw->last; | |
633 | |
634 pkt->log->action = "parsing quic initial header"; | |
635 | |
636 p = ngx_quic_parse_int(p, end, &varint); | |
637 if (p == NULL) { | |
638 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
639 "quic failed to parse token length"); | |
640 return NGX_ERROR; | |
641 } | |
642 | |
643 pkt->token.len = varint; | |
644 | |
645 p = ngx_quic_read_bytes(p, end, pkt->token.len, &pkt->token.data); | |
646 if (p == NULL) { | |
647 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
648 "quic packet too small to read token data"); | |
649 return NGX_ERROR; | |
650 } | |
651 | |
652 p = ngx_quic_parse_int(p, end, &varint); | |
653 if (p == NULL) { | |
654 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic bad packet length"); | |
655 return NGX_ERROR; | |
656 } | |
657 | |
658 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
659 "quic packet rx initial len:%uL", varint); | |
660 | |
661 if (varint > (uint64_t) ((pkt->data + pkt->len) - p)) { | |
662 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
663 "quic truncated initial packet"); | |
664 return NGX_ERROR; | |
665 } | |
666 | |
667 pkt->raw->pos = p; | |
668 pkt->len = p + varint - pkt->data; | |
669 | |
670 #ifdef NGX_QUIC_DEBUG_PACKETS | |
671 ngx_quic_hexdump(pkt->log, "quic DCID", pkt->dcid.data, pkt->dcid.len); | |
672 ngx_quic_hexdump(pkt->log, "quic SCID", pkt->scid.data, pkt->scid.len); | |
673 ngx_quic_hexdump(pkt->log, "quic token", pkt->token.data, pkt->token.len); | |
674 #endif | |
675 | |
676 return NGX_OK; | |
677 } | |
678 | |
679 | |
680 static ngx_int_t | |
681 ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt) | |
682 { | |
683 u_char *p, *end; | |
684 uint64_t plen; | |
685 | |
686 p = pkt->raw->pos; | |
687 end = pkt->raw->last; | |
688 | |
689 pkt->log->action = "parsing quic handshake header"; | |
690 | |
691 p = ngx_quic_parse_int(p, end, &plen); | |
692 if (p == NULL) { | |
693 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic bad packet length"); | |
694 return NGX_ERROR; | |
695 } | |
696 | |
697 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | |
698 "quic packet rx handshake len:%uL", plen); | |
699 | |
700 if (plen > (uint64_t)((pkt->data + pkt->len) - p)) { | |
701 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
702 "quic truncated handshake packet"); | |
703 return NGX_ERROR; | |
704 } | |
705 | |
706 pkt->raw->pos = p; | |
707 pkt->len = p + plen - pkt->data; | |
708 | |
709 return NGX_OK; | |
710 } | |
711 | |
712 | |
713 static ngx_int_t | |
714 ngx_quic_supported_version(uint32_t version) | |
715 { | |
716 ngx_uint_t i; | |
717 | |
718 for (i = 0; i < NGX_QUIC_NVERSIONS; i++) { | |
719 if (ngx_quic_versions[i] == version) { | |
720 return 1; | |
721 } | |
722 } | |
723 | |
724 return 0; | |
725 } | 725 } |
726 | 726 |
727 | 727 |
728 #define ngx_quic_stream_bit_off(val) (((val) & 0x04) ? 1 : 0) | 728 #define ngx_quic_stream_bit_off(val) (((val) & 0x04) ? 1 : 0) |
729 #define ngx_quic_stream_bit_len(val) (((val) & 0x02) ? 1 : 0) | 729 #define ngx_quic_stream_bit_len(val) (((val) & 0x02) ? 1 : 0) |