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