15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_protocol.h"
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "net/quic/quic_utils.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::map;
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::numeric_limits;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::ostream;
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::string;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t GetPacketHeaderSize(QuicPacketHeader header) {
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetPacketHeaderSize(header.public_header.guid_length,
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             header.public_header.version_flag,
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             header.public_header.sequence_number_length,
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             header.is_in_fec_group);
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t GetPacketHeaderSize(QuicGuidLength guid_length,
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           bool include_version,
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           QuicSequenceNumberLength sequence_number_length,
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           InFecGroup is_in_fec_group) {
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return kPublicFlagsSize + guid_length +
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (include_version ? kQuicVersionSize : 0) + sequence_number_length +
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kPrivateFlagsSize + (is_in_fec_group == IN_FEC_GROUP ? kFecGroupSize : 0);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t GetPublicResetPacketSize() {
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return kPublicFlagsSize + PACKET_8BYTE_GUID + kPublicResetNonceSize +
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t GetStartOfFecProtectedData(
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicGuidLength guid_length,
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool include_version,
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicSequenceNumberLength sequence_number_length) {
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetPacketHeaderSize(
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guid_length, include_version, sequence_number_length, IN_FEC_GROUP);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t GetStartOfEncryptedData(
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicGuidLength guid_length,
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool include_version,
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicSequenceNumberLength sequence_number_length) {
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Don't include the fec size, since encryption starts before private flags.
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetPacketHeaderSize(
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guid_length, include_version, sequence_number_length, NOT_IN_FEC_GROUP) -
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kPrivateFlagsSize;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicPacketPublicHeader::QuicPacketPublicHeader()
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : guid(0),
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guid_length(PACKET_8BYTE_GUID),
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      reset_flag(false),
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      version_flag(false),
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sequence_number_length(PACKET_6BYTE_SEQUENCE_NUMBER) {
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicPacketPublicHeader::QuicPacketPublicHeader(
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicPacketPublicHeader& other)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : guid(other.guid),
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guid_length(other.guid_length),
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      reset_flag(other.reset_flag),
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      version_flag(other.version_flag),
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sequence_number_length(other.sequence_number_length),
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      versions(other.versions) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicPacketPublicHeader::~QuicPacketPublicHeader() {}
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicPacketHeader::QuicPacketHeader()
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : fec_flag(false),
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      entropy_flag(false),
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      entropy_hash(0),
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      packet_sequence_number(0),
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      is_in_fec_group(NOT_IN_FEC_GROUP),
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fec_group(0) {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicPacketHeader::QuicPacketHeader(const QuicPacketPublicHeader& header)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public_header(header),
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fec_flag(false),
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      entropy_flag(false),
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      entropy_hash(0),
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      packet_sequence_number(0),
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      is_in_fec_group(NOT_IN_FEC_GROUP),
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fec_group(0) {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicStreamFrame::QuicStreamFrame() {}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicStreamFrame::QuicStreamFrame(const QuicStreamFrame& frame)
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : stream_id(frame.stream_id),
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      fin(frame.fin),
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      offset(frame.offset),
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      data(frame.data),
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      notifier(frame.notifier) {
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 bool fin,
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 QuicStreamOffset offset,
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 IOVector data)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : stream_id(stream_id),
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fin(fin),
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offset(offset),
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      data(data),
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      notifier(NULL) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)string* QuicStreamFrame::GetDataAsString() const {
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  string* data_string = new string();
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  data_string->reserve(data.TotalBufferSize());
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < data.Size(); ++i) {
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    data_string->append(static_cast<char*>(data.iovec()[i].iov_base),
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        data.iovec()[i].iov_len);
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(data_string->size(), data.TotalBufferSize());
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return data_string;
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
128558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochuint32 MakeQuicTag(char a, char b, char c, char d) {
129558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return static_cast<uint32>(a) |
130558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch         static_cast<uint32>(b) << 8 |
131558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch         static_cast<uint32>(c) << 16 |
132558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch         static_cast<uint32>(d) << 24;
133558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
134558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)QuicVersionVector QuicSupportedVersions() {
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  QuicVersionVector supported_versions;
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    supported_versions.push_back(kSupportedQuicVersions[i]);
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return supported_versions;
141c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch}
142c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
143558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochQuicTag QuicVersionToQuicTag(const QuicVersion version) {
144558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  switch (version) {
1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case QUIC_VERSION_12:
1460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return MakeQuicTag('Q', '0', '1', '2');
147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    default:
148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      // This shold be an ERROR because we should never attempt to convert an
149558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      // invalid QuicVersion to be written to the wire.
150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      LOG(ERROR) << "Unsupported QuicVersion: " << version;
151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return 0;
152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
153558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
155558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochQuicVersion QuicTagToQuicVersion(const QuicTag version_tag) {
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (version_tag == QuicVersionToQuicTag(kSupportedQuicVersions[i])) {
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return kSupportedQuicVersions[i];
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Reading from the client so this should not be considered an ERROR.
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << "Unsupported QuicTag version: "
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             << QuicUtils::TagToString(version_tag);
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return QUIC_VERSION_UNSUPPORTED;
165558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#define RETURN_STRING_LITERAL(x) \
168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochcase x: \
169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochreturn #x
170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstring QuicVersionToString(const QuicVersion version) {
172558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  switch (version) {
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    RETURN_STRING_LITERAL(QUIC_VERSION_12);
174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    default:
175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return "QUIC_VERSION_UNSUPPORTED";
176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
178558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)string QuicVersionVectorToString(const QuicVersionVector& versions) {
180558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  string result = "";
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < versions.size(); ++i) {
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (i != 0) {
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      result.append(",");
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    result.append(QuicVersionToString(versions[i]));
186558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
187558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return result;
188558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
189558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ostream& operator<<(ostream& os, const QuicPacketHeader& header) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << "{ guid: " << header.public_header.guid
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     << ", guid_length:" << header.public_header.guid_length
1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)     << ", sequence_number_length:"
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)     << header.public_header.sequence_number_length
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << ", reset_flag: " << header.public_header.reset_flag
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << ", version_flag: " << header.public_header.version_flag;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (header.public_header.version_flag) {
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os << " version: ";
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < header.public_header.versions.size(); ++i) {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os << header.public_header.versions[0] << " ";
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << ", fec_flag: " << header.fec_flag
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << ", entropy_flag: " << header.entropy_flag
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << ", entropy hash: " << static_cast<int>(header.entropy_hash)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << ", sequence_number: " << header.packet_sequence_number
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     << ", is_in_fec_group:" << header.is_in_fec_group
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << ", fec_group: " << header.fec_group<< "}\n";
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os;
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ReceivedPacketInfo::ReceivedPacketInfo()
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : largest_observed(0),
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      delta_time_largest_observed(QuicTime::Delta::Infinite()),
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      is_truncated(false) {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceivedPacketInfo::~ReceivedPacketInfo() {}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsAwaitingPacket(const ReceivedPacketInfo& received_info,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      QuicPacketSequenceNumber sequence_number) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return sequence_number > received_info.largest_observed ||
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContainsKey(received_info.missing_packets, sequence_number);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InsertMissingPacketsBetween(ReceivedPacketInfo* received_info,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 QuicPacketSequenceNumber lower,
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 QuicPacketSequenceNumber higher) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (QuicPacketSequenceNumber i = lower; i < higher; ++i) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    received_info->missing_packets.insert(i);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SentPacketInfo::SentPacketInfo() {}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SentPacketInfo::~SentPacketInfo() {}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Testing convenience method.
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicAckFrame::QuicAckFrame(QuicPacketSequenceNumber largest_observed,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           QuicTime largest_observed_receive_time,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           QuicPacketSequenceNumber least_unacked) {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  received_info.largest_observed = largest_observed;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  received_info.entropy_hash = 0;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sent_info.least_unacked = least_unacked;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sent_info.entropy_hash = 0;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ostream& operator<<(ostream& os, const SentPacketInfo& sent_info) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << "entropy_hash: " << static_cast<int>(sent_info.entropy_hash)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << " least_unacked: " << sent_info.least_unacked;
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ostream& operator<<(ostream& os, const ReceivedPacketInfo& received_info) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << "entropy_hash: " << static_cast<int>(received_info.entropy_hash)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << " largest_observed: " << received_info.largest_observed
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << " missing_packets: [ ";
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (SequenceNumberSet::const_iterator it =
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           received_info.missing_packets.begin();
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != received_info.missing_packets.end(); ++it) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    os << *it << " ";
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << " ] ";
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicCongestionFeedbackFrame::QuicCongestionFeedbackFrame() {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicCongestionFeedbackFrame::~QuicCongestionFeedbackFrame() {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ostream& operator<<(ostream& os,
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const QuicCongestionFeedbackFrame& congestion_frame) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << "type: " << congestion_frame.type;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (congestion_frame.type) {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kInterArrival: {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const CongestionFeedbackMessageInterArrival& inter_arrival =
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          congestion_frame.inter_arrival;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os << " accumulated_number_of_lost_packets: "
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         << inter_arrival.accumulated_number_of_lost_packets;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os << " received packets: [ ";
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (TimeMap::const_iterator it =
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               inter_arrival.received_packet_times.begin();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           it != inter_arrival.received_packet_times.end(); ++it) {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        os << it->first << "@" << it->second.ToDebuggingValue() << " ";
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os << "]";
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kFixRate: {
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os << " bitrate_in_bytes_per_second: "
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         << congestion_frame.fix_rate.bitrate.ToBytesPerSecond();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kTCP: {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const CongestionFeedbackMessageTCP& tcp = congestion_frame.tcp;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os << " accumulated_number_of_lost_packets: "
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         << congestion_frame.tcp.accumulated_number_of_lost_packets;
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os << " receive_window: " << tcp.receive_window;
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return os;
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ostream& operator<<(ostream& os, const QuicAckFrame& ack_frame) {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << "sent info { " << ack_frame.sent_info << " } "
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << "received info { " << ack_frame.received_info << " }\n";
31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return os;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CongestionFeedbackMessageFixRate::CongestionFeedbackMessageFixRate()
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : bitrate(QuicBandwidth::Zero()) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CongestionFeedbackMessageInterArrival::
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CongestionFeedbackMessageInterArrival() {}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CongestionFeedbackMessageInterArrival::
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)~CongestionFeedbackMessageInterArrival() {}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicGoAwayFrame::QuicGoAwayFrame(QuicErrorCode error_code,
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 QuicStreamId last_good_stream_id,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const string& reason)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : error_code(error_code),
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_good_stream_id(last_good_stream_id),
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      reason_phrase(reason) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(error_code, numeric_limits<uint8>::max());
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicFecData::QuicFecData() {}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicData::~QuicData() {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (owns_buffer_) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete [] const_cast<char*>(buffer_);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StringPiece QuicPacket::FecProtectedData() const {
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const size_t start_of_fec = GetStartOfFecProtectedData(
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guid_length_, includes_version_, sequence_number_length_);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return StringPiece(data() + start_of_fec, length() - start_of_fec);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StringPiece QuicPacket::AssociatedData() const {
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return StringPiece(
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      data() + kStartOfHashData,
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetStartOfEncryptedData(
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          guid_length_, includes_version_, sequence_number_length_) -
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kStartOfHashData);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StringPiece QuicPacket::BeforePlaintext() const {
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return StringPiece(data(), GetStartOfEncryptedData(guid_length_,
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                     includes_version_,
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                     sequence_number_length_));
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StringPiece QuicPacket::Plaintext() const {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t start_of_encrypted_data =
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetStartOfEncryptedData(
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          guid_length_, includes_version_, sequence_number_length_);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return StringPiece(data() + start_of_encrypted_data,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     length() - start_of_encrypted_data);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RetransmittableFrames::RetransmittableFrames()
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : encryption_level_(NUM_ENCRYPTION_LEVELS) {
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)RetransmittableFrames::~RetransmittableFrames() {
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (QuicFrames::iterator it = frames_.begin(); it != frames_.end(); ++it) {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (it->type) {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PADDING_FRAME:
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delete it->padding_frame;
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STREAM_FRAME:
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delete it->stream_frame;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ACK_FRAME:
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delete it->ack_frame;
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case CONGESTION_FEEDBACK_FRAME:
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delete it->congestion_feedback_frame;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case RST_STREAM_FRAME:
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delete it->rst_stream_frame;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case CONNECTION_CLOSE_FRAME:
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delete it->connection_close_frame;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case GOAWAY_FRAME:
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delete it->goaway_frame;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case NUM_FRAME_TYPES:
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK(false) << "Cannot delete type: " << it->type;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  STLDeleteElements(&stream_data_);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const QuicFrame& RetransmittableFrames::AddStreamFrame(
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicStreamFrame* stream_frame) {
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make an owned copy of the stream frame's data.
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream_data_.push_back(stream_frame->GetDataAsString());
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Ensure the stream frame's IOVector points to the owned copy of the data.
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream_frame->data.Clear();
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream_frame->data.Append(const_cast<char*>(stream_data_.back()->data()),
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            stream_data_.back()->size());
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames_.push_back(QuicFrame(stream_frame));
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frames_.back();
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const QuicFrame& RetransmittableFrames::AddNonStreamFrame(
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicFrame& frame) {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(frame.type, STREAM_FRAME);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames_.push_back(frame);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frames_.back();
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RetransmittableFrames::set_encryption_level(EncryptionLevel level) {
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  encryption_level_ = level;
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)SerializedPacket::SerializedPacket(
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicSequenceNumberLength sequence_number_length,
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicPacket* packet,
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicPacketEntropyHash entropy_hash,
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RetransmittableFrames* retransmittable_frames)
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : sequence_number(sequence_number),
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sequence_number_length(sequence_number_length),
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      packet(packet),
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      entropy_hash(entropy_hash),
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      retransmittable_frames(retransmittable_frames) {
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)SerializedPacket::~SerializedPacket() {}
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicEncryptedPacket* QuicEncryptedPacket::Clone() const {
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  char* buffer = new char[this->length()];
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  memcpy(buffer, this->data(), this->length());
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return new QuicEncryptedPacket(buffer, this->length(), true);
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ostream& operator<<(ostream& os, const QuicEncryptedPacket& s) {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << s.length() << "-byte data";
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ostream& operator<<(ostream& os, const QuicConsumedData& s) {
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os << "bytes_consumed: " << s.bytes_consumed
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     << " fin_consumed: " << s.fin_consumed;
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os;
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
459