• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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