quic_packet_creator.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A QuicRandom wrapper that gets a bucket of entropy and distributes it
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// class if single bit randomness is needed elsewhere.
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class QuicRandomBoolSource {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // random: Source of entropy. Not owned.
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit QuicRandomBoolSource(QuicRandom* random)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : random_(random),
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bit_bucket_(0),
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bit_mask_(0) {}
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~QuicRandomBoolSource() {}
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns the next random bit from the bucket.
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool RandBool() {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (bit_mask_ == 0) {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bit_bucket_ = random_->RandUint64();
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bit_mask_ = 1;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool result = ((bit_bucket_ & bit_mask_) != 0);
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bit_mask_ <<= 1;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return result;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Source of entropy.
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicRandom* random_;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Stored random bits.
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64 bit_bucket_;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The next available bit has "1" in the mask. Zero means empty bucket.
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64 bit_mask_;
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuicRandomBoolSource);
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     QuicFramer* framer,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     QuicRandom* random_generator,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     bool is_server)
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : connection_id_(connection_id),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer_(framer),
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      random_bool_source_(new QuicRandomBoolSource(random_generator)),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence_number_(0),
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fec_group_number_(0),
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_server_(is_server),
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      send_version_in_packet_(!is_server),
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      sequence_number_length_(options_.send_sequence_number_length),
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      packet_size_(0) {
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  framer_->set_fec_builder(this);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::~QuicPacketCreator() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::OnBuiltFecProtectedPayload(
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicPacketHeader& header, StringPiece payload) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fec_group_.get()) {
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK_NE(0u, header.fec_group);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_group_->Update(header, payload);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 &&
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (force_close ||
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::MaybeStartFEC() {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Don't send FEC until QUIC_VERSION_15.
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (framer_->version() != QUIC_VERSION_13 &&
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) {
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(queued_frames_.empty());
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Set the fec group number to the sequence number of the next packet.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fec_group_number_ = sequence_number() + 1;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fec_group_.reset(new QuicFecGroup());
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stops serializing version of the protocol in packets sent after this call.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A packet that is already open might send kQuicVersionSize bytes less than the
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maximum packet size if we stop sending version before it is serialized.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::StopSendingVersion() {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(send_version_in_packet_);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  send_version_in_packet_ = false;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (packet_size_ > 0) {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_LT(kQuicVersionSize, packet_size_);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    packet_size_ -= kQuicVersionSize;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicPacketCreator::UpdateSequenceNumberLength(
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      QuicPacketSequenceNumber least_packet_awaited_by_peer,
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      QuicByteCount bytes_per_second) {
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1);
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Since the packet creator will not change sequence number length mid FEC
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // group, include the size of an FEC group to be safe.
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const QuicPacketSequenceNumber current_delta =
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      options_.max_packets_per_fec_group + sequence_number_ + 1
122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      - least_packet_awaited_by_peer;
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const uint64 congestion_window =
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      bytes_per_second / options_.max_packet_length;
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const uint64 delta = max(current_delta, congestion_window);
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  options_.send_sequence_number_length =
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      QuicFramer::GetMinSequenceNumberLength(delta * 4);
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
1322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                              QuicStreamOffset offset) const {
1332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return BytesFree() >
1342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      QuicFramer::GetMinStreamFrameSize(framer_->version(), id, offset, true);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t QuicPacketCreator::StreamFramePacketOverhead(
1392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    QuicVersion version,
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuicConnectionIdLength connection_id_length,
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool include_version,
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    QuicSequenceNumberLength sequence_number_length,
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    InFecGroup is_in_fec_group) {
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetPacketHeaderSize(connection_id_length, include_version,
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             sequence_number_length, is_in_fec_group) +
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Assumes this is a stream with a single lone packet.
1472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      QuicFramer::GetMinStreamFrameSize(version, 1u, 0u, true);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                            const IOVector& data,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicStreamOffset offset,
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            bool fin,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            QuicFrame* frame) {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GT(options_.max_packet_length,
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            StreamFramePacketOverhead(
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP));
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "No room for Stream frame, BytesFree: " << BytesFree()
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << " MinStreamFrameSize: "
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << QuicFramer::GetMinStreamFrameSize(
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          framer_->version(), id, offset, true);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (data.Empty()) {
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LOG_IF(DFATAL, !fin)
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        << "Creating a stream frame with no data or fin.";
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Create a new packet for the fin, if necessary.
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *frame = QuicFrame(new QuicStreamFrame(id, true, offset, data));
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return 0;
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t free_bytes = BytesFree();
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t bytes_consumed = 0;
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const size_t data_size = data.TotalBufferSize();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // When a STREAM frame is the last frame in a packet, it consumes two fewer
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // bytes of framing overhead.
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Anytime more data is available than fits in with the extra two bytes,
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the frame will be the last, and up to two extra bytes are consumed.
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(ianswett): If QUIC pads, the 1 byte PADDING frame does not fit when
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // 1 byte is available, because then the STREAM frame isn't the last.
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The minimum frame size(0 bytes of data) if it's not the last frame.
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      framer_->version(), id, offset, false);
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Check if it's the last frame in the packet.
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (data_size + min_frame_size > free_bytes) {
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // The minimum frame size(0 bytes of data) if it is the last frame.
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    size_t min_last_frame_size = QuicFramer::GetMinStreamFrameSize(
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        framer_->version(), id, offset, true);
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bytes_consumed =
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        min<size_t>(free_bytes - min_last_frame_size, data_size);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_LT(data_size, BytesFree());
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bytes_consumed = data_size;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool set_fin = fin && bytes_consumed == data_size;  // Last frame.
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  IOVector frame_data;
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(),
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    bytes_consumed);
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed);
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return bytes_consumed;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrameWithNotifier(
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicStreamId id,
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const IOVector& data,
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicStreamOffset offset,
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool fin,
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicAckNotifier* notifier,
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QuicFrame* frame) {
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  size_t bytes_consumed = CreateStreamFrame(id, data, offset, fin, frame);
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The frame keeps track of the QuicAckNotifier until it is serialized into
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // a packet. At that point the notifier is informed of the sequence number
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // of the packet that this frame was eventually sent in.
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  frame->stream_frame->notifier = notifier;
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return bytes_consumed;
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SerializedPacket QuicPacketCreator::ReserializeAllFrames(
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const QuicFrames& frames,
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    QuicSequenceNumberLength original_length) {
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicSequenceNumberLength start_length = sequence_number_length_;
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicSequenceNumberLength start_options_length =
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      options_.send_sequence_number_length;
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicFecGroupNumber start_fec_group = fec_group_number_;
23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const size_t start_max_packets_per_fec_group =
23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      options_.max_packets_per_fec_group;
23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Temporarily set the sequence number length and disable FEC.
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sequence_number_length_ = original_length;
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  options_.send_sequence_number_length = original_length;
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fec_group_number_ = 0;
23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  options_.max_packets_per_fec_group = 0;
24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Serialize the packet and restore the fec and sequence number length state.
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SerializedPacket serialized_packet = SerializeAllFrames(frames);
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sequence_number_length_ = start_length;
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  options_.send_sequence_number_length = start_options_length;
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fec_group_number_ = start_fec_group;
24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  options_.max_packets_per_fec_group = start_max_packets_per_fec_group;
24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return serialized_packet;
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeAllFrames(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const QuicFrames& frames) {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames from SendStreamData()[send_stream_should_flush_ == false &&
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // data.empty() == true] and retransmit due to RTO.
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, frames.empty())
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Attempt to serialize empty packet";
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < frames.size(); ++i) {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success = AddFrame(frames[i], false);
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(success);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet = SerializePacket();
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(packet.retransmittable_frames == NULL);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return packet;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::HasPendingFrames() {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !queued_frames_.empty();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::BytesFree() const {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t max_plaintext_size =
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer_->GetMaxPlaintextSize(options_.max_packet_length);
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(max_plaintext_size, PacketSize());
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If the last frame in the packet is a stream frame, then it can be
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // two bytes smaller than if it were not the last.  So this means that
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // there are two fewer bytes available to the next frame in this case.
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool has_trailing_stream_frame =
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t expanded_packet_size = PacketSize() +
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      (has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0);
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (expanded_packet_size  >= max_plaintext_size) {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return max_plaintext_size - expanded_packet_size;
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)size_t QuicPacketCreator::PacketSize() const {
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (queued_frames_.empty()) {
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Only adjust the sequence number length when the FEC group is not open,
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // to ensure no packets in a group are too large.
2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (fec_group_.get() == NULL ||
2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        fec_group_->NumReceivedPackets() == 0) {
2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      sequence_number_length_ = options_.send_sequence_number_length;
2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    packet_size_ = GetPacketHeaderSize(options_.send_connection_id_length,
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       send_version_in_packet_,
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       sequence_number_length_,
30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                       options_.max_packets_per_fec_group == 0 ?
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                           NOT_IN_FEC_GROUP : IN_FEC_GROUP);
3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return packet_size_;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddFrame(frame, true);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializePacket() {
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, queued_frames_.empty())
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Attempt to serialize empty packet";
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FillPacketHeader(fec_group_number_, false, &header);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MaybeAddPadding();
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t max_plaintext_size =
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      framer_->GetMaxPlaintextSize(options_.max_packet_length);
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(max_plaintext_size, packet_size_);
3230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // ACK and CONNECTION_CLOSE Frames will be truncated only if they're
3240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // the first frame in the packet.  If truncation is to occur, then
3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // GetSerializedFrameLength will have returned all bytes free.
3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool possibly_truncated =
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      packet_size_ != max_plaintext_size ||
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      queued_frames_.size() != 1 ||
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      (queued_frames_.back().type == ACK_FRAME ||
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       queued_frames_.back().type == CONNECTION_CLOSE_FRAME);
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SerializedPacket serialized =
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      framer_->BuildDataPacket(header, queued_frames_, packet_size_);
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, !serialized.packet)
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Failed to serialize " << queued_frames_.size() << " frames.";
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Because of possible truncation, we can't be confident that our
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // packet size calculation worked correctly.
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!possibly_truncated)
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK_EQ(packet_size_, serialized.packet->length());
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  packet_size_ = 0;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  queued_frames_.clear();
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized.retransmittable_frames = queued_retransmittable_frames_.release();
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeFec() {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(0u, fec_group_->NumReceivedPackets());
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, queued_frames_.size());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FillPacketHeader(fec_group_number_, true, &header);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFecData fec_data;
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.fec_group = fec_group_->min_protected_packet();
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_data.redundancy = fec_group_->payload_parity();
3542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_group_.reset(NULL);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fec_group_number_ = 0;
3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  packet_size_ = 0;
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, !serialized.packet)
359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Failed to serialize fec packet for group:" << fec_data.fec_group;
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(options_.max_packet_length, serialized.packet->length());
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return serialized;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeConnectionClose(
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicConnectionCloseFrame* close_frame) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frames.push_back(QuicFrame(close_frame));
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SerializeAllFrames(frames);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
372558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const QuicVersionVector& supported_versions) {
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(is_server_);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketPublicHeader header;
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header.connection_id = connection_id_;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.reset_flag = false;
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.version_flag = true;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header.versions = supported_versions;
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicEncryptedPacket* encrypted =
3802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      framer_->BuildVersionNegotiationPacket(header, supported_versions);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(encrypted);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(options_.max_packet_length, encrypted->length());
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return encrypted;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool fec_flag,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         QuicPacketHeader* header) {
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  header->public_header.connection_id = connection_id_;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.reset_flag = false;
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->public_header.version_flag = send_version_in_packet_;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  header->fec_flag = fec_flag;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->packet_sequence_number = ++sequence_number_;
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  header->public_header.sequence_number_length = sequence_number_length_;
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  header->entropy_flag = random_bool_source_->RandBool();
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->fec_group = fec_group;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switch (frame.type) {
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case ACK_FRAME:
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case CONGESTION_FEEDBACK_FRAME:
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case PADDING_FRAME:
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case STOP_WAITING_FRAME:
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    default:
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return true;
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool save_retransmittable_frames) {
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Adding frame: " << frame;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t frame_len = framer_->GetSerializedFrameLength(
4160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      frame, BytesFree(), queued_frames_.empty(), true,
4170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      options()->send_sequence_number_length);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (frame_len == 0) {
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_LT(0u, packet_size_);
42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MaybeStartFEC();
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  packet_size_ += frame_len;
4241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If the last frame in the packet was a stream frame, then once we add the
4251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // new frame it's serialization will be two bytes larger.
4261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME) {
4271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    packet_size_ += kQuicStreamPayloadLengthSize;
4281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (save_retransmittable_frames && ShouldRetransmit(frame)) {
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (queued_retransmittable_frames_.get() == NULL) {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_retransmittable_frames_.reset(new RetransmittableFrames());
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame.type == STREAM_FRAME) {
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame));
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_frames_.push_back(
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          queued_retransmittable_frames_->AddNonStreamFrame(frame));
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queued_frames_.push_back(frame);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicPacketCreator::MaybeAddPadding() {
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (BytesFree() == 0) {
4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Don't pad full packets.
4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If any of the frames in the current packet are on the crypto stream
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // then they contain handshake messagses, and we should pad them.
4541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool is_handshake = false;
4551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < queued_frames_.size(); ++i) {
4561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (queued_frames_[i].type == STREAM_FRAME &&
4571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        queued_frames_[i].stream_frame->stream_id == kCryptoStreamId) {
4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      is_handshake = true;
4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      break;
4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!is_handshake) {
4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  QuicPaddingFrame padding;
4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool success = AddFrame(QuicFrame(&padding), false);
4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(success);
4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
472