xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_chaos_protector.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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