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