quic_packet_creator.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_fec_group.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::make_pair; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::pair; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicPacketCreator::QuicPacketCreator(QuicGuid guid, 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicFramer* framer, 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicRandom* random_generator, 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_server) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : guid_(guid), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer_(framer), 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) random_generator_(random_generator), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sequence_number_(0), 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_number_(0), 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_server_(is_server), 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) send_version_in_packet_(!is_server), 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) packet_size_(GetPacketHeaderSize(options_.send_guid_length, 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) send_version_in_packet_, 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) options_.send_sequence_number_length, 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NOT_IN_FEC_GROUP)) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer_->set_fec_builder(this); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::~QuicPacketCreator() { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::OnBuiltFecProtectedPayload( 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicPacketHeader& header, StringPiece payload) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fec_group_.get()) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fec_group_->Update(header, payload); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldSendFec(bool force_close) const { 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 && 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (force_close || 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicPacketCreator::MaybeStartFEC() { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) { 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(queued_frames_.empty()); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set the fec group number to the sequence number of the next packet. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_number_ = sequence_number() + 1; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_.reset(new QuicFecGroup()); 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) packet_size_ = GetPacketHeaderSize(options_.send_guid_length, 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) send_version_in_packet_, 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) options_.send_sequence_number_length, 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IN_FEC_GROUP); 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LE(packet_size_, options_.max_packet_length); 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) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::HasRoomForStreamFrame() const { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return BytesFree() > QuicFramer::GetMinStreamFrameSize(); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t QuicPacketCreator::StreamFramePacketOverhead( 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicGuidLength guid_length, 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool include_version, 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicSequenceNumberLength sequence_number_length, 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) InFecGroup is_in_fec_group) { 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GetPacketHeaderSize(guid_length, include_version, 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sequence_number_length, is_in_fec_group) + 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Assumes this is a stream with a single lone packet. 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QuicFramer::GetMinStreamFrameSize(1, 0, true); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringPiece data, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicStreamOffset offset, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicFrame* frame) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(options_.max_packet_length, 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StreamFramePacketOverhead( 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PACKET_8BYTE_GUID, kIncludeVersion, 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP)); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(HasRoomForStreamFrame()); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t free_bytes = BytesFree(); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t bytes_consumed = 0; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data.size() != 0) { 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t min_last_stream_frame_size = 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QuicFramer::GetMinStreamFrameSize(id, offset, true); 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Comparing against the last stream frame size including the length 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // guarantees that all the bytes will fit. Otherwise there is a 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // discontinuity where the packet goes one byte over due to the length data. 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (data.size() > free_bytes - min_last_stream_frame_size - 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch kQuicStreamPayloadLengthSize) { 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Its the last frame, put as much data as possible in. 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bytes_consumed = 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch min<size_t>(free_bytes - min_last_stream_frame_size, data.size()); 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bytes_consumed = data.size(); 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool set_fin = fin && bytes_consumed == data.size(); // Last frame. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringPiece data_frame(data.data(), bytes_consumed); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, data_frame)); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(fin); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a new packet for the fin, if necessary. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *frame = QuicFrame(new QuicStreamFrame(id, true, offset, "")); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bytes_consumed; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeAllFrames( 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicFrames& frames) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // frames from SendStreamData()[send_stream_should_flush_ == false && 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // data.empty() == true] and retransmit due to RTO. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0u, queued_frames_.size()); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < frames.size(); ++i) { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = AddFrame(frames[i], false); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(success); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SerializedPacket packet = SerializePacket(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(packet.retransmittable_frames == NULL); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return packet; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::HasPendingFrames() { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !queued_frames_.empty(); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t QuicPacketCreator::BytesFree() const { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t max_plaintext_size = 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer_->GetMaxPlaintextSize(options_.max_packet_length); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (packet_size_ > max_plaintext_size) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return max_plaintext_size - packet_size_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFrame(frame, true); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializePacket() { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(false, queued_frames_.empty()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketHeader header; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FillPacketHeader(fec_group_number_, false, false, &header); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SerializedPacket serialized = framer_->ConstructFrameDataPacket( 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header, queued_frames_, packet_size_); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.clear(); 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) packet_size_ = GetPacketHeaderSize(options_.send_guid_length, 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) send_version_in_packet_, 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) options_.send_sequence_number_length, 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fec_group_.get() != NULL ? 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IN_FEC_GROUP : NOT_IN_FEC_GROUP); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) serialized.retransmittable_frames = queued_retransmittable_frames_.release(); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return serialized; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeFec() { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(0u, fec_group_->NumReceivedPackets()); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0u, queued_frames_.size()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketHeader header; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FillPacketHeader(fec_group_number_, true, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_->entropy_parity(), &header); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicFecData fec_data; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_data.fec_group = fec_group_->min_protected_packet(); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_data.redundancy = fec_group_->payload_parity(); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SerializedPacket serialized = framer_->ConstructFecPacket(header, fec_data); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_.reset(NULL); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fec_group_number_ = 0; 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Reset packet_size_, since the next packet may not have an FEC group. 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) packet_size_ = GetPacketHeaderSize(options_.send_guid_length, 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) send_version_in_packet_, 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) options_.send_sequence_number_length, 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NOT_IN_FEC_GROUP); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(serialized.packet); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(options_.max_packet_length, serialized.packet->length()); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return serialized; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedPacket QuicPacketCreator::SerializeConnectionClose( 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConnectionCloseFrame* close_frame) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicFrames frames; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frames.push_back(QuicFrame(close_frame)); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SerializeAllFrames(frames); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const QuicTagVector& supported_versions) { 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(is_server_); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketPublicHeader header; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header.guid = guid_; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header.reset_flag = false; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header.version_flag = true; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header.versions = supported_versions; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicEncryptedPacket* encrypted = 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer_->ConstructVersionNegotiationPacket(header, supported_versions); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(encrypted); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(options_.max_packet_length, encrypted->length()); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return encrypted; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fec_flag, 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fec_entropy_flag, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketHeader* header) { 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header->public_header.guid = guid_; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header->public_header.reset_flag = false; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header->public_header.version_flag = send_version_in_packet_; 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) header->fec_flag = fec_flag; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->packet_sequence_number = ++sequence_number_; 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool entropy_flag; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (header->packet_sequence_number == 1) { 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!fec_flag); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(satyamshekhar): No entropy in the first message. 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For crypto tests to pass. Fix this by using deterministic QuicRandom. 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) entropy_flag = 0; 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (fec_flag) { 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // FEC packets don't have an entropy of their own. Entropy flag for FEC 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // packets is the XOR of entropy of previous packets. 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) entropy_flag = fec_entropy_flag; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) entropy_flag = random_generator_->RandBool(); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) header->entropy_flag = entropy_flag; 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->fec_group = fec_group; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME && 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame.type != PADDING_FRAME; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicPacketCreator::AddFrame(const QuicFrame& frame, 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool save_retransmittable_frames) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t frame_len = framer_->GetSerializedFrameLength( 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame, BytesFree(), queued_frames_.empty()); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame_len == 0) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) packet_size_ += frame_len; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (save_retransmittable_frames && ShouldRetransmit(frame)) { 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_retransmittable_frames_.get() == NULL) { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_retransmittable_frames_.reset(new RetransmittableFrames()); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame.type == STREAM_FRAME) { 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.push_back( 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame)); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.push_back( 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_retransmittable_frames_->AddNonStreamFrame(frame)); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_frames_.push_back(frame); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 290