quic_packet_creator.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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_packet_creator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_random.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_fec_group.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::make_pair;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::pair;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicPacketCreator::QuicPacketCreator(QuicGuid guid,
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     QuicFramer* framer,
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     QuicRandom* random_generator,
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     bool is_server)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : guid_(guid),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer_(framer),
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      random_generator_(random_generator),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence_number_(0),
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fec_group_number_(0),
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_server_(is_server),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      send_version_in_packet_(!is_server),
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      packet_size_(GetPacketHeaderSize(options_.send_guid_length,
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       send_version_in_packet_,
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       options_.send_sequence_number_length,
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       NOT_IN_FEC_GROUP)) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer_->set_fec_builder(this);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::~QuicPacketCreator() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::OnBuiltFecProtectedPayload(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicPacketHeader& header, StringPiece payload) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fec_group_.get()) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_group_->Update(header, payload);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 &&
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (force_close ||
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::MaybeStartFEC() {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) {
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(queued_frames_.empty());
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Set the fec group number to the sequence number of the next packet.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fec_group_number_ = sequence_number() + 1;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fec_group_.reset(new QuicFecGroup());
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       send_version_in_packet_,
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       options_.send_sequence_number_length,
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       IN_FEC_GROUP);
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK_LE(packet_size_, options_.max_packet_length);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stops serializing version of the protocol in packets sent after this call.
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A packet that is already open might send kQuicVersionSize bytes less than the
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maximum packet size if we stop sending version before it is serialized.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::StopSendingVersion() {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(send_version_in_packet_);
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  send_version_in_packet_ = false;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (packet_size_ > 0) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_LT(kQuicVersionSize, packet_size_);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    packet_size_ -= kQuicVersionSize;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::HasRoomForStreamFrame() const {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return BytesFree() > QuicFramer::GetMinStreamFrameSize();
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t QuicPacketCreator::StreamFramePacketOverhead(
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicGuidLength guid_length,
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool include_version,
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicSequenceNumberLength sequence_number_length,
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    InFecGroup is_in_fec_group) {
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetPacketHeaderSize(guid_length, include_version,
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             sequence_number_length, is_in_fec_group) +
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Assumes this is a stream with a single lone packet.
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      QuicFramer::GetMinStreamFrameSize(1, 0, true);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            StringPiece data,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicStreamOffset offset,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            bool fin,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicFrame* frame) {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GT(options_.max_packet_length,
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            StreamFramePacketOverhead(
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                PACKET_8BYTE_GUID, kIncludeVersion,
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP));
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(HasRoomForStreamFrame());
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t free_bytes = BytesFree();
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t bytes_consumed = 0;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (data.size() != 0) {
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    size_t min_last_stream_frame_size =
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        QuicFramer::GetMinStreamFrameSize(id, offset, true);
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Comparing against the last stream frame size including the length
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // guarantees that all the bytes will fit.  Otherwise there is a
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // discontinuity where the packet goes one byte over due to the length data.
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (data.size() > free_bytes - min_last_stream_frame_size -
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        kQuicStreamPayloadLengthSize) {
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Its the last frame, put as much data as possible in.
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      bytes_consumed =
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          min<size_t>(free_bytes - min_last_stream_frame_size, data.size());
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      bytes_consumed = data.size();
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool set_fin = fin && bytes_consumed == data.size();  // Last frame.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StringPiece data_frame(data.data(), bytes_consumed);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, data_frame));
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(fin);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Create a new packet for the fin, if necessary.
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *frame = QuicFrame(new QuicStreamFrame(id, true, offset, ""));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return bytes_consumed;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeAllFrames(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicFrames& frames) {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames from SendStreamData()[send_stream_should_flush_ == false &&
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // data.empty() == true] and retransmit due to RTO.
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < frames.size(); ++i) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success = AddFrame(frames[i], false);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(success);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet = SerializePacket();
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(packet.retransmittable_frames == NULL);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return packet;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::HasPendingFrames() {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !queued_frames_.empty();
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::BytesFree() const {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t max_plaintext_size =
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer_->GetMaxPlaintextSize(options_.max_packet_length);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (packet_size_ > max_plaintext_size) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_plaintext_size - packet_size_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddFrame(frame, true);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializePacket() {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(false, queued_frames_.empty());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FillPacketHeader(fec_group_number_, false, false, &header);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket serialized = framer_->ConstructFrameDataPacket(
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      header, queued_frames_, packet_size_);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  queued_frames_.clear();
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     send_version_in_packet_,
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     options_.send_sequence_number_length,
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     fec_group_.get() != NULL ?
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         IN_FEC_GROUP : NOT_IN_FEC_GROUP);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized.retransmittable_frames = queued_retransmittable_frames_.release();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeFec() {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(0u, fec_group_->NumReceivedPackets());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FillPacketHeader(fec_group_number_, true,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   fec_group_->entropy_parity(), &header);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFecData fec_data;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.fec_group = fec_group_->min_protected_packet();
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.redundancy = fec_group_->payload_parity();
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket serialized = framer_->ConstructFecPacket(header, fec_data);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_group_.reset(NULL);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_group_number_ = 0;
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Reset packet_size_, since the next packet may not have an FEC group.
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     send_version_in_packet_,
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     options_.send_sequence_number_length,
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                     NOT_IN_FEC_GROUP);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(serialized.packet);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(options_.max_packet_length, serialized.packet->length());
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeConnectionClose(
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicConnectionCloseFrame* close_frame) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(close_frame));
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SerializeAllFrames(frames);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const QuicTagVector& supported_versions) {
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(is_server_);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketPublicHeader header;
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.guid = guid_;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.reset_flag = false;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.version_flag = true;
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.versions = supported_versions;
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket* encrypted =
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer_->ConstructVersionNegotiationPacket(header, supported_versions);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(encrypted);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(options_.max_packet_length, encrypted->length());
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return encrypted;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool fec_flag,
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool fec_entropy_flag,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         QuicPacketHeader* header) {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.guid = guid_;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.reset_flag = false;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.version_flag = send_version_in_packet_;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->fec_flag = fec_flag;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->packet_sequence_number = ++sequence_number_;
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool entropy_flag;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (header->packet_sequence_number == 1) {
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(!fec_flag);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(satyamshekhar): No entropy in the first message.
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For crypto tests to pass. Fix this by using deterministic QuicRandom.
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    entropy_flag = 0;
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (fec_flag) {
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // FEC packets don't have an entropy of their own. Entropy flag for FEC
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packets is the XOR of entropy of previous packets.
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    entropy_flag = fec_entropy_flag;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    entropy_flag = random_generator_->RandBool();
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header->entropy_flag = entropy_flag;
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->fec_group = fec_group;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME &&
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame.type != PADDING_FRAME;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool save_retransmittable_frames) {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t frame_len = framer_->GetSerializedFrameLength(
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, BytesFree(), queued_frames_.empty());
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (frame_len == 0) {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  packet_size_ += frame_len;
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (save_retransmittable_frames && ShouldRetransmit(frame)) {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (queued_retransmittable_frames_.get() == NULL) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_retransmittable_frames_.reset(new RetransmittableFrames());
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame.type == STREAM_FRAME) {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame));
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddNonStreamFrame(frame));
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queued_frames_.push_back(frame);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
290