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)