summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packets.h
blob: 5246f43eaaf79a6791e96aa4c9286d461b3a5c58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_QUIC_PACKETS_H_
#define QUICHE_QUIC_CORE_QUIC_PACKETS_H_

#include <cstddef>
#include <cstdint>
#include <memory>
#include <ostream>
#include <string>
#include <utility>

#include "absl/strings/string_view.h"
#include "quiche/quic/core/frames/quic_frame.h"
#include "quiche/quic/core/quic_ack_listener_interface.h"
#include "quiche/quic/core/quic_bandwidth.h"
#include "quiche/quic/core/quic_constants.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_socket_address.h"

namespace quic {

class QuicPacket;
struct QuicPacketHeader;

// Returns the destination connection ID of |header| when |perspective| is
// server, and the source connection ID when |perspective| is client.
QUIC_EXPORT_PRIVATE QuicConnectionId GetServerConnectionIdAsRecipient(
    const QuicPacketHeader& header, Perspective perspective);

// Returns the destination connection ID of |header| when |perspective| is
// client, and the source connection ID when |perspective| is server.
QUIC_EXPORT_PRIVATE QuicConnectionId GetClientConnectionIdAsRecipient(
    const QuicPacketHeader& header, Perspective perspective);

// Returns the destination connection ID of |header| when |perspective| is
// client, and the source connection ID when |perspective| is server.
QUIC_EXPORT_PRIVATE QuicConnectionId GetServerConnectionIdAsSender(
    const QuicPacketHeader& header, Perspective perspective);

// Returns the destination connection ID included of |header| when |perspective|
// is client, and the source connection ID included when |perspective| is
// server.
QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
GetServerConnectionIdIncludedAsSender(const QuicPacketHeader& header,
                                      Perspective perspective);

// Returns the destination connection ID of |header| when |perspective| is
// server, and the source connection ID when |perspective| is client.
QUIC_EXPORT_PRIVATE QuicConnectionId GetClientConnectionIdAsSender(
    const QuicPacketHeader& header, Perspective perspective);

// Returns the destination connection ID included of |header| when |perspective|
// is server, and the source connection ID included when |perspective| is
// client.
QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
GetClientConnectionIdIncludedAsSender(const QuicPacketHeader& header,
                                      Perspective perspective);

// Number of connection ID bytes that are actually included over the wire.
QUIC_EXPORT_PRIVATE QuicConnectionIdLength
GetIncludedConnectionIdLength(QuicConnectionId connection_id,
                              QuicConnectionIdIncluded connection_id_included);

// Number of destination connection ID bytes that are actually included over the
// wire for this particular header.
QUIC_EXPORT_PRIVATE QuicConnectionIdLength
GetIncludedDestinationConnectionIdLength(const QuicPacketHeader& header);

// Number of source connection ID bytes that are actually included over the
// wire for this particular header.
QUIC_EXPORT_PRIVATE QuicConnectionIdLength
GetIncludedSourceConnectionIdLength(const QuicPacketHeader& header);

// Size in bytes of the data packet header.
QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version,
                                               const QuicPacketHeader& header);

QUIC_EXPORT_PRIVATE size_t
GetPacketHeaderSize(QuicTransportVersion version,
                    QuicConnectionIdLength destination_connection_id_length,
                    QuicConnectionIdLength source_connection_id_length,
                    bool include_version, bool include_diversification_nonce,
                    QuicPacketNumberLength packet_number_length,
                    QuicVariableLengthIntegerLength retry_token_length_length,
                    QuicByteCount retry_token_length,
                    QuicVariableLengthIntegerLength length_length);

// Index of the first byte in a QUIC packet of encrypted data.
QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(
    QuicTransportVersion version, const QuicPacketHeader& header);

QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(
    QuicTransportVersion version,
    QuicConnectionIdLength destination_connection_id_length,
    QuicConnectionIdLength source_connection_id_length, bool include_version,
    bool include_diversification_nonce,
    QuicPacketNumberLength packet_number_length,
    QuicVariableLengthIntegerLength retry_token_length_length,
    QuicByteCount retry_token_length,
    QuicVariableLengthIntegerLength length_length);

struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
  QuicPacketHeader();
  QuicPacketHeader(const QuicPacketHeader& other);
  ~QuicPacketHeader();

  QuicPacketHeader& operator=(const QuicPacketHeader& other);

  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
      std::ostream& os, const QuicPacketHeader& header);

  // Universal header. All QuicPacket headers will have a connection_id and
  // public flags.
  QuicConnectionId destination_connection_id;
  QuicConnectionIdIncluded destination_connection_id_included;
  QuicConnectionId source_connection_id;
  QuicConnectionIdIncluded source_connection_id_included;
  // This is only used for Google QUIC.
  bool reset_flag;
  // For Google QUIC, version flag in packets from the server means version
  // negotiation packet. For IETF QUIC, version flag means long header.
  bool version_flag;
  // Indicates whether |possible_stateless_reset_token| contains a valid value
  // parsed from the packet buffer. IETF QUIC only, always false for GQUIC.
  bool has_possible_stateless_reset_token;
  QuicPacketNumberLength packet_number_length;
  uint8_t type_byte;
  ParsedQuicVersion version;
  // nonce contains an optional, 32-byte nonce value. If not included in the
  // packet, |nonce| will be empty.
  DiversificationNonce* nonce;
  QuicPacketNumber packet_number;
  // Format of this header.
  PacketHeaderFormat form;
  // Short packet type is reflected in packet_number_length.
  QuicLongHeaderType long_packet_type;
  // Only valid if |has_possible_stateless_reset_token| is true.
  // Stores last 16 bytes of a this packet, used to check whether this packet is
  // a stateless reset packet on decryption failure.
  StatelessResetToken possible_stateless_reset_token;
  // Length of the retry token length variable length integer field,
  // carried only by v99 IETF Initial packets.
  QuicVariableLengthIntegerLength retry_token_length_length;
  // Retry token, carried only by v99 IETF Initial packets.
  absl::string_view retry_token;
  // Length of the length variable length integer field,
  // carried only by v99 IETF Initial, 0-RTT and Handshake packets.
  QuicVariableLengthIntegerLength length_length;
  // Length of the packet number and payload, carried only by v99 IETF Initial,
  // 0-RTT and Handshake packets. Also includes the length of the
  // diversification nonce in server to client 0-RTT packets.
  QuicByteCount remaining_packet_length;
};

struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket {
  QuicPublicResetPacket();
  explicit QuicPublicResetPacket(QuicConnectionId connection_id);

  QuicConnectionId connection_id;
  QuicPublicResetNonceProof nonce_proof;
  QuicSocketAddress client_address;
  // An arbitrary string to identify an endpoint. Used by clients to
  // differentiate traffic from Google servers vs Non-google servers.
  // Will not be used if empty().
  std::string endpoint_id;
};

struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket {
  QuicVersionNegotiationPacket();
  explicit QuicVersionNegotiationPacket(QuicConnectionId connection_id);
  QuicVersionNegotiationPacket(const QuicVersionNegotiationPacket& other);
  ~QuicVersionNegotiationPacket();

  QuicConnectionId connection_id;
  ParsedQuicVersionVector versions;
};

struct QUIC_EXPORT_PRIVATE QuicIetfStatelessResetPacket {
  QuicIetfStatelessResetPacket();
  QuicIetfStatelessResetPacket(const QuicPacketHeader& header,
                               StatelessResetToken token);
  QuicIetfStatelessResetPacket(const QuicIetfStatelessResetPacket& other);
  ~QuicIetfStatelessResetPacket();

  QuicPacketHeader header;
  StatelessResetToken stateless_reset_token;
};

class QUIC_EXPORT_PRIVATE QuicData {
 public:
  // Creates a QuicData from a buffer and length. Does not own the buffer.
  QuicData(const char* buffer, size_t length);
  // Creates a QuicData from a buffer and length,
  // optionally taking ownership of the buffer.
  QuicData(const char* buffer, size_t length, bool owns_buffer);
  // Creates a QuicData from a absl::string_view. Does not own the
  // buffer.
  QuicData(absl::string_view data);
  QuicData(const QuicData&) = delete;
  QuicData& operator=(const QuicData&) = delete;
  virtual ~QuicData();

  absl::string_view AsStringPiece() const {
    return absl::string_view(data(), length());
  }

  const char* data() const { return buffer_; }
  size_t length() const { return length_; }

 private:
  const char* buffer_;
  size_t length_;
  bool owns_buffer_;
};

class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData {
 public:
  QuicPacket(char* buffer, size_t length, bool owns_buffer,
             QuicConnectionIdLength destination_connection_id_length,
             QuicConnectionIdLength source_connection_id_length,
             bool includes_version, bool includes_diversification_nonce,
             QuicPacketNumberLength packet_number_length,
             QuicVariableLengthIntegerLength retry_token_length_length,
             QuicByteCount retry_token_length,
             QuicVariableLengthIntegerLength length_length);
  QuicPacket(QuicTransportVersion version, char* buffer, size_t length,
             bool owns_buffer, const QuicPacketHeader& header);
  QuicPacket(const QuicPacket&) = delete;
  QuicPacket& operator=(const QuicPacket&) = delete;

  absl::string_view AssociatedData(QuicTransportVersion version) const;
  absl::string_view Plaintext(QuicTransportVersion version) const;

  char* mutable_data() { return buffer_; }

 private:
  char* buffer_;
  const QuicConnectionIdLength destination_connection_id_length_;
  const QuicConnectionIdLength source_connection_id_length_;
  const bool includes_version_;
  const bool includes_diversification_nonce_;
  const QuicPacketNumberLength packet_number_length_;
  const QuicVariableLengthIntegerLength retry_token_length_length_;
  const QuicByteCount retry_token_length_;
  const QuicVariableLengthIntegerLength length_length_;
};

class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
 public:
  // Creates a QuicEncryptedPacket from a buffer and length.
  // Does not own the buffer.
  QuicEncryptedPacket(const char* buffer, size_t length);
  // Creates a QuicEncryptedPacket from a buffer and length,
  // optionally taking ownership of the buffer.
  QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer);
  // Creates a QuicEncryptedPacket from a absl::string_view.
  // Does not own the buffer.
  QuicEncryptedPacket(absl::string_view data);

  QuicEncryptedPacket(const QuicEncryptedPacket&) = delete;
  QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete;

  // Clones the packet into a new packet which owns the buffer.
  std::unique_ptr<QuicEncryptedPacket> Clone() const;

  // By default, gtest prints the raw bytes of an object. The bool data
  // member (in the base class QuicData) causes this object to have padding
  // bytes, which causes the default gtest object printer to read
  // uninitialize memory. So we need to teach gtest how to print this object.
  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
      std::ostream& os, const QuicEncryptedPacket& s);
};

// A received encrypted QUIC packet, with a recorded time of receipt.
class QUIC_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket {
 public:
  QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time);
  QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time,
                     bool owns_buffer);
  QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time,
                     bool owns_buffer, int ttl, bool ttl_valid);
  QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time,
                     bool owns_buffer, int ttl, bool ttl_valid,
                     char* packet_headers, size_t headers_length,
                     bool owns_header_buffer);
  ~QuicReceivedPacket();
  QuicReceivedPacket(const QuicReceivedPacket&) = delete;
  QuicReceivedPacket& operator=(const QuicReceivedPacket&) = delete;

  // Clones the packet into a new packet which owns the buffer.
  std::unique_ptr<QuicReceivedPacket> Clone() const;

  // Returns the time at which the packet was received.
  QuicTime receipt_time() const { return receipt_time_; }

  // This is the TTL of the packet, assuming ttl_vaild_ is true.
  int ttl() const { return ttl_; }

  // Start of packet headers.
  char* packet_headers() const { return packet_headers_; }

  // Length of packet headers.
  int headers_length() const { return headers_length_; }

  // By default, gtest prints the raw bytes of an object. The bool data
  // member (in the base class QuicData) causes this object to have padding
  // bytes, which causes the default gtest object printer to read
  // uninitialize memory. So we need to teach gtest how to print this object.
  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
      std::ostream& os, const QuicReceivedPacket& s);

 private:
  const QuicTime receipt_time_;
  int ttl_;
  // Points to the start of packet headers.
  char* packet_headers_;
  // Length of packet headers.
  int headers_length_;
  // Whether owns the buffer for packet headers.
  bool owns_header_buffer_;
};

// SerializedPacket contains information of a serialized(encrypted) packet.
//
// WARNING:
//
//   If you add a member field to this class, please make sure it is properly
//   copied in |CopySerializedPacket|.
//
struct QUIC_EXPORT_PRIVATE SerializedPacket {
  SerializedPacket(QuicPacketNumber packet_number,
                   QuicPacketNumberLength packet_number_length,
                   const char* encrypted_buffer,
                   QuicPacketLength encrypted_length, bool has_ack,
                   bool has_stop_waiting);

  // Copy constructor & assignment are deleted. Use |CopySerializedPacket| to
  // make a copy.
  SerializedPacket(const SerializedPacket& other) = delete;
  SerializedPacket& operator=(const SerializedPacket& other) = delete;
  SerializedPacket(SerializedPacket&& other);
  ~SerializedPacket();

  // TODO(wub): replace |encrypted_buffer|+|release_encrypted_buffer| by a
  // QuicOwnedPacketBuffer.
  // Not owned if |release_encrypted_buffer| is nullptr. Otherwise it is
  // released by |release_encrypted_buffer| on destruction.
  const char* encrypted_buffer;
  QuicPacketLength encrypted_length;
  std::function<void(const char*)> release_encrypted_buffer;

  QuicFrames retransmittable_frames;
  QuicFrames nonretransmittable_frames;
  IsHandshake has_crypto_handshake;
  QuicPacketNumber packet_number;
  QuicPacketNumberLength packet_number_length;
  EncryptionLevel encryption_level;
  // TODO(fayang): Remove has_ack and has_stop_waiting.
  bool has_ack;
  bool has_stop_waiting;
  TransmissionType transmission_type;
  // The largest acked of the AckFrame in this packet if has_ack is true,
  // 0 otherwise.
  QuicPacketNumber largest_acked;
  // Indicates whether this packet has a copy of ack frame in
  // nonretransmittable_frames.
  bool has_ack_frame_copy;
  bool has_ack_frequency;
  bool has_message;
  SerializedPacketFate fate;
  QuicSocketAddress peer_address;
};

// Make a copy of |serialized| (including the underlying frames). |copy_buffer|
// indicates whether the encrypted buffer should be copied.
QUIC_EXPORT_PRIVATE SerializedPacket* CopySerializedPacket(
    const SerializedPacket& serialized,
    quiche::QuicheBufferAllocator* allocator, bool copy_buffer);

// Allocates a new char[] of size |packet.encrypted_length| and copies in
// |packet.encrypted_buffer|.
QUIC_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet);
// Allocates a new char[] of size |encrypted_length| and copies in
// |encrypted_buffer|.
QUIC_EXPORT_PRIVATE char* CopyBuffer(const char* encrypted_buffer,
                                     QuicPacketLength encrypted_length);

// Context for an incoming packet.
struct QUIC_EXPORT_PRIVATE QuicPerPacketContext {
  virtual ~QuicPerPacketContext() {}
};

// ReceivedPacketInfo comprises information obtained by parsing the unencrypted
// bytes of a received packet.
struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
  ReceivedPacketInfo(const QuicSocketAddress& self_address,
                     const QuicSocketAddress& peer_address,
                     const QuicReceivedPacket& packet);
  ReceivedPacketInfo(const ReceivedPacketInfo& other) = default;

  ~ReceivedPacketInfo();

  std::string ToString() const;

  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
      std::ostream& os, const ReceivedPacketInfo& packet_info);

  const QuicSocketAddress& self_address;
  const QuicSocketAddress& peer_address;
  const QuicReceivedPacket& packet;

  PacketHeaderFormat form;
  // This is only used if the form is IETF_QUIC_LONG_HEADER_PACKET.
  QuicLongHeaderType long_packet_type;
  bool version_flag;
  bool use_length_prefix;
  QuicVersionLabel version_label;
  ParsedQuicVersion version;
  QuicConnectionId destination_connection_id;
  QuicConnectionId source_connection_id;
  absl::optional<absl::string_view> retry_token;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_PACKETS_H_