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)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_random.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/quic/quic_ack_notifier.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_fec_group.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::make_pair;
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using std::max;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::pair;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Default max packets in an FEC group.
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const size_t kDefaultMaxPacketsPerFecGroup = 10;
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Lowest max packets in an FEC group.
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const size_t kLowestMaxPacketsPerFecGroup = 2;
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A QuicRandom wrapper that gets a bucket of entropy and distributes it
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// class if single bit randomness is needed elsewhere.
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class QuicRandomBoolSource {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // random: Source of entropy. Not owned.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit QuicRandomBoolSource(QuicRandom* random)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : random_(random),
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bit_bucket_(0),
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bit_mask_(0) {}
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~QuicRandomBoolSource() {}
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns the next random bit from the bucket.
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool RandBool() {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (bit_mask_ == 0) {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bit_bucket_ = random_->RandUint64();
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bit_mask_ = 1;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool result = ((bit_bucket_ & bit_mask_) != 0);
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bit_mask_ <<= 1;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return result;
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Source of entropy.
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicRandom* random_;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Stored random bits.
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64 bit_bucket_;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The next available bit has "1" in the mask. Zero means empty bucket.
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64 bit_mask_;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuicRandomBoolSource);
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     QuicFramer* framer,
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                     QuicRandom* random_generator)
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : connection_id_(connection_id),
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      encryption_level_(ENCRYPTION_NONE),
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer_(framer),
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      random_bool_source_(new QuicRandomBoolSource(random_generator)),
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence_number_(0),
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      should_fec_protect_(false),
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fec_group_number_(0),
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      send_version_in_packet_(!framer->is_server()),
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      max_packet_length_(kDefaultMaxPacketSize),
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup),
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      connection_id_length_(PACKET_8BYTE_CONNECTION_ID),
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      next_sequence_number_length_(PACKET_1BYTE_SEQUENCE_NUMBER),
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      sequence_number_length_(next_sequence_number_length_),
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      packet_size_(0) {
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  framer_->set_fec_builder(this);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::~QuicPacketCreator() {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::OnBuiltFecProtectedPayload(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicPacketHeader& header, StringPiece payload) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fec_group_.get()) {
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK_NE(0u, header.fec_group);
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    fec_group_->Update(encryption_level_, header, payload);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void QuicPacketCreator::set_max_packets_per_fec_group(
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_t max_packets_per_fec_group) {
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup,
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   max_packets_per_fec_group);
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_LT(0u, max_packets_per_fec_group_);
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(!HasPendingFrames());
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 &&
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      (force_close || fec_group_->NumReceivedPackets() >=
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      max_packets_per_fec_group_);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool QuicPacketCreator::IsFecGroupOpen() const {
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return fec_group_.get() != NULL;
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void QuicPacketCreator::StartFecProtectingPackets() {
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!IsFecEnabled()) {
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled.";
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(jri): This currently requires that the generator flush out any
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // pending frames when FEC protection is turned on. If current packet can be
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // converted to an FEC protected packet, do it. This will require the
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // generator to check if the resulting expansion still allows the incoming
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // frame to be added to the packet.
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (HasPendingFrames()) {
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(DFATAL) << "Cannot start FEC protection with pending frames.";
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!should_fec_protect_);
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  should_fec_protect_ = true;
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void QuicPacketCreator::StopFecProtectingPackets() {
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (fec_group_.get() != NULL) {
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(DFATAL) << "Cannot stop FEC protection with open FEC group.";
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(should_fec_protect_);
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  should_fec_protect_ = false;
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  fec_group_number_ = 0;
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool QuicPacketCreator::IsFecProtected() const {
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return should_fec_protect_;
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool QuicPacketCreator::IsFecEnabled() const {
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return max_packets_per_fec_group_ > 0;
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (fec_group_.get() != NULL) {
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't update any lengths when an FEC group is open, to ensure same
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // packet header size in all packets within a group.
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return IN_FEC_GROUP;
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!queued_frames_.empty()) {
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't change creator state if there are frames queued.
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Update sequence number length only on packet and FEC group boundaries.
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  sequence_number_length_ = next_sequence_number_length_;
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!should_fec_protect_) {
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NOT_IN_FEC_GROUP;
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Start a new FEC group since protection is on. Set the fec group number to
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the sequence number of the next packet.
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  fec_group_number_ = sequence_number() + 1;
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  fec_group_.reset(new QuicFecGroup());
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return IN_FEC_GROUP;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stops serializing version of the protocol in packets sent after this call.
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A packet that is already open might send kQuicVersionSize bytes less than the
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maximum packet size if we stop sending version before it is serialized.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::StopSendingVersion() {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(send_version_in_packet_);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  send_version_in_packet_ = false;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (packet_size_ > 0) {
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_LT(kQuicVersionSize, packet_size_);
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    packet_size_ -= kQuicVersionSize;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicPacketCreator::UpdateSequenceNumberLength(
189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      QuicPacketSequenceNumber least_packet_awaited_by_peer,
1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      QuicByteCount congestion_window) {
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1);
192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Since the packet creator will not change sequence number length mid FEC
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // group, include the size of an FEC group to be safe.
194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const QuicPacketSequenceNumber current_delta =
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      max_packets_per_fec_group_ + sequence_number_ + 1
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      - least_packet_awaited_by_peer;
1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const uint64 congestion_window_packets =
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      congestion_window / max_packet_length_;
1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const uint64 delta = max(current_delta, congestion_window_packets);
20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  next_sequence_number_length_ =
2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      QuicFramer::GetMinSequenceNumberLength(delta * 4);
202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
2052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                              QuicStreamOffset offset) const {
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // TODO(jri): This is a simple safe decision for now, but make
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // is_in_fec_group a parameter. Same as with all public methods in
208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // QuicPacketCreator.
2092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return BytesFree() >
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      QuicFramer::GetMinStreamFrameSize(id, offset, true,
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        should_fec_protect_ ? IN_FEC_GROUP :
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                              NOT_IN_FEC_GROUP);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t QuicPacketCreator::StreamFramePacketOverhead(
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuicConnectionIdLength connection_id_length,
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool include_version,
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicSequenceNumberLength sequence_number_length,
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    QuicStreamOffset offset,
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    InFecGroup is_in_fec_group) {
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetPacketHeaderSize(connection_id_length, include_version,
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             sequence_number_length, is_in_fec_group) +
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Assumes this is a stream with a single lone packet.
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                            const IOVector& data,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicStreamOffset offset,
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            bool fin,
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicFrame* frame) {
23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK_GT(max_packet_length_, StreamFramePacketOverhead(
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                PACKET_6BYTE_SEQUENCE_NUMBER, offset, IN_FEC_GROUP));
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "No room for Stream frame, BytesFree: " << BytesFree()
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << " MinStreamFrameSize: "
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (data.Empty()) {
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LOG_IF(DFATAL, !fin)
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        << "Creating a stream frame with no data or fin.";
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Create a new packet for the fin, if necessary.
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *frame = QuicFrame(new QuicStreamFrame(id, true, offset, data));
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return 0;
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const size_t data_size = data.TotalBufferSize();
253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      id, offset, /* last_frame_in_packet= */ true, is_in_fec_group);
255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool set_fin = fin && bytes_consumed == data_size;  // Last frame.
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  IOVector frame_data;
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(),
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    bytes_consumed);
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed);
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data));
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return bytes_consumed;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrameWithNotifier(
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicStreamId id,
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const IOVector& data,
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicStreamOffset offset,
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool fin,
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicAckNotifier* notifier,
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicFrame* frame) {
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  size_t bytes_consumed = CreateStreamFrame(id, data, offset, fin, frame);
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The frame keeps track of the QuicAckNotifier until it is serialized into
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // a packet. At that point the notifier is informed of the sequence number
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // of the packet that this frame was eventually sent in.
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  frame->stream_frame->notifier = notifier;
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return bytes_consumed;
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SerializedPacket QuicPacketCreator::ReserializeAllFrames(
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const QuicFrames& frames,
2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    QuicSequenceNumberLength original_length) {
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(fec_group_.get() == NULL);
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const QuicSequenceNumberLength saved_length = sequence_number_length_;
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const QuicSequenceNumberLength saved_next_length =
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      next_sequence_number_length_;
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const bool saved_should_fec_protect = should_fec_protect_;
29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Temporarily set the sequence number length and stop FEC protection.
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sequence_number_length_ = original_length;
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  next_sequence_number_length_ = original_length;
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  should_fec_protect_ = false;
29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Serialize the packet and restore the FEC and sequence number length state.
2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SerializedPacket serialized_packet = SerializeAllFrames(frames);
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  sequence_number_length_ = saved_length;
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  next_sequence_number_length_ = saved_next_length;
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  should_fec_protect_ = saved_should_fec_protect;
30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return serialized_packet;
3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeAllFrames(
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicFrames& frames) {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames from SendStreamData()[send_stream_should_flush_ == false &&
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // data.empty() == true] and retransmit due to RTO.
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, frames.empty())
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Attempt to serialize empty packet";
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < frames.size(); ++i) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success = AddFrame(frames[i], false);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(success);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet = SerializePacket();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(packet.retransmittable_frames == NULL);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return packet;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool QuicPacketCreator::HasPendingFrames() const {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !queued_frames_.empty();
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
3286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return queued_retransmittable_frames_.get() != NULL &&
3296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      !queued_retransmittable_frames_->frames().empty();
3306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochsize_t QuicPacketCreator::ExpansionOnNewFrame() const {
333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // If packet is FEC protected, there's no expansion.
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (should_fec_protect_) {
335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return 0;
336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // If the last frame in the packet is a stream frame, then it will expand to
338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // include the stream_length field when a new frame is added.
339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool has_trailing_stream_frame =
340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
341c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0;
342c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
343c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::BytesFree() const {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t max_plaintext_size =
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      framer_->GetMaxPlaintextSize(max_packet_length_);
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(max_plaintext_size, PacketSize());
348c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return max_plaintext_size - min(max_plaintext_size, PacketSize()
349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                  + ExpansionOnNewFrame());
3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)size_t QuicPacketCreator::PacketSize() const {
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!queued_frames_.empty()) {
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return packet_size_;
3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (fec_group_.get() == NULL) {
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Update sequence number length on packet and FEC boundary.
35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sequence_number_length_ = next_sequence_number_length_;
35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  packet_size_ = GetPacketHeaderSize(
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      connection_id_length_, send_version_in_packet_, sequence_number_length_,
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return packet_size_;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddFrame(frame, true);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializePacket() {
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, queued_frames_.empty())
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Attempt to serialize empty packet";
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_GE(sequence_number_ + 1, fec_group_number_);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MaybeAddPadding();
3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t max_plaintext_size =
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      framer_->GetMaxPlaintextSize(max_packet_length_);
3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(max_plaintext_size, packet_size_);
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // ACK Frames will be truncated due to length only if they're the only frame
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // in the packet, and if packet_size_ was set to max_plaintext_size. If
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // truncation due to length occurred, then GetSerializedFrameLength will have
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // returned all bytes free.
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool possibly_truncated_by_length = packet_size_ == max_plaintext_size &&
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      queued_frames_.size() == 1 &&
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      queued_frames_.back().type == ACK_FRAME;
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SerializedPacket serialized =
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      framer_->BuildDataPacket(header, queued_frames_, packet_size_);
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, !serialized.packet)
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Failed to serialize " << queued_frames_.size() << " frames.";
3931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Because of possible truncation, we can't be confident that our
3941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // packet size calculation worked correctly.
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!possibly_truncated_by_length) {
3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK_EQ(packet_size_, serialized.packet->length());
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  packet_size_ = 0;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  queued_frames_.clear();
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized.retransmittable_frames = queued_retransmittable_frames_.release();
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeFec() {
4050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) {
4060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group.";
4070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // TODO(jri): Make this a public method of framer?
4080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL);
4090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return kNoPacket;
4100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FillPacketHeader(fec_group_number_, true, &header);
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFecData fec_data;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.fec_group = fec_group_->min_protected_packet();
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.redundancy = fec_group_->payload_parity();
4172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_group_.reset(NULL);
4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  packet_size_ = 0;
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, !serialized.packet)
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Failed to serialize fec packet for group:" << fec_data.fec_group;
42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK_GE(max_packet_length_, serialized.packet->length());
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeConnectionClose(
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicConnectionCloseFrame* close_frame) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(close_frame));
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SerializeAllFrames(frames);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
434558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const QuicVersionVector& supported_versions) {
435f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(framer_->is_server());
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketPublicHeader header;
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.connection_id = connection_id_;
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.reset_flag = false;
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.version_flag = true;
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.versions = supported_versions;
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket* encrypted =
4422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      framer_->BuildVersionNegotiationPacket(header, supported_versions);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(encrypted);
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK_GE(max_packet_length_, encrypted->length());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return encrypted;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool fec_flag,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         QuicPacketHeader* header) {
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header->public_header.connection_id = connection_id_;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.reset_flag = false;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.version_flag = send_version_in_packet_;
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->fec_flag = fec_flag;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->packet_sequence_number = ++sequence_number_;
4563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  header->public_header.sequence_number_length = sequence_number_length_;
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header->entropy_flag = random_bool_source_->RandBool();
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->fec_group = fec_group;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switch (frame.type) {
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case ACK_FRAME:
465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case CONGESTION_FEEDBACK_FRAME:
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case PADDING_FRAME:
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case STOP_WAITING_FRAME:
468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    default:
470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return true;
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool save_retransmittable_frames) {
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Adding frame: " << frame;
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t frame_len = framer_->GetSerializedFrameLength(
480c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      sequence_number_length_);
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (frame_len == 0) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_LT(0u, packet_size_);
486c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  packet_size_ += ExpansionOnNewFrame() + frame_len;
487c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (save_retransmittable_frames && ShouldRetransmit(frame)) {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (queued_retransmittable_frames_.get() == NULL) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_retransmittable_frames_.reset(new RetransmittableFrames());
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame.type == STREAM_FRAME) {
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame));
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddNonStreamFrame(frame));
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queued_frames_.push_back(frame);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicPacketCreator::MaybeAddPadding() {
50629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  if (BytesFree() == 0) {
50729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    // Don't pad full packets.
5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
51029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch
51129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // Since ReserializeAllFrames does not populate queued_retransmittable_frames_
51229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // it's not sufficient to simply call
51329b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // queued_retransmittable_frames_->HasCryptoHandshake().
51429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // TODO(rch): we should really make ReserializeAllFrames not be a special
51529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // case!
51629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch
51729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // If any of the frames in the current packet are on the crypto stream
51829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // then they contain handshake messagses, and we should pad them.
51929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  bool is_handshake = false;
52029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  for (const QuicFrame& frame : queued_frames_) {
52129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    if (frame.type == STREAM_FRAME &&
52229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch        frame.stream_frame->stream_id == kCryptoStreamId) {
52329b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch      is_handshake = true;
52429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch      break;
52529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    }
5261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
52729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  if (!is_handshake) {
5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
5291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
53029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch
5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  QuicPaddingFrame padding;
5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool success = AddFrame(QuicFrame(&padding), false);
5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(success);
5341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
537