|  | // 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 "net/quic/test_tools/simple_quic_framer.h" | 
|  |  | 
|  | #include "base/stl_util.h" | 
|  | #include "net/quic/crypto/crypto_framer.h" | 
|  | #include "net/quic/crypto/quic_decrypter.h" | 
|  | #include "net/quic/crypto/quic_encrypter.h" | 
|  |  | 
|  | using base::StringPiece; | 
|  | using std::string; | 
|  | using std::vector; | 
|  |  | 
|  | namespace net { | 
|  | namespace test { | 
|  |  | 
|  | class SimpleFramerVisitor : public QuicFramerVisitorInterface { | 
|  | public: | 
|  | SimpleFramerVisitor() | 
|  | : error_(QUIC_NO_ERROR) { | 
|  | } | 
|  |  | 
|  | ~SimpleFramerVisitor() override { STLDeleteElements(&stream_data_); } | 
|  |  | 
|  | void OnError(QuicFramer* framer) override { error_ = framer->error(); } | 
|  |  | 
|  | bool OnProtocolVersionMismatch(QuicVersion version) override { return false; } | 
|  |  | 
|  | void OnPacket() override {} | 
|  | void OnPublicResetPacket(const QuicPublicResetPacket& packet) override { | 
|  | public_reset_packet_.reset(new QuicPublicResetPacket(packet)); | 
|  | } | 
|  | void OnVersionNegotiationPacket( | 
|  | const QuicVersionNegotiationPacket& packet) override { | 
|  | version_negotiation_packet_.reset( | 
|  | new QuicVersionNegotiationPacket(packet)); | 
|  | } | 
|  | void OnRevivedPacket() override {} | 
|  |  | 
|  | bool OnUnauthenticatedPublicHeader( | 
|  | const QuicPacketPublicHeader& header) override { | 
|  | return true; | 
|  | } | 
|  | bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override { | 
|  | return true; | 
|  | } | 
|  | void OnDecryptedPacket(EncryptionLevel level) override {} | 
|  | bool OnPacketHeader(const QuicPacketHeader& header) override { | 
|  | has_header_ = true; | 
|  | header_ = header; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void OnFecProtectedPayload(StringPiece payload) override {} | 
|  |  | 
|  | bool OnStreamFrame(const QuicStreamFrame& frame) override { | 
|  | // Save a copy of the data so it is valid after the packet is processed. | 
|  | stream_data_.push_back(frame.GetDataAsString()); | 
|  | QuicStreamFrame stream_frame(frame); | 
|  | // Make sure that the stream frame points to this data. | 
|  | stream_frame.data.Clear(); | 
|  | stream_frame.data.Append(const_cast<char*>(stream_data_.back()->data()), | 
|  | stream_data_.back()->size()); | 
|  | stream_frames_.push_back(stream_frame); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool OnAckFrame(const QuicAckFrame& frame) override { | 
|  | ack_frames_.push_back(frame); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override { | 
|  | stop_waiting_frames_.push_back(frame); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool OnPingFrame(const QuicPingFrame& frame) override { | 
|  | ping_frames_.push_back(frame); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void OnFecData(const QuicFecData& fec) override { | 
|  | fec_data_ = fec; | 
|  | fec_redundancy_ = fec_data_.redundancy.as_string(); | 
|  | fec_data_.redundancy = fec_redundancy_; | 
|  | } | 
|  |  | 
|  | 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 OnGoAwayFrame(const QuicGoAwayFrame& frame) override { | 
|  | goaway_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; | 
|  | } | 
|  |  | 
|  | void OnPacketComplete() override {} | 
|  |  | 
|  | const QuicPacketHeader& header() const { return header_; } | 
|  | const vector<QuicAckFrame>& ack_frames() const { return ack_frames_; } | 
|  | const vector<QuicConnectionCloseFrame>& connection_close_frames() const { | 
|  | return connection_close_frames_; | 
|  | } | 
|  | const vector<QuicGoAwayFrame>& goaway_frames() const { | 
|  | return goaway_frames_; | 
|  | } | 
|  | const vector<QuicRstStreamFrame>& rst_stream_frames() const { | 
|  | return rst_stream_frames_; | 
|  | } | 
|  | const vector<QuicStreamFrame>& stream_frames() const { | 
|  | return stream_frames_; | 
|  | } | 
|  | const vector<QuicStopWaitingFrame>& stop_waiting_frames() const { | 
|  | return stop_waiting_frames_; | 
|  | } | 
|  | const vector<QuicPingFrame>& ping_frames() const { | 
|  | return ping_frames_; | 
|  | } | 
|  | const QuicFecData& fec_data() const { | 
|  | return fec_data_; | 
|  | } | 
|  | const QuicVersionNegotiationPacket* version_negotiation_packet() const { | 
|  | return version_negotiation_packet_.get(); | 
|  | } | 
|  | const QuicPublicResetPacket* public_reset_packet() const { | 
|  | return public_reset_packet_.get(); | 
|  | } | 
|  |  | 
|  | private: | 
|  | QuicErrorCode error_; | 
|  | bool has_header_; | 
|  | QuicPacketHeader header_; | 
|  | QuicFecData fec_data_; | 
|  | scoped_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_; | 
|  | scoped_ptr<QuicPublicResetPacket> public_reset_packet_; | 
|  | string fec_redundancy_; | 
|  | vector<QuicAckFrame> ack_frames_; | 
|  | vector<QuicStopWaitingFrame> stop_waiting_frames_; | 
|  | vector<QuicPingFrame> ping_frames_; | 
|  | vector<QuicStreamFrame> stream_frames_; | 
|  | vector<QuicRstStreamFrame> rst_stream_frames_; | 
|  | vector<QuicGoAwayFrame> goaway_frames_; | 
|  | vector<QuicConnectionCloseFrame> connection_close_frames_; | 
|  | vector<QuicWindowUpdateFrame> window_update_frames_; | 
|  | vector<QuicBlockedFrame> blocked_frames_; | 
|  | vector<string*> stream_data_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(SimpleFramerVisitor); | 
|  | }; | 
|  |  | 
|  | SimpleQuicFramer::SimpleQuicFramer() | 
|  | : framer_(QuicSupportedVersions(), QuicTime::Zero(), true) { | 
|  | } | 
|  |  | 
|  | SimpleQuicFramer::SimpleQuicFramer(const QuicVersionVector& supported_versions) | 
|  | : framer_(supported_versions, QuicTime::Zero(), true) { | 
|  | } | 
|  |  | 
|  | SimpleQuicFramer::~SimpleQuicFramer() { | 
|  | } | 
|  |  | 
|  | bool SimpleQuicFramer::ProcessPacket(const QuicPacket& packet) { | 
|  | scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket( | 
|  | ENCRYPTION_NONE, 0, packet)); | 
|  | return ProcessPacket(*encrypted); | 
|  | } | 
|  |  | 
|  | bool SimpleQuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) { | 
|  | visitor_.reset(new SimpleFramerVisitor); | 
|  | framer_.set_visitor(visitor_.get()); | 
|  | return framer_.ProcessPacket(packet); | 
|  | } | 
|  |  | 
|  | void SimpleQuicFramer::Reset() { | 
|  | visitor_.reset(new SimpleFramerVisitor); | 
|  | } | 
|  |  | 
|  |  | 
|  | const QuicPacketHeader& SimpleQuicFramer::header() const { | 
|  | return visitor_->header(); | 
|  | } | 
|  |  | 
|  | const QuicFecData& SimpleQuicFramer::fec_data() const { | 
|  | return visitor_->fec_data(); | 
|  | } | 
|  |  | 
|  | const QuicVersionNegotiationPacket* | 
|  | SimpleQuicFramer::version_negotiation_packet() const { | 
|  | return visitor_->version_negotiation_packet(); | 
|  | } | 
|  |  | 
|  | const QuicPublicResetPacket* SimpleQuicFramer::public_reset_packet() const { | 
|  | return visitor_->public_reset_packet(); | 
|  | } | 
|  |  | 
|  | 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() + | 
|  | stream_frames().size() + | 
|  | ping_frames().size() + | 
|  | connection_close_frames().size(); | 
|  | } | 
|  |  | 
|  | const vector<QuicAckFrame>& SimpleQuicFramer::ack_frames() const { | 
|  | return visitor_->ack_frames(); | 
|  | } | 
|  |  | 
|  | const vector<QuicStopWaitingFrame>& | 
|  | SimpleQuicFramer::stop_waiting_frames() const { | 
|  | return visitor_->stop_waiting_frames(); | 
|  | } | 
|  |  | 
|  | const vector<QuicPingFrame>& SimpleQuicFramer::ping_frames() const { | 
|  | return visitor_->ping_frames(); | 
|  | } | 
|  |  | 
|  | const vector<QuicStreamFrame>& SimpleQuicFramer::stream_frames() const { | 
|  | return visitor_->stream_frames(); | 
|  | } | 
|  |  | 
|  | const vector<QuicRstStreamFrame>& SimpleQuicFramer::rst_stream_frames() const { | 
|  | return visitor_->rst_stream_frames(); | 
|  | } | 
|  |  | 
|  | const vector<QuicGoAwayFrame>& | 
|  | SimpleQuicFramer::goaway_frames() const { | 
|  | return visitor_->goaway_frames(); | 
|  | } | 
|  |  | 
|  | const vector<QuicConnectionCloseFrame>& | 
|  | SimpleQuicFramer::connection_close_frames() const { | 
|  | return visitor_->connection_close_frames(); | 
|  | } | 
|  |  | 
|  | }  // namespace test | 
|  | }  // namespace net |