// 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 QUICHE_QUIC_CORE_QUIC_PACKETS_H_ #define QUICHE_QUIC_CORE_QUIC_PACKETS_H_ #include #include #include #include #include #include #include #include #include "net/third_party/quiche/src/quic/core/frames/quic_frame.h" #include "net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h" #include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" namespace quic { class QuicPacket; struct QuicPacketHeader; // Number of connection ID bytes that are actually included over the wire. QUIC_EXPORT_PRIVATE QuicConnectionIdLength GetIncludedConnectionIdLength(QuicConnectionId connection_id, QuicConnectionIdIncluded connection_id_included); // Number of destination connection ID bytes that are actually included over the // wire for this particular header. QUIC_EXPORT_PRIVATE QuicConnectionIdLength GetIncludedDestinationConnectionIdLength(const QuicPacketHeader& header); // Number of source connection ID bytes that are actually included over the // wire for this particular header. QUIC_EXPORT_PRIVATE QuicConnectionIdLength GetIncludedSourceConnectionIdLength(const QuicPacketHeader& header); // Size in bytes of the data packet header. QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version, const QuicPacketHeader& header); QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version, QuicConnectionIdLength destination_connection_id_length, QuicConnectionIdLength source_connection_id_length, bool include_version, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length, QuicVariableLengthIntegerLength retry_token_length_length, QuicByteCount retry_token_length, QuicVariableLengthIntegerLength length_length); // Index of the first byte in a QUIC packet of encrypted data. QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(QuicTransportVersion version, const QuicPacketHeader& header); QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData( QuicTransportVersion version, QuicConnectionIdLength destination_connection_id_length, QuicConnectionIdLength source_connection_id_length, bool include_version, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length, QuicVariableLengthIntegerLength retry_token_length_length, QuicByteCount retry_token_length, QuicVariableLengthIntegerLength length_length); struct QUIC_EXPORT_PRIVATE QuicPacketHeader { QuicPacketHeader(); QuicPacketHeader(const QuicPacketHeader& other); ~QuicPacketHeader(); QUIC_EXPORT_PRIVATE friend std::ostream& operator<<( std::ostream& os, const QuicPacketHeader& header); // Universal header. All QuicPacket headers will have a connection_id and // public flags. QuicConnectionId destination_connection_id; QuicConnectionIdIncluded destination_connection_id_included; QuicConnectionId source_connection_id; QuicConnectionIdIncluded source_connection_id_included; // This is only used for Google QUIC. bool reset_flag; // For Google QUIC, version flag in packets from the server means version // negotiation packet. For IETF QUIC, version flag means long header. bool version_flag; // Indicates whether |possible_stateless_reset_token| contains a valid value // parsed from the packet buffer. IETF QUIC only, always false for GQUIC. bool has_possible_stateless_reset_token; QuicPacketNumberLength packet_number_length; ParsedQuicVersion version; // nonce contains an optional, 32-byte nonce value. If not included in the // packet, |nonce| will be empty. DiversificationNonce* nonce; QuicPacketNumber packet_number; // Format of this header. PacketHeaderFormat form; // Short packet type is reflected in packet_number_length. QuicLongHeaderType long_packet_type; // Only valid if |has_possible_stateless_reset_token| is true. // Stores last 16 bytes of a this packet, used to check whether this packet is // a stateless reset packet on decryption failure. QuicUint128 possible_stateless_reset_token; // Length of the retry token length variable length integer field, // carried only by v99 IETF Initial packets. QuicVariableLengthIntegerLength retry_token_length_length; // Retry token, carried only by v99 IETF Initial packets. QuicStringPiece retry_token; // Length of the length variable length integer field, // carried only by v99 IETF Initial, 0-RTT and Handshake packets. QuicVariableLengthIntegerLength length_length; // Length of the packet number and payload, carried only by v99 IETF Initial, // 0-RTT and Handshake packets. Also includes the length of the // diversification nonce in server to client 0-RTT packets. QuicByteCount remaining_packet_length; }; struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket { QuicPublicResetPacket(); explicit QuicPublicResetPacket(QuicConnectionId connection_id); QuicConnectionId connection_id; QuicPublicResetNonceProof nonce_proof; QuicSocketAddress client_address; // An arbitrary string to identify an endpoint. Used by clients to // differentiate traffic from Google servers vs Non-google servers. // Will not be used if empty(). std::string endpoint_id; }; struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket { QuicVersionNegotiationPacket(); explicit QuicVersionNegotiationPacket(QuicConnectionId connection_id); QuicVersionNegotiationPacket(const QuicVersionNegotiationPacket& other); ~QuicVersionNegotiationPacket(); QuicConnectionId connection_id; ParsedQuicVersionVector versions; }; struct QUIC_EXPORT_PRIVATE QuicIetfStatelessResetPacket { QuicIetfStatelessResetPacket(); QuicIetfStatelessResetPacket(const QuicPacketHeader& header, QuicUint128 token); QuicIetfStatelessResetPacket(const QuicIetfStatelessResetPacket& other); ~QuicIetfStatelessResetPacket(); QuicPacketHeader header; QuicUint128 stateless_reset_token; }; class QUIC_EXPORT_PRIVATE QuicData { public: QuicData(const char* buffer, size_t length); QuicData(const char* buffer, size_t length, bool owns_buffer); QuicData(const QuicData&) = delete; QuicData& operator=(const QuicData&) = delete; virtual ~QuicData(); QuicStringPiece AsStringPiece() const { return QuicStringPiece(data(), length()); } const char* data() const { return buffer_; } size_t length() const { return length_; } private: const char* buffer_; size_t length_; bool owns_buffer_; }; class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData { public: QuicPacket(char* buffer, size_t length, bool owns_buffer, QuicConnectionIdLength destination_connection_id_length, QuicConnectionIdLength source_connection_id_length, bool includes_version, bool includes_diversification_nonce, QuicPacketNumberLength packet_number_length, QuicVariableLengthIntegerLength retry_token_length_length, QuicByteCount retry_token_length, QuicVariableLengthIntegerLength length_length); QuicPacket(QuicTransportVersion version, char* buffer, size_t length, bool owns_buffer, const QuicPacketHeader& header); QuicPacket(const QuicPacket&) = delete; QuicPacket& operator=(const QuicPacket&) = delete; QuicStringPiece AssociatedData(QuicTransportVersion version) const; QuicStringPiece Plaintext(QuicTransportVersion version) const; char* mutable_data() { return buffer_; } private: char* buffer_; const QuicConnectionIdLength destination_connection_id_length_; const QuicConnectionIdLength source_connection_id_length_; const bool includes_version_; const bool includes_diversification_nonce_; const QuicPacketNumberLength packet_number_length_; const QuicVariableLengthIntegerLength retry_token_length_length_; const QuicByteCount retry_token_length_; const QuicVariableLengthIntegerLength length_length_; }; class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData { public: QuicEncryptedPacket(const char* buffer, size_t length); QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer); QuicEncryptedPacket(const QuicEncryptedPacket&) = delete; QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete; // Clones the packet into a new packet which owns the buffer. std::unique_ptr Clone() const; // By default, gtest prints the raw bytes of an object. The bool data // member (in the base class QuicData) causes this object to have padding // bytes, which causes the default gtest object printer to read // uninitialize memory. So we need to teach gtest how to print this object. QUIC_EXPORT_PRIVATE friend std::ostream& operator<<( std::ostream& os, const QuicEncryptedPacket& s); }; // A received encrypted QUIC packet, with a recorded time of receipt. class QUIC_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket { public: QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time); QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time, bool owns_buffer); QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time, bool owns_buffer, int ttl, bool ttl_valid); QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time, bool owns_buffer, int ttl, bool ttl_valid, char* packet_headers, size_t headers_length, bool owns_header_buffer); ~QuicReceivedPacket(); QuicReceivedPacket(const QuicReceivedPacket&) = delete; QuicReceivedPacket& operator=(const QuicReceivedPacket&) = delete; // Clones the packet into a new packet which owns the buffer. std::unique_ptr Clone() const; // Returns the time at which the packet was received. QuicTime receipt_time() const { return receipt_time_; } // This is the TTL of the packet, assuming ttl_vaild_ is true. int ttl() const { return ttl_; } // Start of packet headers. char* packet_headers() const { return packet_headers_; } // Length of packet headers. int headers_length() const { return headers_length_; } // By default, gtest prints the raw bytes of an object. The bool data // member (in the base class QuicData) causes this object to have padding // bytes, which causes the default gtest object printer to read // uninitialize memory. So we need to teach gtest how to print this object. QUIC_EXPORT_PRIVATE friend std::ostream& operator<<( std::ostream& os, const QuicReceivedPacket& s); private: const QuicTime receipt_time_; int ttl_; // Points to the start of packet headers. char* packet_headers_; // Length of packet headers. int headers_length_; // Whether owns the buffer for packet headers. bool owns_header_buffer_; }; struct QUIC_EXPORT_PRIVATE SerializedPacket { SerializedPacket(QuicPacketNumber packet_number, QuicPacketNumberLength packet_number_length, const char* encrypted_buffer, QuicPacketLength encrypted_length, bool has_ack, bool has_stop_waiting); SerializedPacket(const SerializedPacket& other); SerializedPacket& operator=(const SerializedPacket& other); SerializedPacket(SerializedPacket&& other); ~SerializedPacket(); // Not owned. const char* encrypted_buffer; QuicPacketLength encrypted_length; QuicFrames retransmittable_frames; IsHandshake has_crypto_handshake; // -1: full padding to the end of a max-sized packet // 0: no padding // otherwise: only pad up to num_padding_bytes bytes int16_t num_padding_bytes; QuicPacketNumber packet_number; QuicPacketNumberLength packet_number_length; EncryptionLevel encryption_level; bool has_ack; bool has_stop_waiting; TransmissionType transmission_type; QuicPacketNumber original_packet_number; // The largest acked of the AckFrame in this packet if has_ack is true, // 0 otherwise. QuicPacketNumber largest_acked; }; // Deletes and clears all the frames and the packet from serialized packet. QUIC_EXPORT_PRIVATE void ClearSerializedPacket( SerializedPacket* serialized_packet); // Allocates a new char[] of size |packet.encrypted_length| and copies in // |packet.encrypted_buffer|. QUIC_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet); struct QUIC_EXPORT_PRIVATE SerializedPacketDeleter { void operator()(SerializedPacket* packet) { if (packet->encrypted_buffer != nullptr) { delete[] packet->encrypted_buffer; } delete packet; } }; // On destruction, OwningSerializedPacketPointer deletes a packet's (on-heap) // encrypted_buffer before deleting the (also on-heap) packet itself. // TODO(wub): Maybe delete retransmittable_frames too? typedef std::unique_ptr OwningSerializedPacketPointer; // Context for an incoming packet. struct QUIC_EXPORT_PRIVATE QuicPerPacketContext { virtual ~QuicPerPacketContext() {} }; } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_PACKETS_H_