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