quic_packet_creator.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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) 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochInFecGroup QuicPacketCreator::MaybeStartFEC() { 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (IsFecEnabled() && fec_group_.get() == NULL) { 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(queued_frames_.empty()); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set the fec group number to the sequence number of the next packet. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_number_ = sequence_number() + 1; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_.reset(new QuicFecGroup()); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stops serializing version of the protocol in packets sent after this call. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A packet that is already open might send kQuicVersionSize bytes less than the 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// maximum packet size if we stop sending version before it is serialized. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::StopSendingVersion() { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(send_version_in_packet_); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) send_version_in_packet_ = false; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (packet_size_ > 0) { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(kQuicVersionSize, packet_size_); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) packet_size_ -= kQuicVersionSize; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicPacketCreator::UpdateSequenceNumberLength( 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) QuicPacketSequenceNumber least_packet_awaited_by_peer, 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicByteCount congestion_window) { 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1); 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Since the packet creator will not change sequence number length mid FEC 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // group, include the size of an FEC group to be safe. 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const QuicPacketSequenceNumber current_delta = 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) options_.max_packets_per_fec_group + sequence_number_ + 1 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) - least_packet_awaited_by_peer; 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const uint64 congestion_window_packets = 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch congestion_window / options_.max_packet_length; 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const uint64 delta = max(current_delta, congestion_window_packets); 1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) options_.send_sequence_number_length = 1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) QuicFramer::GetMinSequenceNumberLength(delta * 4); 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, 1302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch QuicStreamOffset offset) const { 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(jri): This is a simple safe decision for now, but make 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // is_in_fec_group a parameter. Same as with all public methods in 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // QuicPacketCreator. 1342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return BytesFree() > 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch QuicFramer::GetMinStreamFrameSize(framer_->version(), id, offset, true, 1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IsFecEnabled()); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t QuicPacketCreator::StreamFramePacketOverhead( 1412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch QuicVersion version, 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionIdLength connection_id_length, 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool include_version, 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicSequenceNumberLength sequence_number_length, 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) InFecGroup is_in_fec_group) { 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return GetPacketHeaderSize(connection_id_length, include_version, 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sequence_number_length, is_in_fec_group) + 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Assumes this is a stream with a single lone packet. 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch QuicFramer::GetMinStreamFrameSize(version, 1u, 0u, true, is_in_fec_group); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const IOVector& data, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicStreamOffset offset, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicFrame* frame) { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(options_.max_packet_length, 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StreamFramePacketOverhead( 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP)); 161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch InFecGroup is_in_fec_group = MaybeStartFEC(); 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "No room for Stream frame, BytesFree: " << BytesFree() 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " MinStreamFrameSize: " 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << QuicFramer::GetMinStreamFrameSize( 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch framer_->version(), id, offset, true, is_in_fec_group); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (data.Empty()) { 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG_IF(DFATAL, !fin) 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Creating a stream frame with no data or fin."; 1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Create a new packet for the fin, if necessary. 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *frame = QuicFrame(new QuicStreamFrame(id, true, offset, data)); 1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return 0; 1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const size_t data_size = data.TotalBufferSize(); 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch framer_->version(), id, offset, /*last_frame_in_packet=*/ true, 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch is_in_fec_group); 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool set_fin = fin && bytes_consumed == data_size; // Last frame. 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IOVector frame_data; 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(), 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bytes_consumed); 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed); 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data)); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bytes_consumed; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrameWithNotifier( 19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicStreamId id, 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const IOVector& data, 19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicStreamOffset offset, 19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool fin, 19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicAckNotifier* notifier, 19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicFrame* frame) { 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t bytes_consumed = CreateStreamFrame(id, data, offset, fin, frame); 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The frame keeps track of the QuicAckNotifier until it is serialized into 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // a packet. At that point the notifier is informed of the sequence number 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // of the packet that this frame was eventually sent in. 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) frame->stream_frame->notifier = notifier; 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return bytes_consumed; 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SerializedPacket QuicPacketCreator::ReserializeAllFrames( 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const QuicFrames& frames, 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) QuicSequenceNumberLength original_length) { 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const QuicSequenceNumberLength start_length = sequence_number_length_; 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const QuicSequenceNumberLength start_options_length = 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) options_.send_sequence_number_length; 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const QuicFecGroupNumber start_fec_group = fec_group_number_; 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const size_t start_max_packets_per_fec_group = 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) options_.max_packets_per_fec_group; 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Temporarily set the sequence number length and disable FEC. 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sequence_number_length_ = original_length; 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) options_.send_sequence_number_length = original_length; 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fec_group_number_ = 0; 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) options_.max_packets_per_fec_group = 0; 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Serialize the packet and restore the fec and sequence number length state. 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SerializedPacket serialized_packet = SerializeAllFrames(frames); 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sequence_number_length_ = start_length; 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) options_.send_sequence_number_length = start_options_length; 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fec_group_number_ = start_fec_group; 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) options_.max_packets_per_fec_group = start_max_packets_per_fec_group; 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return serialized_packet; 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeAllFrames( 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicFrames& frames) { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // frames from SendStreamData()[send_stream_should_flush_ == false && 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // data.empty() == true] and retransmit due to RTO. 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0u, queued_frames_.size()); 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG_IF(DFATAL, frames.empty()) 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Attempt to serialize empty packet"; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < frames.size(); ++i) { 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = AddFrame(frames[i], false); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(success); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SerializedPacket packet = SerializePacket(); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(packet.retransmittable_frames == NULL); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return packet; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::HasPendingFrames() { 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !queued_frames_.empty(); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochsize_t QuicPacketCreator::ExpansionOnNewFrame() const { 257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If packet is FEC protected, there's no expansion. 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (fec_group_.get() != NULL) { 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return 0; 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If the last frame in the packet is a stream frame, then it will expand to 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // include the stream_length field when a new frame is added. 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool has_trailing_stream_frame = 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; 266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::BytesFree() const { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t max_plaintext_size = 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer_->GetMaxPlaintextSize(options_.max_packet_length); 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(max_plaintext_size, PacketSize()); 272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return max_plaintext_size - min(max_plaintext_size, PacketSize() 273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch + ExpansionOnNewFrame()); 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2760529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochInFecGroup QuicPacketCreator::IsFecEnabled() const { 2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return (framer_->version() == QUIC_VERSION_13 || 2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch options_.max_packets_per_fec_group == 0) ? 2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NOT_IN_FEC_GROUP : IN_FEC_GROUP; 2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)size_t QuicPacketCreator::PacketSize() const { 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (queued_frames_.empty()) { 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Only adjust the sequence number length when the FEC group is not open, 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // to ensure no packets in a group are too large. 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (fec_group_.get() == NULL || 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fec_group_->NumReceivedPackets() == 0) { 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sequence_number_length_ = options_.send_sequence_number_length; 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) packet_size_ = GetPacketHeaderSize(options_.send_connection_id_length, 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) send_version_in_packet_, 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sequence_number_length_, 2930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IsFecEnabled()); 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return packet_size_; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFrame(frame, true); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializePacket() { 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG_IF(DFATAL, queued_frames_.empty()) 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Attempt to serialize empty packet"; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketHeader header; 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FillPacketHeader(fec_group_number_, false, &header); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MaybeAddPadding(); 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t max_plaintext_size = 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) framer_->GetMaxPlaintextSize(options_.max_packet_length); 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(max_plaintext_size, packet_size_); 3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // ACK and CONNECTION_CLOSE Frames will be truncated only if they're 3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // the first frame in the packet. If truncation is to occur, then 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // GetSerializedFrameLength will have returned all bytes free. 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool possibly_truncated = 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) packet_size_ != max_plaintext_size || 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) queued_frames_.size() != 1 || 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) (queued_frames_.back().type == ACK_FRAME || 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) queued_frames_.back().type == CONNECTION_CLOSE_FRAME); 32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SerializedPacket serialized = 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) framer_->BuildDataPacket(header, queued_frames_, packet_size_); 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG_IF(DFATAL, !serialized.packet) 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Failed to serialize " << queued_frames_.size() << " frames."; 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Because of possible truncation, we can't be confident that our 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // packet size calculation worked correctly. 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!possibly_truncated) 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_EQ(packet_size_, serialized.packet->length()); 32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) packet_size_ = 0; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.clear(); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) serialized.retransmittable_frames = queued_retransmittable_frames_.release(); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return serialized; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeFec() { 3370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) { 3380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; 3390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(jri): Make this a public method of framer? 3400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL); 3410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return kNoPacket; 3420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0u, queued_frames_.size()); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketHeader header; 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FillPacketHeader(fec_group_number_, true, &header); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicFecData fec_data; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_data.fec_group = fec_group_->min_protected_packet(); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_data.redundancy = fec_group_->payload_parity(); 3492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_.reset(NULL); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_number_ = 0; 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) packet_size_ = 0; 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG_IF(DFATAL, !serialized.packet) 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Failed to serialize fec packet for group:" << fec_data.fec_group; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(options_.max_packet_length, serialized.packet->length()); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return serialized; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeConnectionClose( 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConnectionCloseFrame* close_frame) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicFrames frames; 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frames.push_back(QuicFrame(close_frame)); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SerializeAllFrames(frames); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( 367558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const QuicVersionVector& supported_versions) { 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(is_server_); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketPublicHeader header; 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.connection_id = connection_id_; 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header.reset_flag = false; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header.version_flag = true; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header.versions = supported_versions; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicEncryptedPacket* encrypted = 3752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch framer_->BuildVersionNegotiationPacket(header, supported_versions); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(encrypted); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(options_.max_packet_length, encrypted->length()); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return encrypted; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fec_flag, 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketHeader* header) { 384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header->public_header.connection_id = connection_id_; 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header->public_header.reset_flag = false; 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header->public_header.version_flag = send_version_in_packet_; 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header->fec_flag = fec_flag; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->packet_sequence_number = ++sequence_number_; 3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) header->public_header.sequence_number_length = sequence_number_length_; 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) header->entropy_flag = random_bool_source_->RandBool(); 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->fec_group = fec_group; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (frame.type) { 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case ACK_FRAME: 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case CONGESTION_FEEDBACK_FRAME: 399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case PADDING_FRAME: 400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case STOP_WAITING_FRAME: 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddFrame(const QuicFrame& frame, 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool save_retransmittable_frames) { 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Adding frame: " << frame; 410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch InFecGroup is_in_fec_group = MaybeStartFEC(); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t frame_len = framer_->GetSerializedFrameLength( 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, 4130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) options()->send_sequence_number_length); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame_len == 0) { 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_LT(0u, packet_size_); 418c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch packet_size_ += ExpansionOnNewFrame() + frame_len; 419c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (save_retransmittable_frames && ShouldRetransmit(frame)) { 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_retransmittable_frames_.get() == NULL) { 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_retransmittable_frames_.reset(new RetransmittableFrames()); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame.type == STREAM_FRAME) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.push_back( 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame)); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.push_back( 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_retransmittable_frames_->AddNonStreamFrame(frame)); 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.push_back(frame); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicPacketCreator::MaybeAddPadding() { 4381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (BytesFree() == 0) { 4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Don't pad full packets. 4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If any of the frames in the current packet are on the crypto stream 4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // then they contain handshake messagses, and we should pad them. 4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool is_handshake = false; 4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (size_t i = 0; i < queued_frames_.size(); ++i) { 4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (queued_frames_[i].type == STREAM_FRAME && 4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) queued_frames_[i].stream_frame->stream_id == kCryptoStreamId) { 4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) is_handshake = true; 4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!is_handshake) { 4541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 4551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) QuicPaddingFrame padding; 4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool success = AddFrame(QuicFrame(&padding), false); 4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(success); 4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 463