1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_packet_creator.h" 6 7 #include "base/logging.h" 8 #include "net/quic/crypto/quic_random.h" 9 #include "net/quic/quic_fec_group.h" 10 #include "net/quic/quic_utils.h" 11 12 using base::StringPiece; 13 using std::make_pair; 14 using std::min; 15 using std::pair; 16 using std::vector; 17 18 namespace net { 19 20 QuicPacketCreator::QuicPacketCreator(QuicGuid guid, 21 QuicFramer* framer, 22 QuicRandom* random_generator, 23 bool is_server) 24 : guid_(guid), 25 framer_(framer), 26 random_generator_(random_generator), 27 sequence_number_(0), 28 fec_group_number_(0), 29 is_server_(is_server), 30 send_version_in_packet_(!is_server), 31 packet_size_(GetPacketHeaderSize(options_.send_guid_length, 32 send_version_in_packet_, 33 options_.send_sequence_number_length, 34 NOT_IN_FEC_GROUP)) { 35 framer_->set_fec_builder(this); 36 } 37 38 QuicPacketCreator::~QuicPacketCreator() { 39 } 40 41 void QuicPacketCreator::OnBuiltFecProtectedPayload( 42 const QuicPacketHeader& header, StringPiece payload) { 43 if (fec_group_.get()) { 44 fec_group_->Update(header, payload); 45 } 46 } 47 48 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { 49 return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 && 50 (force_close || 51 fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group); 52 } 53 54 void QuicPacketCreator::MaybeStartFEC() { 55 if (options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) { 56 DCHECK(queued_frames_.empty()); 57 // Set the fec group number to the sequence number of the next packet. 58 fec_group_number_ = sequence_number() + 1; 59 fec_group_.reset(new QuicFecGroup()); 60 packet_size_ = GetPacketHeaderSize(options_.send_guid_length, 61 send_version_in_packet_, 62 options_.send_sequence_number_length, 63 IN_FEC_GROUP); 64 DCHECK_LE(packet_size_, options_.max_packet_length); 65 } 66 } 67 68 // Stops serializing version of the protocol in packets sent after this call. 69 // A packet that is already open might send kQuicVersionSize bytes less than the 70 // maximum packet size if we stop sending version before it is serialized. 71 void QuicPacketCreator::StopSendingVersion() { 72 DCHECK(send_version_in_packet_); 73 send_version_in_packet_ = false; 74 if (packet_size_ > 0) { 75 DCHECK_LT(kQuicVersionSize, packet_size_); 76 packet_size_ -= kQuicVersionSize; 77 } 78 } 79 80 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, 81 QuicStreamOffset offset) const { 82 return BytesFree() > 83 QuicFramer::GetMinStreamFrameSize(framer_->version(), id, offset, true); 84 } 85 86 // static 87 size_t QuicPacketCreator::StreamFramePacketOverhead( 88 QuicVersion version, 89 QuicGuidLength guid_length, 90 bool include_version, 91 QuicSequenceNumberLength sequence_number_length, 92 InFecGroup is_in_fec_group) { 93 return GetPacketHeaderSize(guid_length, include_version, 94 sequence_number_length, is_in_fec_group) + 95 // Assumes this is a stream with a single lone packet. 96 QuicFramer::GetMinStreamFrameSize(version, 1u, 0u, true); 97 } 98 99 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, 100 StringPiece data, 101 QuicStreamOffset offset, 102 bool fin, 103 QuicFrame* frame) { 104 DCHECK_GT(options_.max_packet_length, 105 StreamFramePacketOverhead( 106 framer_->version(), PACKET_8BYTE_GUID, kIncludeVersion, 107 PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP)); 108 DCHECK(HasRoomForStreamFrame(id, offset)); 109 110 const size_t free_bytes = BytesFree(); 111 size_t bytes_consumed = 0; 112 113 if (data.size() != 0) { 114 // When a STREAM frame is the last frame in a packet, it consumes two fewer 115 // bytes of framing overhead. 116 // Anytime more data is available than fits in with the extra two bytes, 117 // the frame will be the last, and up to two extra bytes are consumed. 118 // TODO(ianswett): If QUIC pads, the 1 byte PADDING frame does not fit when 119 // 1 byte is available, because then the STREAM frame isn't the last. 120 121 // The minimum frame size(0 bytes of data) if it's not the last frame. 122 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( 123 framer_->version(), id, offset, false); 124 // Check if it's the last frame in the packet. 125 if (data.size() + min_frame_size > free_bytes) { 126 // The minimum frame size(0 bytes of data) if it is the last frame. 127 size_t min_last_frame_size = QuicFramer::GetMinStreamFrameSize( 128 framer_->version(), id, offset, true); 129 bytes_consumed = 130 min<size_t>(free_bytes - min_last_frame_size, data.size()); 131 } else { 132 DCHECK_LT(data.size(), BytesFree()); 133 bytes_consumed = data.size(); 134 } 135 136 bool set_fin = fin && bytes_consumed == data.size(); // Last frame. 137 StringPiece data_frame(data.data(), bytes_consumed); 138 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, data_frame)); 139 } else { 140 DCHECK(fin); 141 // Create a new packet for the fin, if necessary. 142 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, "")); 143 } 144 145 return bytes_consumed; 146 } 147 148 SerializedPacket QuicPacketCreator::SerializeAllFrames( 149 const QuicFrames& frames) { 150 // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued 151 // frames from SendStreamData()[send_stream_should_flush_ == false && 152 // data.empty() == true] and retransmit due to RTO. 153 DCHECK_EQ(0u, queued_frames_.size()); 154 for (size_t i = 0; i < frames.size(); ++i) { 155 bool success = AddFrame(frames[i], false); 156 DCHECK(success); 157 } 158 SerializedPacket packet = SerializePacket(); 159 DCHECK(packet.retransmittable_frames == NULL); 160 return packet; 161 } 162 163 bool QuicPacketCreator::HasPendingFrames() { 164 return !queued_frames_.empty(); 165 } 166 167 size_t QuicPacketCreator::BytesFree() const { 168 const size_t max_plaintext_size = 169 framer_->GetMaxPlaintextSize(options_.max_packet_length); 170 if (packet_size_ > max_plaintext_size) { 171 return 0; 172 } 173 return max_plaintext_size - packet_size_; 174 } 175 176 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { 177 return AddFrame(frame, true); 178 } 179 180 SerializedPacket QuicPacketCreator::SerializePacket() { 181 DCHECK_EQ(false, queued_frames_.empty()); 182 QuicPacketHeader header; 183 FillPacketHeader(fec_group_number_, false, false, &header); 184 185 SerializedPacket serialized = framer_->BuildDataPacket( 186 header, queued_frames_, packet_size_); 187 queued_frames_.clear(); 188 packet_size_ = GetPacketHeaderSize(options_.send_guid_length, 189 send_version_in_packet_, 190 options_.send_sequence_number_length, 191 fec_group_.get() != NULL ? 192 IN_FEC_GROUP : NOT_IN_FEC_GROUP); 193 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); 194 return serialized; 195 } 196 197 SerializedPacket QuicPacketCreator::SerializeFec() { 198 DCHECK_LT(0u, fec_group_->NumReceivedPackets()); 199 DCHECK_EQ(0u, queued_frames_.size()); 200 QuicPacketHeader header; 201 FillPacketHeader(fec_group_number_, true, 202 fec_group_->entropy_parity(), &header); 203 QuicFecData fec_data; 204 fec_data.fec_group = fec_group_->min_protected_packet(); 205 fec_data.redundancy = fec_group_->payload_parity(); 206 SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data); 207 fec_group_.reset(NULL); 208 fec_group_number_ = 0; 209 // Reset packet_size_, since the next packet may not have an FEC group. 210 packet_size_ = GetPacketHeaderSize(options_.send_guid_length, 211 send_version_in_packet_, 212 options_.send_sequence_number_length, 213 NOT_IN_FEC_GROUP); 214 DCHECK(serialized.packet); 215 DCHECK_GE(options_.max_packet_length, serialized.packet->length()); 216 return serialized; 217 } 218 219 SerializedPacket QuicPacketCreator::SerializeConnectionClose( 220 QuicConnectionCloseFrame* close_frame) { 221 QuicFrames frames; 222 frames.push_back(QuicFrame(close_frame)); 223 return SerializeAllFrames(frames); 224 } 225 226 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( 227 const QuicVersionVector& supported_versions) { 228 DCHECK(is_server_); 229 QuicPacketPublicHeader header; 230 header.guid = guid_; 231 header.reset_flag = false; 232 header.version_flag = true; 233 header.versions = supported_versions; 234 QuicEncryptedPacket* encrypted = 235 framer_->BuildVersionNegotiationPacket(header, supported_versions); 236 DCHECK(encrypted); 237 DCHECK_GE(options_.max_packet_length, encrypted->length()); 238 return encrypted; 239 } 240 241 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, 242 bool fec_flag, 243 bool fec_entropy_flag, 244 QuicPacketHeader* header) { 245 header->public_header.guid = guid_; 246 header->public_header.reset_flag = false; 247 header->public_header.version_flag = send_version_in_packet_; 248 header->fec_flag = fec_flag; 249 header->packet_sequence_number = ++sequence_number_; 250 251 bool entropy_flag; 252 if (header->packet_sequence_number == 1) { 253 DCHECK(!fec_flag); 254 // TODO(satyamshekhar): No entropy in the first message. 255 // For crypto tests to pass. Fix this by using deterministic QuicRandom. 256 entropy_flag = 0; 257 } else if (fec_flag) { 258 // FEC packets don't have an entropy of their own. Entropy flag for FEC 259 // packets is the XOR of entropy of previous packets. 260 entropy_flag = fec_entropy_flag; 261 } else { 262 entropy_flag = random_generator_->RandBool(); 263 } 264 header->entropy_flag = entropy_flag; 265 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; 266 header->fec_group = fec_group; 267 } 268 269 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { 270 return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME && 271 frame.type != PADDING_FRAME; 272 } 273 274 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, 275 bool save_retransmittable_frames) { 276 size_t frame_len = framer_->GetSerializedFrameLength( 277 frame, BytesFree(), queued_frames_.empty()); 278 if (frame_len == 0) { 279 return false; 280 } 281 packet_size_ += frame_len; 282 283 if (save_retransmittable_frames && ShouldRetransmit(frame)) { 284 if (queued_retransmittable_frames_.get() == NULL) { 285 queued_retransmittable_frames_.reset(new RetransmittableFrames()); 286 } 287 if (frame.type == STREAM_FRAME) { 288 queued_frames_.push_back( 289 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame)); 290 } else { 291 queued_frames_.push_back( 292 queued_retransmittable_frames_->AddNonStreamFrame(frame)); 293 } 294 } else { 295 queued_frames_.push_back(frame); 296 } 297 return true; 298 } 299 300 } // namespace net 301