quic_packet_creator.cc revision f2477e01787aa58f445919b809d89e252beef54f
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"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/quic/quic_ack_notifier.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_fec_group.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::make_pair;
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using std::max;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::pair;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// If true, then QUIC handshake packets will be padded to the maximium packet
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// size.
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool FLAGS_pad_quic_handshake_packets = true;
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicPacketCreator::QuicPacketCreator(QuicGuid guid,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     QuicFramer* framer,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     QuicRandom* random_generator,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     bool is_server)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : guid_(guid),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer_(framer),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      random_generator_(random_generator),
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence_number_(0),
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fec_group_number_(0),
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_server_(is_server),
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      send_version_in_packet_(!is_server),
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      sequence_number_length_(options_.send_sequence_number_length),
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      packet_size_(0) {
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  framer_->set_fec_builder(this);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::~QuicPacketCreator() {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::OnBuiltFecProtectedPayload(
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicPacketHeader& header, StringPiece payload) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fec_group_.get()) {
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK_NE(0u, header.fec_group);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_group_->Update(header, payload);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 &&
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (force_close ||
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::MaybeStartFEC() {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) {
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(queued_frames_.empty());
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Set the fec group number to the sequence number of the next packet.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fec_group_number_ = sequence_number() + 1;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fec_group_.reset(new QuicFecGroup());
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)
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicPacketCreator::UpdateSequenceNumberLength(
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      QuicPacketSequenceNumber least_packet_awaited_by_peer,
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      QuicByteCount bytes_per_second) {
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1);
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Since the packet creator will not change sequence number length mid FEC
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // group, include the size of an FEC group to be safe.
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const QuicPacketSequenceNumber current_delta =
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      options_.max_packets_per_fec_group + sequence_number_ + 1
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      - least_packet_awaited_by_peer;
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const uint64 congestion_window =
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      bytes_per_second / options_.max_packet_length;
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const uint64 delta = max(current_delta, congestion_window);
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  options_.send_sequence_number_length =
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      QuicFramer::GetMinSequenceNumberLength(delta * 4);
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                              QuicStreamOffset offset) const {
992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return BytesFree() >
1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      QuicFramer::GetMinStreamFrameSize(framer_->version(), id, offset, true);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t QuicPacketCreator::StreamFramePacketOverhead(
1052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    QuicVersion version,
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicGuidLength guid_length,
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool include_version,
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicSequenceNumberLength sequence_number_length,
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    InFecGroup is_in_fec_group) {
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetPacketHeaderSize(guid_length, include_version,
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             sequence_number_length, is_in_fec_group) +
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Assumes this is a stream with a single lone packet.
1132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      QuicFramer::GetMinStreamFrameSize(version, 1u, 0u, true);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                            const IOVector& data,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicStreamOffset offset,
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            bool fin,
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicFrame* frame) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GT(options_.max_packet_length,
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            StreamFramePacketOverhead(
1232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                framer_->version(), PACKET_8BYTE_GUID, kIncludeVersion,
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP));
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!HasRoomForStreamFrame(id, offset)) {
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    LOG(DFATAL) << "No room for Stream frame, BytesFree: " << BytesFree()
127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                << " MinStreamFrameSize: "
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                << QuicFramer::GetMinStreamFrameSize(
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    framer_->version(), id, offset, true);
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (data.Empty()) {
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!fin) {
1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(DFATAL) << "Creating a stream frame with no data or fin.";
1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Create a new packet for the fin, if necessary.
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *frame = QuicFrame(new QuicStreamFrame(id, true, offset, data));
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return 0;
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t free_bytes = BytesFree();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t bytes_consumed = 0;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const size_t data_size = data.TotalBufferSize();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // When a STREAM frame is the last frame in a packet, it consumes two fewer
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // bytes of framing overhead.
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Anytime more data is available than fits in with the extra two bytes,
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the frame will be the last, and up to two extra bytes are consumed.
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(ianswett): If QUIC pads, the 1 byte PADDING frame does not fit when
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // 1 byte is available, because then the STREAM frame isn't the last.
1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The minimum frame size(0 bytes of data) if it's not the last frame.
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      framer_->version(), id, offset, false);
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Check if it's the last frame in the packet.
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (data_size + min_frame_size > free_bytes) {
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // The minimum frame size(0 bytes of data) if it is the last frame.
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    size_t min_last_frame_size = QuicFramer::GetMinStreamFrameSize(
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        framer_->version(), id, offset, true);
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bytes_consumed =
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        min<size_t>(free_bytes - min_last_frame_size, data_size);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_LT(data_size, BytesFree());
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bytes_consumed = data_size;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool set_fin = fin && bytes_consumed == data_size;  // Last frame.
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  IOVector frame_data;
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(),
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    bytes_consumed);
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed);
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data));
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return bytes_consumed;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrameWithNotifier(
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicStreamId id,
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const IOVector& data,
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicStreamOffset offset,
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool fin,
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicAckNotifier* notifier,
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicFrame* frame) {
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  size_t bytes_consumed = CreateStreamFrame(id, data, offset, fin, frame);
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The frame keeps track of the QuicAckNotifier until it is serialized into
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // a packet. At that point the notifier is informed of the sequence number
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // of the packet that this frame was eventually sent in.
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  frame->stream_frame->notifier = notifier;
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return bytes_consumed;
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SerializedPacket QuicPacketCreator::ReserializeAllFrames(
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const QuicFrames& frames,
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    QuicSequenceNumberLength original_length) {
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicSequenceNumberLength start_length = sequence_number_length_;
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicSequenceNumberLength start_options_length =
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      options_.send_sequence_number_length;
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicFecGroupNumber start_fec_group = fec_group_number_;
20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const size_t start_max_packets_per_fec_group =
20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      options_.max_packets_per_fec_group;
20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Temporarily set the sequence number length and disable FEC.
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sequence_number_length_ = original_length;
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  options_.send_sequence_number_length = original_length;
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fec_group_number_ = 0;
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  options_.max_packets_per_fec_group = 0;
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Serialize the packet and restore the fec and sequence number length state.
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SerializedPacket serialized_packet = SerializeAllFrames(frames);
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sequence_number_length_ = start_length;
2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  options_.send_sequence_number_length = start_options_length;
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fec_group_number_ = start_fec_group;
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  options_.max_packets_per_fec_group = start_max_packets_per_fec_group;
21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return serialized_packet;
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeAllFrames(
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicFrames& frames) {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames from SendStreamData()[send_stream_should_flush_ == false &&
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // data.empty() == true] and retransmit due to RTO.
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (frames.empty()) {
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    LOG(DFATAL) << "Attempt to serialize empty packet";
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < frames.size(); ++i) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success = AddFrame(frames[i], false);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(success);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet = SerializePacket();
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(packet.retransmittable_frames == NULL);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return packet;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::HasPendingFrames() {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !queued_frames_.empty();
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::BytesFree() const {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t max_plaintext_size =
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer_->GetMaxPlaintextSize(options_.max_packet_length);
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(max_plaintext_size, PacketSize());
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If the last frame in the packet is a stream frame, then it can be
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // two bytes smaller than if it were not the last.  So this means that
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // there are two fewer bytes available to the next frame in this case.
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool has_trailing_stream_frame =
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t expanded_packet_size = PacketSize() +
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      (has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0);
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (expanded_packet_size  >= max_plaintext_size) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return max_plaintext_size - expanded_packet_size;
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)size_t QuicPacketCreator::PacketSize() const {
2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (queued_frames_.empty()) {
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Only adjust the sequence number length when the FEC group is not open,
2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // to ensure no packets in a group are too large.
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (fec_group_.get() == NULL ||
2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        fec_group_->NumReceivedPackets() == 0) {
2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      sequence_number_length_ = options_.send_sequence_number_length;
2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       send_version_in_packet_,
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       sequence_number_length_,
27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                       options_.max_packets_per_fec_group == 0 ?
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                           NOT_IN_FEC_GROUP : IN_FEC_GROUP);
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return packet_size_;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddFrame(frame, true);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializePacket() {
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (queued_frames_.empty()) {
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    LOG(DFATAL) << "Attempt to serialize empty packet";
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FillPacketHeader(fec_group_number_, false, false, &header);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (FLAGS_pad_quic_handshake_packets) {
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    MaybeAddPadding();
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t max_plaintext_size =
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      framer_->GetMaxPlaintextSize(options_.max_packet_length);
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(max_plaintext_size, packet_size_);
2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // ACK and CONNECTION_CLOSE Frames will be truncated only if they're
2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // the first frame in the packet.  If truncation is to occur, then
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // GetSerializedFrameLength will have returned all bytes free.
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool possibly_truncated =
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      packet_size_ != max_plaintext_size ||
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      queued_frames_.size() != 1 ||
3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      (queued_frames_.back().type == ACK_FRAME ||
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       queued_frames_.back().type == CONNECTION_CLOSE_FRAME);
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SerializedPacket serialized =
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      framer_->BuildDataPacket(header, queued_frames_, packet_size_);
3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!serialized.packet) {
3060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(DFATAL) << "Failed to serialize " << queued_frames_.size()
3070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                << " frames.";
3080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Because of possible truncation, we can't be confident that our
3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // packet size calculation worked correctly.
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!possibly_truncated)
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK_EQ(packet_size_, serialized.packet->length());
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  packet_size_ = 0;
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  queued_frames_.clear();
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized.retransmittable_frames = queued_retransmittable_frames_.release();
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeFec() {
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(0u, fec_group_->NumReceivedPackets());
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FillPacketHeader(fec_group_number_, true,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   fec_group_->entropy_parity(), &header);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFecData fec_data;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.fec_group = fec_group_->min_protected_packet();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.redundancy = fec_group_->payload_parity();
3292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_group_.reset(NULL);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_group_number_ = 0;
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  packet_size_ = 0;
3330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!serialized.packet) {
3340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(DFATAL) << "Failed to serialize fec packet for group:"
3350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                << fec_data.fec_group;
3360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(options_.max_packet_length, serialized.packet->length());
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeConnectionClose(
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicConnectionCloseFrame* close_frame) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(close_frame));
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SerializeAllFrames(frames);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
349558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const QuicVersionVector& supported_versions) {
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(is_server_);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketPublicHeader header;
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.guid = guid_;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.reset_flag = false;
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.version_flag = true;
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.versions = supported_versions;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket* encrypted =
3572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      framer_->BuildVersionNegotiationPacket(header, supported_versions);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(encrypted);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(options_.max_packet_length, encrypted->length());
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return encrypted;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool fec_flag,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool fec_entropy_flag,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         QuicPacketHeader* header) {
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.guid = guid_;
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.reset_flag = false;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.version_flag = send_version_in_packet_;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->fec_flag = fec_flag;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->packet_sequence_number = ++sequence_number_;
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  header->public_header.sequence_number_length = sequence_number_length_;
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool entropy_flag;
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (header->packet_sequence_number == 1) {
376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(!fec_flag);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(satyamshekhar): No entropy in the first message.
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For crypto tests to pass. Fix this by using deterministic QuicRandom.
379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    entropy_flag = 0;
380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (fec_flag) {
381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // FEC packets don't have an entropy of their own. Entropy flag for FEC
382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // packets is the XOR of entropy of previous packets.
383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    entropy_flag = fec_entropy_flag;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    entropy_flag = random_generator_->RandBool();
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header->entropy_flag = entropy_flag;
388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->fec_group = fec_group;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME &&
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame.type != PADDING_FRAME;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool save_retransmittable_frames) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t frame_len = framer_->GetSerializedFrameLength(
4000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      frame, BytesFree(), queued_frames_.empty(), true,
4010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      options()->send_sequence_number_length);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (frame_len == 0) {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_LT(0u, packet_size_);
40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MaybeStartFEC();
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  packet_size_ += frame_len;
4081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If the last frame in the packet was a stream frame, then once we add the
4091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // new frame it's serialization will be two bytes larger.
4101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME) {
4111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    packet_size_ += kQuicStreamPayloadLengthSize;
4121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (save_retransmittable_frames && ShouldRetransmit(frame)) {
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (queued_retransmittable_frames_.get() == NULL) {
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_retransmittable_frames_.reset(new RetransmittableFrames());
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame.type == STREAM_FRAME) {
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame));
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddNonStreamFrame(frame));
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queued_frames_.push_back(frame);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicPacketCreator::MaybeAddPadding() {
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (BytesFree() == 0) {
4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Don't pad full packets.
4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If any of the frames in the current packet are on the crypto stream
4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // then they contain handshake messagses, and we should pad them.
4381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool is_handshake = false;
4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < queued_frames_.size(); ++i) {
4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (queued_frames_[i].type == STREAM_FRAME &&
4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        queued_frames_[i].stream_frame->stream_id == kCryptoStreamId) {
4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      is_handshake = true;
4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      break;
4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!is_handshake) {
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  QuicPaddingFrame padding;
4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool success = AddFrame(QuicFrame(&padding), false);
4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(success);
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
456