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 11 #include "absl/types/optional.h" 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 QUIC_EXPORT_PRIVATE QuicChaosProtector 30 : public QuicStreamFrameDataProducer { 31 public: 32 // |framer| and |random| must be valid for the lifetime of QuicChaosProtector. 33 explicit QuicChaosProtector(const QuicCryptoFrame& crypto_frame, 34 int num_padding_bytes, size_t packet_size, 35 QuicFramer* framer, QuicRandom* random); 36 37 ~QuicChaosProtector() override; 38 39 QuicChaosProtector(const QuicChaosProtector&) = delete; 40 QuicChaosProtector(QuicChaosProtector&&) = delete; 41 QuicChaosProtector& operator=(const QuicChaosProtector&) = delete; 42 QuicChaosProtector& operator=(QuicChaosProtector&&) = delete; 43 44 // Attempts to build a data packet with chaos protection. If an error occurs, 45 // then absl::nullopt is returned. Otherwise returns the serialized length. 46 absl::optional<size_t> BuildDataPacket(const QuicPacketHeader& header, 47 char* buffer); 48 49 // From QuicStreamFrameDataProducer. 50 WriteStreamDataResult WriteStreamData(QuicStreamId id, 51 QuicStreamOffset offset, 52 QuicByteCount data_length, 53 QuicDataWriter* /*writer*/) override; 54 bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset, 55 QuicByteCount data_length, 56 QuicDataWriter* writer) override; 57 58 private: 59 friend class test::QuicChaosProtectorTest; 60 61 // Allocate the crypto data buffer, create the CRYPTO frame and write the 62 // crypto data to our buffer. 63 bool CopyCryptoDataToLocalBuffer(); 64 65 // Split the CRYPTO frame in |frames_| into one or more CRYPTO frames that 66 // collectively represent the same data. Adjusts padding to compensate. 67 void SplitCryptoFrame(); 68 69 // Add a random number of PING frames to |frames_| and adjust padding. 70 void AddPingFrames(); 71 72 // Randomly reorder |frames_|. 73 void ReorderFrames(); 74 75 // Add PADDING frames randomly between all other frames. 76 void SpreadPadding(); 77 78 // Serialize |frames_| using |framer_|. 79 absl::optional<size_t> BuildPacket(const QuicPacketHeader& header, 80 char* buffer); 81 82 size_t packet_size_; 83 std::unique_ptr<char[]> crypto_frame_buffer_; 84 const char* crypto_data_buffer_ = nullptr; 85 QuicByteCount crypto_data_length_; 86 QuicStreamOffset crypto_buffer_offset_; 87 EncryptionLevel level_; 88 int remaining_padding_bytes_; 89 QuicFrames frames_; // Inner frames owned, will be deleted by destructor. 90 QuicFramer* framer_; // Unowned. 91 QuicRandom* random_; // Unowned. 92 }; 93 94 } // namespace quic 95 96 #endif // QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_ 97