quic_protocol.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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 NET_QUIC_QUIC_PROTOCOL_H_
6#define NET_QUIC_QUIC_PROTOCOL_H_
7
8#include <stddef.h>
9#include <limits>
10#include <map>
11#include <ostream>
12#include <set>
13#include <string>
14#include <utility>
15#include <vector>
16
17#include "base/basictypes.h"
18#include "base/hash_tables.h"
19#include "base/logging.h"
20#include "base/string_piece.h"
21#include "net/base/int128.h"
22#include "net/base/net_export.h"
23#include "net/quic/quic_bandwidth.h"
24#include "net/quic/quic_time.h"
25
26namespace net {
27
28using ::operator<<;
29
30class QuicPacket;
31
32typedef uint64 QuicGuid;
33typedef uint32 QuicStreamId;
34typedef uint64 QuicStreamOffset;
35typedef uint64 QuicPacketSequenceNumber;
36typedef QuicPacketSequenceNumber QuicFecGroupNumber;
37typedef uint64 QuicPublicResetNonceProof;
38typedef uint8 QuicPacketEntropyHash;
39typedef uint32 QuicVersionTag;
40typedef std::vector<QuicVersionTag> QuicVersionTagList;
41
42// TODO(rch): Consider Quic specific names for these constants.
43// Maximum size in bytes of a QUIC packet.
44const QuicByteCount kMaxPacketSize = 1200;
45
46// Maximum number of open streams per connection.
47const size_t kDefaultMaxStreamsPerConnection = 100;
48
49// Number of bytes reserved for guid in the packet header.
50const size_t kQuicGuidSize = 8;
51// Number of bytes reserved for public flags in the packet header.
52const size_t kPublicFlagsSize = 1;
53// Number of bytes reserved for version number in the packet header.
54const size_t kQuicVersionSize = 4;
55// Number of bytes reserved for sequence number in the packet header.
56const size_t kSequenceNumberSize = 6;
57// Number of bytes reserved for private flags in the packet header.
58const size_t kPrivateFlagsSize = 1;
59// Number of bytes reserved for FEC group in the packet header.
60const size_t kFecGroupSize = 1;
61// Number of bytes reserved for the nonce proof in public reset packet.
62const size_t kPublicResetNonceSize = 8;
63
64// Signifies that the QuicPacket will contain version of the protocol.
65const bool kIncludeVersion = true;
66
67// Size in bytes of the data or fec packet header.
68NET_EXPORT_PRIVATE size_t GetPacketHeaderSize(bool include_version);
69// Size in bytes of the public reset packet.
70NET_EXPORT_PRIVATE size_t GetPublicResetPacketSize();
71
72// Index of the first byte in a QUIC packet of FEC protected data.
73NET_EXPORT_PRIVATE size_t GetStartOfFecProtectedData(bool include_version);
74// Index of the first byte in a QUIC packet of encrypted data.
75NET_EXPORT_PRIVATE size_t GetStartOfEncryptedData(bool include_version);
76// Returns true if |version| is a supported protocol version.
77NET_EXPORT_PRIVATE bool IsSupportedVersion(QuicVersionTag version);
78
79// Index of the first byte in a QUIC packet which is used in hash calculation.
80const size_t kStartOfHashData = 0;
81
82// Limit on the delta between stream IDs.
83const QuicStreamId kMaxStreamIdDelta = 100;
84
85// Reserved ID for the crypto stream.
86// TODO(rch): ensure that this is not usable by any other streams.
87const QuicStreamId kCryptoStreamId = 1;
88
89// Value which indicates this packet is not FEC protected.
90const uint8 kNoFecOffset = 0xFF;
91
92const int64 kDefaultTimeoutUs = 600000000;  // 10 minutes.
93
94enum QuicFrameType {
95  PADDING_FRAME = 0,
96  STREAM_FRAME,
97  ACK_FRAME,
98  CONGESTION_FEEDBACK_FRAME,
99  RST_STREAM_FRAME,
100  CONNECTION_CLOSE_FRAME,
101  GOAWAY_FRAME,
102  NUM_FRAME_TYPES
103};
104
105enum QuicPacketPublicFlags {
106  PACKET_PUBLIC_FLAGS_NONE = 0,
107  PACKET_PUBLIC_FLAGS_VERSION = 1 << 0,  // Packet header contains version info.
108  PACKET_PUBLIC_FLAGS_RST = 1 << 1,  // Packet is a public reset packet.
109  PACKET_PUBLIC_FLAGS_MAX = (1 << 2) - 1  // All bits set.
110};
111
112enum QuicPacketPrivateFlags {
113  PACKET_PRIVATE_FLAGS_NONE = 0,
114  PACKET_PRIVATE_FLAGS_FEC = 1 << 0,  // Payload is FEC as opposed to frames.
115  PACKET_PRIVATE_FLAGS_ENTROPY = 1 << 1,
116  PACKET_PRIVATE_FLAGS_FEC_ENTROPY = 1 << 2,
117  PACKET_PRIVATE_FLAGS_MAX = (1 << 3) - 1  // All bits set.
118};
119
120enum QuicErrorCode {
121  // Stream errors.
122  QUIC_NO_ERROR = 0,
123
124  // Connection has reached an invalid state.
125  QUIC_INTERNAL_ERROR,
126
127  // There were data frames after the a fin or reset.
128  QUIC_STREAM_DATA_AFTER_TERMINATION,
129  // There was some server error which halted stream processing.
130  QUIC_SERVER_ERROR_PROCESSING_STREAM,
131  // We got two fin or reset offsets which did not match.
132  QUIC_MULTIPLE_TERMINATION_OFFSETS,
133  // We got bad payload and can not respond to it at the protocol level.
134  QUIC_BAD_APPLICATION_PAYLOAD,
135
136  // Connection errors.
137
138  // Control frame is malformed.
139  QUIC_INVALID_PACKET_HEADER,
140  // Frame data is malformed.
141  QUIC_INVALID_FRAME_DATA,
142  // FEC data is malformed.
143  QUIC_INVALID_FEC_DATA,
144  // Stream rst data is malformed
145  QUIC_INVALID_RST_STREAM_DATA,
146  // Connection close data is malformed.
147  QUIC_INVALID_CONNECTION_CLOSE_DATA,
148  // GoAway data is malformed.
149  QUIC_INVALID_GOAWAY_DATA,
150  // Ack data is malformed.
151  QUIC_INVALID_ACK_DATA,
152  // Version negotiation packet is malformed.
153  QUIC_INVALID_VERSION_NEGOTIATION_PACKET,
154  // There was an error decrypting.
155  QUIC_DECRYPTION_FAILURE,
156  // There was an error encrypting.
157  QUIC_ENCRYPTION_FAILURE,
158  // The packet exceeded kMaxPacketSize.
159  QUIC_PACKET_TOO_LARGE,
160  // Data was sent for a stream which did not exist.
161  QUIC_PACKET_FOR_NONEXISTENT_STREAM,
162  // The peer is going away.  May be a client or server.
163  QUIC_PEER_GOING_AWAY,
164  // A stream ID was invalid.
165  QUIC_INVALID_STREAM_ID,
166  // Too many streams already open.
167  QUIC_TOO_MANY_OPEN_STREAMS,
168  // Received public reset for this connection.
169  QUIC_PUBLIC_RESET,
170  // Invalid protocol version
171  QUIC_INVALID_VERSION,
172
173  // We hit our prenegotiated (or default) timeout
174  QUIC_CONNECTION_TIMED_OUT,
175
176  // Crypto errors.
177
178  // Handshake message contained out of order tags.
179  QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
180  // Handshake message contained too many entries.
181  QUIC_CRYPTO_TOO_MANY_ENTRIES,
182  // Handshake message contained an invalid value length.
183  QUIC_CRYPTO_INVALID_VALUE_LENGTH,
184  // A crypto message was received after the handshake was complete.
185  QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
186  // A crypto message was received with an illegal message tag.
187  QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
188  // A crypto message was received with an illegal parameter.
189  QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
190  // A crypto message was received with a mandatory parameter missing.
191  QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND,
192  // A crypto message was received with a parameter that has no overlap
193  // with the local parameter.
194  QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP,
195  // A crypto message was received that contained a parameter with too few
196  // values.
197  QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND,
198};
199
200// Version and Crypto tags are written to the wire with a big-endian
201// representation of the name of the tag.  For example
202// the client hello tag (CHLO) will be written as the
203// following 4 bytes: 'C' 'H' 'L' 'O'.  Since it is
204// stored in memory as a little endian uint32, we need
205// to reverse the order of the bytes.
206#define MAKE_TAG(a, b, c, d) ((d << 24) + (c << 16) + (b << 8) + a)
207
208const QuicVersionTag kUnsupportedVersion = -1;
209const QuicVersionTag kQuicVersion1 = MAKE_TAG('Q', '1', '.', '0');
210
211struct NET_EXPORT_PRIVATE QuicPacketPublicHeader {
212  QuicPacketPublicHeader();
213  explicit QuicPacketPublicHeader(const QuicPacketPublicHeader& other);
214  ~QuicPacketPublicHeader();
215
216  QuicPacketPublicHeader& operator=(const QuicPacketPublicHeader& other);
217
218  // Universal header. All QuicPacket headers will have a guid and public flags.
219  QuicGuid guid;
220  bool reset_flag;
221  bool version_flag;
222  QuicVersionTagList versions;
223};
224
225// Header for Data or FEC packets.
226struct QuicPacketHeader {
227  QuicPacketHeader() {}
228  explicit QuicPacketHeader(const QuicPacketPublicHeader& header)
229      : public_header(header) {}
230
231  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
232      std::ostream& os, const QuicPacketHeader& s);
233
234  QuicPacketPublicHeader public_header;
235  bool fec_flag;
236  bool fec_entropy_flag;
237  bool entropy_flag;
238  QuicPacketEntropyHash entropy_hash;
239  QuicPacketSequenceNumber packet_sequence_number;
240  QuicFecGroupNumber fec_group;
241};
242
243struct QuicPublicResetPacket {
244  QuicPublicResetPacket() {}
245  explicit QuicPublicResetPacket(const QuicPacketPublicHeader& header)
246      : public_header(header) {}
247  QuicPacketPublicHeader public_header;
248  QuicPacketSequenceNumber rejected_sequence_number;
249  QuicPublicResetNonceProof nonce_proof;
250};
251
252enum QuicVersionNegotiationState {
253  START_NEGOTIATION = 0,
254  SENT_NEGOTIATION_PACKET,
255  NEGOTIATED_VERSION
256};
257
258typedef QuicPacketPublicHeader QuicVersionNegotiationPacket;
259
260// A padding frame contains no payload.
261struct NET_EXPORT_PRIVATE QuicPaddingFrame {
262};
263
264struct NET_EXPORT_PRIVATE QuicStreamFrame {
265  QuicStreamFrame();
266  QuicStreamFrame(QuicStreamId stream_id,
267                  bool fin,
268                  QuicStreamOffset offset,
269                  base::StringPiece data);
270
271  QuicStreamId stream_id;
272  bool fin;
273  QuicStreamOffset offset;  // Location of this data in the stream.
274  base::StringPiece data;
275};
276
277// TODO(ianswett): Re-evaluate the trade-offs of hash_set vs set when framing
278// is finalized.
279typedef std::set<QuicPacketSequenceNumber> SequenceNumberSet;
280// TODO(pwestin): Add a way to enforce the max size of this map.
281typedef std::map<QuicPacketSequenceNumber, QuicTime> TimeMap;
282
283struct NET_EXPORT_PRIVATE ReceivedPacketInfo {
284  ReceivedPacketInfo();
285  ~ReceivedPacketInfo();
286  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
287      std::ostream& os, const ReceivedPacketInfo& s);
288
289  // Entropy hash of all packets up to largest observed not including missing
290  // packets.
291  QuicPacketEntropyHash entropy_hash;
292
293  // The highest packet sequence number we've observed from the peer.
294  //
295  // In general, this should be the largest packet number we've received.  In
296  // the case of truncated acks, we may have to advertise a lower "upper bound"
297  // than largest received, to avoid implicitly acking missing packets that
298  // don't fit in the missing packet list due to size limitations.  In this
299  // case, largest_observed may be a packet which is also in the missing packets
300  // list.
301  QuicPacketSequenceNumber largest_observed;
302
303  // Time elapsed since largest_observed was received until this Ack frame was
304  // sent.
305  QuicTime::Delta delta_time_largest_observed;
306
307  // TODO(satyamshekhar): Can be optimized using an interval set like data
308  // structure.
309  // The set of packets which we're expecting and have not received.
310  SequenceNumberSet missing_packets;
311};
312
313// True if the sequence number is greater than largest_observed or is listed
314// as missing.
315// Always returns false for sequence numbers less than least_unacked.
316bool NET_EXPORT_PRIVATE IsAwaitingPacket(
317    const ReceivedPacketInfo& received_info,
318    QuicPacketSequenceNumber sequence_number);
319
320// Inserts missing packets between [lower, higher).
321void NET_EXPORT_PRIVATE InsertMissingPacketsBetween(
322    ReceivedPacketInfo* received_info,
323    QuicPacketSequenceNumber lower,
324    QuicPacketSequenceNumber higher);
325
326struct NET_EXPORT_PRIVATE SentPacketInfo {
327  SentPacketInfo();
328  ~SentPacketInfo();
329  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
330      std::ostream& os, const SentPacketInfo& s);
331
332  // Entropy hash of all packets up to, but not including, the least unacked
333  // packet.
334  QuicPacketEntropyHash entropy_hash;
335  // The lowest packet we've sent which is unacked, and we expect an ack for.
336  QuicPacketSequenceNumber least_unacked;
337};
338
339struct NET_EXPORT_PRIVATE QuicAckFrame {
340  QuicAckFrame() {}
341  // Testing convenience method to construct a QuicAckFrame with all packets
342  // from least_unacked to largest_observed acked.
343  QuicAckFrame(QuicPacketSequenceNumber largest_observed,
344               QuicTime largest_observed_receive_time,
345               QuicPacketSequenceNumber least_unacked);
346
347  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
348      std::ostream& os, const QuicAckFrame& s);
349
350  SentPacketInfo sent_info;
351  ReceivedPacketInfo received_info;
352};
353
354// Defines for all types of congestion feedback that will be negotiated in QUIC,
355// kTCP MUST be supported by all QUIC implementations to guarentee 100%
356// compatibility.
357enum CongestionFeedbackType {
358  kTCP,  // Used to mimic TCP.
359  kInterArrival,  // Use additional inter arrival information.
360  kFixRate,  // Provided for testing.
361};
362
363struct NET_EXPORT_PRIVATE CongestionFeedbackMessageTCP {
364  uint16 accumulated_number_of_lost_packets;
365  QuicByteCount receive_window;
366};
367
368struct NET_EXPORT_PRIVATE CongestionFeedbackMessageInterArrival {
369  CongestionFeedbackMessageInterArrival();
370  ~CongestionFeedbackMessageInterArrival();
371  uint16 accumulated_number_of_lost_packets;
372  // The set of received packets since the last feedback was sent, along with
373  // their arrival times.
374  TimeMap received_packet_times;
375};
376
377struct NET_EXPORT_PRIVATE CongestionFeedbackMessageFixRate {
378  CongestionFeedbackMessageFixRate();
379  QuicBandwidth bitrate;
380};
381
382struct NET_EXPORT_PRIVATE QuicCongestionFeedbackFrame {
383  QuicCongestionFeedbackFrame();
384  ~QuicCongestionFeedbackFrame();
385
386  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
387      std::ostream& os, const QuicCongestionFeedbackFrame& c);
388
389  CongestionFeedbackType type;
390  // This should really be a union, but since the inter arrival struct
391  // is non-trivial, C++ prohibits it.
392  CongestionFeedbackMessageTCP tcp;
393  CongestionFeedbackMessageInterArrival inter_arrival;
394  CongestionFeedbackMessageFixRate fix_rate;
395};
396
397struct NET_EXPORT_PRIVATE QuicRstStreamFrame {
398  QuicRstStreamFrame() {}
399  QuicRstStreamFrame(QuicStreamId stream_id, QuicErrorCode error_code)
400      : stream_id(stream_id), error_code(error_code) {
401    DCHECK_LE(error_code, std::numeric_limits<uint8>::max());
402  }
403
404  QuicStreamId stream_id;
405  QuicErrorCode error_code;
406  std::string error_details;
407};
408
409struct NET_EXPORT_PRIVATE QuicConnectionCloseFrame {
410  QuicErrorCode error_code;
411  std::string error_details;
412  QuicAckFrame ack_frame;
413};
414
415struct NET_EXPORT_PRIVATE QuicGoAwayFrame {
416  QuicGoAwayFrame() {}
417  QuicGoAwayFrame(QuicErrorCode error_code,
418                  QuicStreamId last_good_stream_id,
419                  const std::string& reason);
420
421  QuicErrorCode error_code;
422  QuicStreamId last_good_stream_id;
423  std::string reason_phrase;
424};
425
426struct NET_EXPORT_PRIVATE QuicFrame {
427  QuicFrame() {}
428  explicit QuicFrame(QuicPaddingFrame* padding_frame)
429      : type(PADDING_FRAME),
430        padding_frame(padding_frame) {
431  }
432  explicit QuicFrame(QuicStreamFrame* stream_frame)
433      : type(STREAM_FRAME),
434        stream_frame(stream_frame) {
435  }
436  explicit QuicFrame(QuicAckFrame* frame)
437      : type(ACK_FRAME),
438        ack_frame(frame) {
439  }
440  explicit QuicFrame(QuicCongestionFeedbackFrame* frame)
441      : type(CONGESTION_FEEDBACK_FRAME),
442        congestion_feedback_frame(frame) {
443  }
444  explicit QuicFrame(QuicRstStreamFrame* frame)
445      : type(RST_STREAM_FRAME),
446        rst_stream_frame(frame) {
447  }
448  explicit QuicFrame(QuicConnectionCloseFrame* frame)
449      : type(CONNECTION_CLOSE_FRAME),
450        connection_close_frame(frame) {
451  }
452  explicit QuicFrame(QuicGoAwayFrame* frame)
453      : type(GOAWAY_FRAME),
454        goaway_frame(frame) {
455  }
456
457  QuicFrameType type;
458  union {
459    QuicPaddingFrame* padding_frame;
460    QuicStreamFrame* stream_frame;
461    QuicAckFrame* ack_frame;
462    QuicCongestionFeedbackFrame* congestion_feedback_frame;
463    QuicRstStreamFrame* rst_stream_frame;
464    QuicConnectionCloseFrame* connection_close_frame;
465    QuicGoAwayFrame* goaway_frame;
466  };
467};
468
469typedef std::vector<QuicFrame> QuicFrames;
470
471struct NET_EXPORT_PRIVATE QuicFecData {
472  QuicFecData();
473
474  bool operator==(const QuicFecData& other) const;
475
476  // The FEC group number is also the sequence number of the first
477  // FEC protected packet.  The last protected packet's sequence number will
478  // be one less than the sequence number of the FEC packet.
479  QuicFecGroupNumber fec_group;
480  base::StringPiece redundancy;
481};
482
483struct NET_EXPORT_PRIVATE QuicPacketData {
484  std::string data;
485};
486
487class NET_EXPORT_PRIVATE QuicData {
488 public:
489  QuicData(const char* buffer, size_t length)
490      : buffer_(buffer),
491        length_(length),
492        owns_buffer_(false) {}
493
494  QuicData(char* buffer, size_t length, bool owns_buffer)
495      : buffer_(buffer),
496        length_(length),
497        owns_buffer_(owns_buffer) {}
498
499  virtual ~QuicData();
500
501  base::StringPiece AsStringPiece() const {
502    return base::StringPiece(data(), length());
503  }
504
505  const char* data() const { return buffer_; }
506  size_t length() const { return length_; }
507
508 private:
509  const char* buffer_;
510  size_t length_;
511  bool owns_buffer_;
512
513  DISALLOW_COPY_AND_ASSIGN(QuicData);
514};
515
516class NET_EXPORT_PRIVATE QuicPacket : public QuicData {
517 public:
518  static QuicPacket* NewDataPacket(char* buffer,
519                                   size_t length,
520                                   bool owns_buffer,
521                                   bool includes_version) {
522    return new QuicPacket(buffer, length, owns_buffer, includes_version, false);
523  }
524
525  static QuicPacket* NewFecPacket(char* buffer,
526                                  size_t length,
527                                  bool owns_buffer,
528                                  bool includes_version) {
529    return new QuicPacket(buffer, length, owns_buffer, includes_version, true);
530  }
531
532  base::StringPiece FecProtectedData() const;
533  base::StringPiece AssociatedData() const;
534  base::StringPiece BeforePlaintext() const;
535  base::StringPiece Plaintext() const;
536
537  bool is_fec_packet() const { return is_fec_packet_; }
538
539  bool includes_version() const { return includes_version_; }
540
541  char* mutable_data() { return buffer_; }
542
543 private:
544  QuicPacket(char* buffer,
545             size_t length,
546             bool owns_buffer,
547             bool includes_version,
548             bool is_fec_packet)
549      : QuicData(buffer, length, owns_buffer),
550        buffer_(buffer),
551        is_fec_packet_(is_fec_packet),
552        includes_version_(includes_version) {}
553
554  char* buffer_;
555  const bool is_fec_packet_;
556  const bool includes_version_;
557
558  DISALLOW_COPY_AND_ASSIGN(QuicPacket);
559};
560
561class NET_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
562 public:
563  QuicEncryptedPacket(const char* buffer, size_t length)
564      : QuicData(buffer, length) {}
565
566  QuicEncryptedPacket(char* buffer, size_t length, bool owns_buffer)
567      : QuicData(buffer, length, owns_buffer) {}
568
569  // By default, gtest prints the raw bytes of an object. The bool data
570  // member (in the base class QuicData) causes this object to have padding
571  // bytes, which causes the default gtest object printer to read
572  // uninitialize memory. So we need to teach gtest how to print this object.
573  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
574      std::ostream& os, const QuicEncryptedPacket& s);
575
576 private:
577  DISALLOW_COPY_AND_ASSIGN(QuicEncryptedPacket);
578};
579
580class NET_EXPORT_PRIVATE RetransmittableFrames {
581 public:
582  RetransmittableFrames();
583  ~RetransmittableFrames();
584
585  // Allocates a local copy of the referenced StringPiece has QuicStreamFrame
586  // use it.
587  // Takes ownership of |stream_frame|.
588  const QuicFrame& AddStreamFrame(QuicStreamFrame* stream_frame);
589  // Takes ownership of the frame inside |frame|.
590  const QuicFrame& AddNonStreamFrame(const QuicFrame& frame);
591  const QuicFrames& frames() const { return frames_; }
592
593 private:
594  QuicFrames frames_;
595  // Data referenced by the StringPiece of a QuicStreamFrame.
596  std::vector<std::string*> stream_data_;
597
598  DISALLOW_COPY_AND_ASSIGN(RetransmittableFrames);
599};
600
601struct NET_EXPORT_PRIVATE SerializedPacket {
602  SerializedPacket(QuicPacketSequenceNumber sequence_number,
603                   QuicPacket* packet,
604                   QuicPacketEntropyHash entropy_hash,
605                   RetransmittableFrames* retransmittable_frames)
606      : sequence_number(sequence_number),
607        packet(packet),
608        entropy_hash(entropy_hash),
609        retransmittable_frames(retransmittable_frames) {}
610
611  QuicPacketSequenceNumber sequence_number;
612  QuicPacket* packet;
613  QuicPacketEntropyHash entropy_hash;
614  RetransmittableFrames* retransmittable_frames;
615};
616
617// A struct for functions which consume data payloads and fins.
618// The first member of the pair indicates bytes consumed.
619// The second member of the pair indicates if an incoming fin was consumed.
620struct QuicConsumedData {
621  QuicConsumedData(size_t bytes_consumed, bool fin_consumed)
622      : bytes_consumed(bytes_consumed),
623        fin_consumed(fin_consumed) {}
624
625  // By default, gtest prints the raw bytes of an object. The bool data
626  // member causes this object to have padding bytes, which causes the
627  // default gtest object printer to read uninitialize memory. So we need
628  // to teach gtest how to print this object.
629  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
630      std::ostream& os, const QuicConsumedData& s);
631
632  size_t bytes_consumed;
633  bool fin_consumed;
634};
635
636}  // namespace net
637
638#endif  // NET_QUIC_QUIC_PROTOCOL_H_
639