| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "quiche/quic/test_tools/simple_quic_framer.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "absl/memory/memory.h" |
| #include "absl/strings/string_view.h" |
| #include "quiche/quic/core/crypto/quic_decrypter.h" |
| #include "quiche/quic/core/crypto/quic_encrypter.h" |
| #include "quiche/quic/core/quic_types.h" |
| |
| namespace quic { |
| namespace test { |
| |
| class SimpleFramerVisitor : public QuicFramerVisitorInterface { |
| public: |
| SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {} |
| SimpleFramerVisitor(const SimpleFramerVisitor&) = delete; |
| SimpleFramerVisitor& operator=(const SimpleFramerVisitor&) = delete; |
| |
| ~SimpleFramerVisitor() override {} |
| |
| void OnError(QuicFramer* framer) override { error_ = framer->error(); } |
| |
| bool OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) override { |
| return false; |
| } |
| |
| void OnPacket() override {} |
| void OnPublicResetPacket(const QuicPublicResetPacket& packet) override { |
| public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet)); |
| } |
| void OnVersionNegotiationPacket( |
| const QuicVersionNegotiationPacket& packet) override { |
| version_negotiation_packet_ = |
| std::make_unique<QuicVersionNegotiationPacket>((packet)); |
| } |
| |
| void OnRetryPacket(QuicConnectionId /*original_connection_id*/, |
| QuicConnectionId /*new_connection_id*/, |
| absl::string_view /*retry_token*/, |
| absl::string_view /*retry_integrity_tag*/, |
| absl::string_view /*retry_without_tag*/) override {} |
| |
| bool OnUnauthenticatedPublicHeader( |
| const QuicPacketHeader& /*header*/) override { |
| return true; |
| } |
| bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override { |
| return true; |
| } |
| void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override { |
| last_decrypted_level_ = level; |
| } |
| bool OnPacketHeader(const QuicPacketHeader& header) override { |
| has_header_ = true; |
| header_ = header; |
| return true; |
| } |
| |
| void OnCoalescedPacket(const QuicEncryptedPacket& packet) override { |
| coalesced_packet_ = packet.Clone(); |
| } |
| |
| void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/, |
| EncryptionLevel /*decryption_level*/, |
| bool /*has_decryption_key*/) override {} |
| |
| bool OnStreamFrame(const QuicStreamFrame& frame) override { |
| // Save a copy of the data so it is valid after the packet is processed. |
| std::string* string_data = |
| new std::string(frame.data_buffer, frame.data_length); |
| stream_data_.push_back(absl::WrapUnique(string_data)); |
| // TODO(ianswett): A pointer isn't necessary with emplace_back. |
| stream_frames_.push_back(std::make_unique<QuicStreamFrame>( |
| frame.stream_id, frame.fin, frame.offset, |
| absl::string_view(*string_data))); |
| return true; |
| } |
| |
| bool OnCryptoFrame(const QuicCryptoFrame& frame) override { |
| // Save a copy of the data so it is valid after the packet is processed. |
| std::string* string_data = |
| new std::string(frame.data_buffer, frame.data_length); |
| crypto_data_.push_back(absl::WrapUnique(string_data)); |
| crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>( |
| frame.level, frame.offset, absl::string_view(*string_data))); |
| return true; |
| } |
| |
| bool OnAckFrameStart(QuicPacketNumber largest_acked, |
| QuicTime::Delta ack_delay_time) override { |
| QuicAckFrame ack_frame; |
| ack_frame.largest_acked = largest_acked; |
| ack_frame.ack_delay_time = ack_delay_time; |
| ack_frames_.push_back(ack_frame); |
| return true; |
| } |
| |
| bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override { |
| QUICHE_DCHECK(!ack_frames_.empty()); |
| ack_frames_[ack_frames_.size() - 1].packets.AddRange(start, end); |
| return true; |
| } |
| |
| bool OnAckTimestamp(QuicPacketNumber /*packet_number*/, |
| QuicTime /*timestamp*/) override { |
| return true; |
| } |
| |
| void OnAckEcnCounts(const QuicEcnCounts& /*ecn_counts*/) override {} |
| |
| bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; } |
| |
| bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override { |
| stop_waiting_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnPaddingFrame(const QuicPaddingFrame& frame) override { |
| padding_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnPingFrame(const QuicPingFrame& frame) override { |
| ping_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override { |
| rst_stream_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override { |
| connection_close_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override { |
| new_connection_id_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnRetireConnectionIdFrame( |
| const QuicRetireConnectionIdFrame& frame) override { |
| retire_connection_id_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override { |
| new_token_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override { |
| stop_sending_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override { |
| path_challenge_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override { |
| path_response_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override { |
| goaway_frames_.push_back(frame); |
| return true; |
| } |
| bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override { |
| max_streams_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override { |
| streams_blocked_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override { |
| window_update_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnBlockedFrame(const QuicBlockedFrame& frame) override { |
| blocked_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnMessageFrame(const QuicMessageFrame& frame) override { |
| message_frames_.emplace_back(frame.data, frame.message_length); |
| return true; |
| } |
| |
| bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override { |
| handshake_done_frames_.push_back(frame); |
| return true; |
| } |
| |
| bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override { |
| ack_frequency_frames_.push_back(frame); |
| return true; |
| } |
| |
| void OnPacketComplete() override {} |
| |
| bool IsValidStatelessResetToken( |
| const StatelessResetToken& /*token*/) const override { |
| return false; |
| } |
| |
| void OnAuthenticatedIetfStatelessResetPacket( |
| const QuicIetfStatelessResetPacket& packet) override { |
| stateless_reset_packet_ = |
| std::make_unique<QuicIetfStatelessResetPacket>(packet); |
| } |
| |
| void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} |
| void OnDecryptedFirstPacketInKeyPhase() override {} |
| std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() |
| override { |
| return nullptr; |
| } |
| std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { |
| return nullptr; |
| } |
| |
| const QuicPacketHeader& header() const { return header_; } |
| const std::vector<QuicAckFrame>& ack_frames() const { return ack_frames_; } |
| const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const { |
| return connection_close_frames_; |
| } |
| |
| const std::vector<QuicGoAwayFrame>& goaway_frames() const { |
| return goaway_frames_; |
| } |
| const std::vector<QuicMaxStreamsFrame>& max_streams_frames() const { |
| return max_streams_frames_; |
| } |
| const std::vector<QuicStreamsBlockedFrame>& streams_blocked_frames() const { |
| return streams_blocked_frames_; |
| } |
| const std::vector<QuicRstStreamFrame>& rst_stream_frames() const { |
| return rst_stream_frames_; |
| } |
| const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const { |
| return stream_frames_; |
| } |
| const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const { |
| return crypto_frames_; |
| } |
| const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const { |
| return stop_waiting_frames_; |
| } |
| const std::vector<QuicPingFrame>& ping_frames() const { return ping_frames_; } |
| const std::vector<QuicMessageFrame>& message_frames() const { |
| return message_frames_; |
| } |
| const std::vector<QuicWindowUpdateFrame>& window_update_frames() const { |
| return window_update_frames_; |
| } |
| const std::vector<QuicPaddingFrame>& padding_frames() const { |
| return padding_frames_; |
| } |
| const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const { |
| return path_challenge_frames_; |
| } |
| const std::vector<QuicPathResponseFrame>& path_response_frames() const { |
| return path_response_frames_; |
| } |
| const QuicVersionNegotiationPacket* version_negotiation_packet() const { |
| return version_negotiation_packet_.get(); |
| } |
| EncryptionLevel last_decrypted_level() const { return last_decrypted_level_; } |
| const QuicEncryptedPacket* coalesced_packet() const { |
| return coalesced_packet_.get(); |
| } |
| |
| private: |
| QuicErrorCode error_; |
| bool has_header_; |
| QuicPacketHeader header_; |
| std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_; |
| std::unique_ptr<QuicPublicResetPacket> public_reset_packet_; |
| std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_; |
| std::vector<QuicAckFrame> ack_frames_; |
| std::vector<QuicStopWaitingFrame> stop_waiting_frames_; |
| std::vector<QuicPaddingFrame> padding_frames_; |
| std::vector<QuicPingFrame> ping_frames_; |
| std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_; |
| std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_; |
| std::vector<QuicRstStreamFrame> rst_stream_frames_; |
| std::vector<QuicGoAwayFrame> goaway_frames_; |
| std::vector<QuicStreamsBlockedFrame> streams_blocked_frames_; |
| std::vector<QuicMaxStreamsFrame> max_streams_frames_; |
| std::vector<QuicConnectionCloseFrame> connection_close_frames_; |
| std::vector<QuicStopSendingFrame> stop_sending_frames_; |
| std::vector<QuicPathChallengeFrame> path_challenge_frames_; |
| std::vector<QuicPathResponseFrame> path_response_frames_; |
| std::vector<QuicWindowUpdateFrame> window_update_frames_; |
| std::vector<QuicBlockedFrame> blocked_frames_; |
| std::vector<QuicNewConnectionIdFrame> new_connection_id_frames_; |
| std::vector<QuicRetireConnectionIdFrame> retire_connection_id_frames_; |
| std::vector<QuicNewTokenFrame> new_token_frames_; |
| std::vector<QuicMessageFrame> message_frames_; |
| std::vector<QuicHandshakeDoneFrame> handshake_done_frames_; |
| std::vector<QuicAckFrequencyFrame> ack_frequency_frames_; |
| std::vector<std::unique_ptr<std::string>> stream_data_; |
| std::vector<std::unique_ptr<std::string>> crypto_data_; |
| EncryptionLevel last_decrypted_level_; |
| std::unique_ptr<QuicEncryptedPacket> coalesced_packet_; |
| }; |
| |
| SimpleQuicFramer::SimpleQuicFramer() |
| : framer_(AllSupportedVersions(), QuicTime::Zero(), Perspective::IS_SERVER, |
| kQuicDefaultConnectionIdLength) {} |
| |
| SimpleQuicFramer::SimpleQuicFramer( |
| const ParsedQuicVersionVector& supported_versions) |
| : framer_(supported_versions, QuicTime::Zero(), Perspective::IS_SERVER, |
| kQuicDefaultConnectionIdLength) {} |
| |
| SimpleQuicFramer::SimpleQuicFramer( |
| const ParsedQuicVersionVector& supported_versions, Perspective perspective) |
| : framer_(supported_versions, QuicTime::Zero(), perspective, |
| kQuicDefaultConnectionIdLength) {} |
| |
| SimpleQuicFramer::~SimpleQuicFramer() {} |
| |
| bool SimpleQuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) { |
| visitor_ = std::make_unique<SimpleFramerVisitor>(); |
| framer_.set_visitor(visitor_.get()); |
| return framer_.ProcessPacket(packet); |
| } |
| |
| void SimpleQuicFramer::Reset() { |
| visitor_ = std::make_unique<SimpleFramerVisitor>(); |
| } |
| |
| const QuicPacketHeader& SimpleQuicFramer::header() const { |
| return visitor_->header(); |
| } |
| |
| const QuicVersionNegotiationPacket* |
| SimpleQuicFramer::version_negotiation_packet() const { |
| return visitor_->version_negotiation_packet(); |
| } |
| |
| EncryptionLevel SimpleQuicFramer::last_decrypted_level() const { |
| return visitor_->last_decrypted_level(); |
| } |
| |
| QuicFramer* SimpleQuicFramer::framer() { return &framer_; } |
| |
| size_t SimpleQuicFramer::num_frames() const { |
| return ack_frames().size() + goaway_frames().size() + |
| rst_stream_frames().size() + stop_waiting_frames().size() + |
| path_challenge_frames().size() + path_response_frames().size() + |
| stream_frames().size() + ping_frames().size() + |
| connection_close_frames().size() + padding_frames().size() + |
| crypto_frames().size(); |
| } |
| |
| const std::vector<QuicAckFrame>& SimpleQuicFramer::ack_frames() const { |
| return visitor_->ack_frames(); |
| } |
| |
| const std::vector<QuicStopWaitingFrame>& SimpleQuicFramer::stop_waiting_frames() |
| const { |
| return visitor_->stop_waiting_frames(); |
| } |
| |
| const std::vector<QuicPathChallengeFrame>& |
| SimpleQuicFramer::path_challenge_frames() const { |
| return visitor_->path_challenge_frames(); |
| } |
| const std::vector<QuicPathResponseFrame>& |
| SimpleQuicFramer::path_response_frames() const { |
| return visitor_->path_response_frames(); |
| } |
| |
| const std::vector<QuicPingFrame>& SimpleQuicFramer::ping_frames() const { |
| return visitor_->ping_frames(); |
| } |
| |
| const std::vector<QuicMessageFrame>& SimpleQuicFramer::message_frames() const { |
| return visitor_->message_frames(); |
| } |
| |
| const std::vector<QuicWindowUpdateFrame>& |
| SimpleQuicFramer::window_update_frames() const { |
| return visitor_->window_update_frames(); |
| } |
| |
| const std::vector<std::unique_ptr<QuicStreamFrame>>& |
| SimpleQuicFramer::stream_frames() const { |
| return visitor_->stream_frames(); |
| } |
| |
| const std::vector<std::unique_ptr<QuicCryptoFrame>>& |
| SimpleQuicFramer::crypto_frames() const { |
| return visitor_->crypto_frames(); |
| } |
| |
| const std::vector<QuicRstStreamFrame>& SimpleQuicFramer::rst_stream_frames() |
| const { |
| return visitor_->rst_stream_frames(); |
| } |
| |
| const std::vector<QuicGoAwayFrame>& SimpleQuicFramer::goaway_frames() const { |
| return visitor_->goaway_frames(); |
| } |
| |
| const std::vector<QuicConnectionCloseFrame>& |
| SimpleQuicFramer::connection_close_frames() const { |
| return visitor_->connection_close_frames(); |
| } |
| |
| const std::vector<QuicPaddingFrame>& SimpleQuicFramer::padding_frames() const { |
| return visitor_->padding_frames(); |
| } |
| |
| const QuicEncryptedPacket* SimpleQuicFramer::coalesced_packet() const { |
| return visitor_->coalesced_packet(); |
| } |
| |
| } // namespace test |
| } // namespace quic |