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