// 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. #ifndef NET_QUIC_QUIC_FRAMER_H_ #define NET_QUIC_QUIC_FRAMER_H_ #include #include "base/basictypes.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/string_piece.h" #include "net/base/ip_endpoint.h" #include "net/base/net_export.h" #include "net/quic/crypto/quic_decrypter.h" #include "net/quic/crypto/quic_encrypter.h" namespace net { class QuicEncrypter; class QuicDecrypter; class QuicFramer; class QuicDataReader; class QuicDataWriter; // Class that receives callbacks from the framer when packets // are processed. class NET_EXPORT_PRIVATE QuicFramerVisitorInterface { public: virtual ~QuicFramerVisitorInterface() {} // Called if an error is detected in the QUIC protocol. virtual void OnError(QuicFramer* framer) = 0; // Called when a new packet has been recieved, before it // has been validated or processed. virtual void OnPacket(const IPEndPoint& peer_address) = 0; // Called when the header of a packet had been parsed. // If OnPacketHeader returns false, framing for this packet will cease. virtual bool OnPacketHeader(const QuicPacketHeader& header) = 0; // Called when a data packet is parsed that is part of an FEC group. // |payload| is the non-encrypted FEC protected payload of the packet. virtual void OnFecProtectedPayload(base::StringPiece payload) = 0; // Called when a StreamFragment has been parsed. virtual void OnStreamFragment(const QuicStreamFragment& fragment) = 0; // Called when a AckFragment has been parsed. virtual void OnAckFragment(const QuicAckFragment& fragment) = 0; // Called when a RstStreamFragment has been parsed. virtual void OnRstStreamFragment( const QuicRstStreamFragment& fragment) = 0; // Called when a ConnectionCloseFragment has been parsed. virtual void OnConnectionCloseFragment( const QuicConnectionCloseFragment& fragment) = 0; // Called when FEC data has been parsed. virtual void OnFecData(const QuicFecData& fec) = 0; // Called when a packet has been completely processed. virtual void OnPacketComplete() = 0; }; class NET_EXPORT_PRIVATE QuicFecBuilderInterface { public: virtual ~QuicFecBuilderInterface() {} // Called when a data packet is constructed that is part of an FEC group. // |payload| is the non-encrypted FEC protected payload of the packet. virtual void OnBuiltFecProtectedPayload(const QuicPacketHeader& header, base::StringPiece payload) = 0; }; // Class for parsing and constructing QUIC packets. Has a // QuicFramerVisitorInterface that is called when packets are parsed. // Also has a QuicFecBuilder that is called when packets are constructed // in order to generate FEC data for subsequently building FEC packets. class NET_EXPORT_PRIVATE QuicFramer { public: // Constructs a new framer that will own |decrypter| and |encrypter|. QuicFramer(QuicDecrypter* decrypter, QuicEncrypter* encrypter); virtual ~QuicFramer(); // Set callbacks to be called from the framer. A visitor must be set, or // else the framer will likely crash. It is acceptable for the visitor // to do nothing. If this is called multiple times, only the last visitor // will be used. void set_visitor(QuicFramerVisitorInterface* visitor) { visitor_ = visitor; } // Set a builder to be called from the framer when building FEC protected // packets. If this is called multiple times, only the last builder // will be used. The builder need not be set. void set_fec_builder(QuicFecBuilderInterface* builder) { fec_builder_ = builder; } QuicErrorCode error() const { return error_; } // Pass a UDP packet into the framer for parsing. // Return true if the packet was processed succesfully. |packet| must be a // single, complete UDP packet (not a fragment of a packet). This packet // might be null padded past the end of the payload, which will be correctly // ignored. bool ProcessPacket(const IPEndPoint& client_address, const QuicEncryptedPacket& packet); // Pass a data packet that was revived from FEC data into the framer // for parsing. // Return true if the packet was processed succesfully. |payload| must be // the complete DECRYPTED payload of the revived packet. bool ProcessRevivedPacket(const IPEndPoint& client_address, const QuicPacketHeader& header, base::StringPiece payload); // Creates a new QuicPacket populated with the fields in |header| and // |fragments|. Assigns |*packet| to the address of the new object. // Returns true upon success. bool ConstructFragementDataPacket(const QuicPacketHeader& header, const QuicFragments& fragments, QuicPacket** packet); // Creates a new QuicPacket populated with the fields in |header| and // |fec|. Assigns |*packet| to the address of the new object. // Returns true upon success. bool ConstructFecPacket(const QuicPacketHeader& header, const QuicFecData& fec, QuicPacket** packet); // Increments the retransmission count by one, and updates the authentication // hash accordingly. void IncrementRetransmitCount(QuicPacket* packet); uint8 GetRetransmitCount(QuicPacket* packet); void WriteTransmissionTime(QuicTransmissionTime time, QuicPacket* packet); // Returns a new encrypted packet, owned by the caller. QuicEncryptedPacket* EncryptPacket(const QuicPacket& packet); // Returns the maximum length of plaintext that can be encrypted // to ciphertext no larger than |ciphertext_size|. size_t GetMaxPlaintextSize(size_t ciphertext_size); const std::string& detailed_error() { return detailed_error_; } private: bool WritePacketHeader(const QuicPacketHeader& header, QuicDataWriter* builder); bool ProcessPacketHeader(QuicPacketHeader* header, const QuicEncryptedPacket& packet); bool ProcessFragmentData(); bool ProcessStreamFragment(); bool ProcessPDUFragment(); bool ProcessAckFragment(QuicAckFragment* fragment); bool ProcessRstStreamFragment(); bool ProcessConnectionCloseFragment(); bool DecryptPayload(const QuicEncryptedPacket& packet); // Computes the wire size in bytes of the payload of |fragment|. size_t ComputeFragmentPayloadLength(const QuicFragment& fragment); bool AppendStreamFragmentPayload( const QuicStreamFragment& fragment, QuicDataWriter* builder); bool AppendAckFragmentPayload( const QuicAckFragment& fragment, QuicDataWriter* builder); bool AppendRstStreamFragmentPayload( const QuicRstStreamFragment& fragment, QuicDataWriter* builder); bool AppendConnectionCloseFragmentPayload( const QuicConnectionCloseFragment& fragment, QuicDataWriter* builder); bool RaiseError(QuicErrorCode error); void set_error(QuicErrorCode error) { error_ = error; } void set_detailed_error(const char* error) { detailed_error_ = error; } std::string detailed_error_; scoped_ptr reader_; QuicFramerVisitorInterface* visitor_; QuicFecBuilderInterface* fec_builder_; QuicErrorCode error_; // Buffer containing decrypted payload data during parsing. scoped_ptr decrypted_; // Decrypter used to decrypt packets during parsing. scoped_ptr decrypter_; // Encrypter used to encrypt packets via EncryptPacket(). scoped_ptr encrypter_; DISALLOW_COPY_AND_ASSIGN(QuicFramer); }; } // namespace net #endif // NET_QUIC_QUIC_FRAMER_H_