Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7706:1f002206a59b quic
Added boundaries checks into frame parser.
The ngx_quic_parse_frame() functions now has new 'pkt' argument: the packet
header of a currently processed frame. This allows to log errors/debug
closer to reasons and perform additional checks regarding possible frame
types. The handler only performs processing of good frames.
A number of functions like read_uint32(), parse_int[_multi] probably should
be implemented as a macro, but currently it is better to have them as
functions for simpler debugging.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 19 Mar 2020 17:07:12 +0300 |
parents | 5ad7bffd3850 |
children | db745339e54b |
comparison
equal
deleted
inserted
replaced
7705:5ad7bffd3850 | 7706:1f002206a59b |
---|---|
719 ack_this = 0; | 719 ack_this = 0; |
720 do_close = 0; | 720 do_close = 0; |
721 | 721 |
722 while (p < end) { | 722 while (p < end) { |
723 | 723 |
724 len = ngx_quic_parse_frame(p, end, &frame); | 724 len = ngx_quic_parse_frame(pkt, p, end, &frame); |
725 if (len < 0) { | 725 if (len < 0) { |
726 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
727 "failed to parse frame type 0x%xi", frame.type); | |
728 return NGX_ERROR; | 726 return NGX_ERROR; |
729 } | 727 } |
730 | 728 |
731 p += len; | 729 p += len; |
732 | 730 |
733 switch (frame.type) { | 731 switch (frame.type) { |
734 | 732 |
735 case NGX_QUIC_FT_ACK: | 733 case NGX_QUIC_FT_ACK: |
736 | |
737 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
738 "ACK: { largest=%ui delay=%ui first=%ui count=%ui}", | |
739 frame.u.ack.largest, | |
740 frame.u.ack.delay, | |
741 frame.u.ack.first_range, | |
742 frame.u.ack.range_count); | |
743 | |
744 if (ngx_quic_handle_ack_frame(c, pkt, &frame.u.ack) != NGX_OK) { | 734 if (ngx_quic_handle_ack_frame(c, pkt, &frame.u.ack) != NGX_OK) { |
745 return NGX_ERROR; | 735 return NGX_ERROR; |
746 } | 736 } |
747 | 737 |
748 break; | 738 break; |
749 | 739 |
750 case NGX_QUIC_FT_CRYPTO: | 740 case NGX_QUIC_FT_CRYPTO: |
751 | |
752 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
753 "quic CRYPTO frame length: %uL off:%uL pp:%p", | |
754 frame.u.crypto.len, frame.u.crypto.offset, | |
755 frame.u.crypto.data); | |
756 | |
757 ngx_quic_hexdump0(c->log, "CRYPTO frame contents", | |
758 frame.u.crypto.data, frame.u.crypto.len); | |
759 | |
760 | 741 |
761 if (ngx_quic_handle_crypto_frame(c, pkt, &frame.u.crypto) | 742 if (ngx_quic_handle_crypto_frame(c, pkt, &frame.u.crypto) |
762 != NGX_OK) | 743 != NGX_OK) |
763 { | 744 { |
764 return NGX_ERROR; | 745 return NGX_ERROR; |
774 ack_this = 1; | 755 ack_this = 1; |
775 break; | 756 break; |
776 | 757 |
777 case NGX_QUIC_FT_NEW_CONNECTION_ID: | 758 case NGX_QUIC_FT_NEW_CONNECTION_ID: |
778 ack_this = 1; | 759 ack_this = 1; |
779 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
780 "NCID: { seq=%ui retire=%ui len=%ui}", | |
781 frame.u.ncid.seqnum, | |
782 frame.u.ncid.retire, | |
783 frame.u.ncid.len); | |
784 break; | 760 break; |
785 | 761 |
786 case NGX_QUIC_FT_CONNECTION_CLOSE: | 762 case NGX_QUIC_FT_CONNECTION_CLOSE: |
787 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
788 "CONN.CLOSE: { %s (0x%xi) type=0x%xi reason='%V'}", | |
789 ngx_quic_error_text(frame.u.close.error_code), | |
790 frame.u.close.error_code, | |
791 frame.u.close.frame_type, | |
792 &frame.u.close.reason); | |
793 | 763 |
794 do_close = 1; | 764 do_close = 1; |
795 break; | 765 break; |
796 | 766 |
797 case NGX_QUIC_FT_STREAM0: | 767 case NGX_QUIC_FT_STREAM0: |
801 case NGX_QUIC_FT_STREAM4: | 771 case NGX_QUIC_FT_STREAM4: |
802 case NGX_QUIC_FT_STREAM5: | 772 case NGX_QUIC_FT_STREAM5: |
803 case NGX_QUIC_FT_STREAM6: | 773 case NGX_QUIC_FT_STREAM6: |
804 case NGX_QUIC_FT_STREAM7: | 774 case NGX_QUIC_FT_STREAM7: |
805 | 775 |
806 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
807 "STREAM frame { 0x%xi id 0x%xi offset 0x%xi len 0x%xi bits:off=%d len=%d fin=%d }", | |
808 frame.type, | |
809 frame.u.stream.stream_id, | |
810 frame.u.stream.offset, | |
811 frame.u.stream.length, | |
812 frame.u.stream.off, | |
813 frame.u.stream.len, | |
814 frame.u.stream.fin); | |
815 | |
816 ngx_quic_hexdump0(c->log, "STREAM frame contents", | |
817 frame.u.stream.data, frame.u.stream.length); | |
818 | |
819 if (ngx_quic_handle_stream_frame(c, pkt, &frame.u.stream) | 776 if (ngx_quic_handle_stream_frame(c, pkt, &frame.u.stream) |
820 != NGX_OK) | 777 != NGX_OK) |
821 { | 778 { |
822 return NGX_ERROR; | 779 return NGX_ERROR; |
823 } | 780 } |
824 | 781 |
825 ack_this = 1; | 782 ack_this = 1; |
826 break; | 783 break; |
827 | 784 |
828 case NGX_QUIC_FT_MAX_DATA: | 785 case NGX_QUIC_FT_MAX_DATA: |
829 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
830 "MAX_DATA frame" | |
831 " { Maximum Data %ui }", | |
832 frame.u.max_data.max_data); | |
833 | |
834 c->quic->max_data = frame.u.max_data.max_data; | 786 c->quic->max_data = frame.u.max_data.max_data; |
835 ack_this = 1; | 787 ack_this = 1; |
836 break; | 788 break; |
837 | 789 |
838 case NGX_QUIC_FT_RESET_STREAM: | 790 case NGX_QUIC_FT_RESET_STREAM: |
839 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | 791 /* TODO: handle */ |
840 "RESET STREAM frame" | |
841 " { id 0x%xi error_code 0x%xi final_size 0x%xi }", | |
842 frame.u.reset_stream.id, | |
843 frame.u.reset_stream.error_code, | |
844 frame.u.reset_stream.final_size); | |
845 break; | 792 break; |
846 | 793 |
847 case NGX_QUIC_FT_STOP_SENDING: | 794 case NGX_QUIC_FT_STOP_SENDING: |
848 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 795 /* TODO: handle; need ack ? */ |
849 "STOP SENDING frame" | |
850 " { id 0x%xi error_code 0x%xi}", | |
851 frame.u.stop_sending.id, | |
852 frame.u.stop_sending.error_code); | |
853 break; | 796 break; |
854 | 797 |
855 case NGX_QUIC_FT_STREAMS_BLOCKED: | 798 case NGX_QUIC_FT_STREAMS_BLOCKED: |
856 case NGX_QUIC_FT_STREAMS_BLOCKED2: | 799 case NGX_QUIC_FT_STREAMS_BLOCKED2: |
857 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 800 /* TODO: handle; need ack ? */ |
858 "STREAMS BLOCKED frame" | |
859 " { limit %i bidi: %d }", | |
860 frame.u.streams_blocked.limit, | |
861 frame.u.streams_blocked.bidi); | |
862 break; | 801 break; |
863 | 802 |
864 default: | 803 default: |
865 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
866 "unsupported frame type 0x%xd in packet", frame.type); | |
867 return NGX_ERROR; | 804 return NGX_ERROR; |
868 } | 805 } |
869 } | 806 } |
870 | 807 |
871 if (p != end) { | 808 if (p != end) { |