1 // Copyright (c) 2021 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_ 6 #define QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_ 7 8 #include <cstddef> 9 #include <memory> 10 #include <optional> 11 12 #include "quiche/quic/core/crypto/quic_random.h" 13 #include "quiche/quic/core/frames/quic_crypto_frame.h" 14 #include "quiche/quic/core/frames/quic_frame.h" 15 #include "quiche/quic/core/quic_data_writer.h" 16 #include "quiche/quic/core/quic_framer.h" 17 #include "quiche/quic/core/quic_packets.h" 18 #include "quiche/quic/core/quic_stream_frame_data_producer.h" 19 #include "quiche/quic/core/quic_types.h" 20 21 namespace quic { 22 23 namespace test { 24 class QuicChaosProtectorTest; 25 } 26 27 // QuicChaosProtector will take a crypto frame and an amount of padding and 28 // build a data packet that will parse to something equivalent. 29 class QUICHE_EXPORT QuicChaosProtector : public QuicStreamFrameDataProducer { 30 public: 31 // |framer| and |random| must be valid for the lifetime of QuicChaosProtector. 32 explicit QuicChaosProtector(const QuicCryptoFrame& crypto_frame, 33 int num_padding_bytes, size_t packet_size, 34 QuicFramer* framer, QuicRandom* random); 35 36 ~QuicChaosProtector() override; 37 38 QuicChaosProtector(const QuicChaosProtector&) = delete; 39 QuicChaosProtector(QuicChaosProtector&&) = delete; 40 QuicChaosProtector& operator=(const QuicChaosProtector&) = delete; 41 QuicChaosProtector& operator=(QuicChaosProtector&&) = delete; 42 43 // Attempts to build a data packet with chaos protection. If an error occurs, 44 // then std::nullopt is returned. Otherwise returns the serialized length. 45 std::optional<size_t> BuildDataPacket(const QuicPacketHeader& header, 46 char* buffer); 47 48 // From QuicStreamFrameDataProducer. 49 WriteStreamDataResult WriteStreamData(QuicStreamId id, 50 QuicStreamOffset offset, 51 QuicByteCount data_length, 52 QuicDataWriter* /*writer*/) override; 53 bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset, 54 QuicByteCount data_length, 55 QuicDataWriter* writer) override; 56 57 private: 58 friend class test::QuicChaosProtectorTest; 59 60 // Allocate the crypto data buffer, create the CRYPTO frame and write the 61 // crypto data to our buffer. 62 bool CopyCryptoDataToLocalBuffer(); 63 64 // Split the CRYPTO frame in |frames_| into one or more CRYPTO frames that 65 // collectively represent the same data. Adjusts padding to compensate. 66 void SplitCryptoFrame(); 67 68 // Add a random number of PING frames to |frames_| and adjust padding. 69 void AddPingFrames(); 70 71 // Randomly reorder |frames_|. 72 void ReorderFrames(); 73 74 // Add PADDING frames randomly between all other frames. 75 void SpreadPadding(); 76 77 // Serialize |frames_| using |framer_|. 78 std::optional<size_t> BuildPacket(const QuicPacketHeader& header, 79 char* buffer); 80 81 size_t packet_size_; 82 std::unique_ptr<char[]> crypto_frame_buffer_; 83 const char* crypto_data_buffer_ = nullptr; 84 QuicByteCount crypto_data_length_; 85 QuicStreamOffset crypto_buffer_offset_; 86 EncryptionLevel level_; 87 int remaining_padding_bytes_; 88 QuicFrames frames_; // Inner frames owned, will be deleted by destructor. 89 QuicFramer* framer_; // Unowned. 90 QuicRandom* random_; // Unowned. 91 }; 92 93 } // namespace quic 94 95 #endif // QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_ 96