| // 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 "quic/test_tools/simple_quic_framer.h" | 
 |  | 
 | #include <memory> | 
 | #include <utility> | 
 |  | 
 | #include "absl/memory/memory.h" | 
 | #include "absl/strings/string_view.h" | 
 | #include "quic/core/crypto/quic_decrypter.h" | 
 | #include "quic/core/crypto/quic_encrypter.h" | 
 | #include "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; | 
 |   } | 
 |  | 
 |   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 |