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_generator.h" 6 7 #include "base/basictypes.h" 8 #include "base/logging.h" 9 #include "net/quic/quic_fec_group.h" 10 #include "net/quic/quic_utils.h" 11 12 using base::StringPiece; 13 14 namespace net { 15 16 namespace { 17 18 // We want to put some space between a protected packet and the FEC packet to 19 // avoid losing them both within the same loss episode. On the other hand, 20 // we expect to be able to recover from any loss in about an RTT. 21 // We resolve this tradeoff by sending an FEC packet atmost half an RTT, 22 // or equivalently, half a cwnd, after the first protected packet. Since we 23 // don't want to delay an FEC packet past half an RTT, we set the max FEC 24 // group size to be half the current congestion window. 25 const float kCongestionWindowMultiplierForFecGroupSize = 0.5; 26 27 } // namespace 28 29 class QuicAckNotifier; 30 31 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, 32 QuicFramer* framer, 33 QuicRandom* random_generator, 34 DelegateInterface* delegate) 35 : delegate_(delegate), 36 debug_delegate_(NULL), 37 packet_creator_(connection_id, framer, random_generator), 38 batch_mode_(false), 39 should_fec_protect_(false), 40 should_send_ack_(false), 41 should_send_feedback_(false), 42 should_send_stop_waiting_(false) { 43 } 44 45 QuicPacketGenerator::~QuicPacketGenerator() { 46 for (QuicFrames::iterator it = queued_control_frames_.begin(); 47 it != queued_control_frames_.end(); ++it) { 48 switch (it->type) { 49 case PADDING_FRAME: 50 delete it->padding_frame; 51 break; 52 case STREAM_FRAME: 53 delete it->stream_frame; 54 break; 55 case ACK_FRAME: 56 delete it->ack_frame; 57 break; 58 case CONGESTION_FEEDBACK_FRAME: 59 delete it->congestion_feedback_frame; 60 break; 61 case RST_STREAM_FRAME: 62 delete it->rst_stream_frame; 63 break; 64 case CONNECTION_CLOSE_FRAME: 65 delete it->connection_close_frame; 66 break; 67 case GOAWAY_FRAME: 68 delete it->goaway_frame; 69 break; 70 case WINDOW_UPDATE_FRAME: 71 delete it->window_update_frame; 72 break; 73 case BLOCKED_FRAME: 74 delete it->blocked_frame; 75 break; 76 case STOP_WAITING_FRAME: 77 delete it->stop_waiting_frame; 78 break; 79 case PING_FRAME: 80 delete it->ping_frame; 81 break; 82 case NUM_FRAME_TYPES: 83 DCHECK(false) << "Cannot delete type: " << it->type; 84 } 85 } 86 } 87 88 // NetworkChangeVisitor method. 89 void QuicPacketGenerator::OnCongestionWindowChange( 90 QuicByteCount congestion_window) { 91 packet_creator_.set_max_packets_per_fec_group( 92 static_cast<size_t>(kCongestionWindowMultiplierForFecGroupSize * 93 congestion_window / kDefaultTCPMSS)); 94 } 95 96 void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback, 97 bool also_send_stop_waiting) { 98 should_send_ack_ = true; 99 should_send_feedback_ = also_send_feedback; 100 should_send_stop_waiting_ = also_send_stop_waiting; 101 SendQueuedFrames(false); 102 } 103 104 void QuicPacketGenerator::SetShouldSendStopWaiting() { 105 should_send_stop_waiting_ = true; 106 SendQueuedFrames(false); 107 } 108 109 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { 110 queued_control_frames_.push_back(frame); 111 SendQueuedFrames(false); 112 } 113 114 QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id, 115 const IOVector& data_to_write, 116 QuicStreamOffset offset, 117 bool fin, 118 FecProtection fec_protection, 119 QuicAckNotifier* notifier) { 120 IsHandshake handshake = id == kCryptoStreamId ? IS_HANDSHAKE : NOT_HANDSHAKE; 121 // To make reasoning about crypto frames easier, we don't combine them with 122 // other retransmittable frames in a single packet. 123 const bool flush = handshake == IS_HANDSHAKE && 124 packet_creator_.HasPendingRetransmittableFrames(); 125 SendQueuedFrames(flush); 126 127 size_t total_bytes_consumed = 0; 128 bool fin_consumed = false; 129 130 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { 131 SerializeAndSendPacket(); 132 } 133 134 if (fec_protection == MUST_FEC_PROTECT) { 135 MaybeStartFecProtection(); 136 } 137 138 IOVector data = data_to_write; 139 size_t data_size = data.TotalBufferSize(); 140 while (delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, 141 HAS_RETRANSMITTABLE_DATA, handshake)) { 142 QuicFrame frame; 143 size_t bytes_consumed; 144 if (notifier != NULL) { 145 // We want to track which packet this stream frame ends up in. 146 bytes_consumed = packet_creator_.CreateStreamFrameWithNotifier( 147 id, data, offset + total_bytes_consumed, fin, notifier, &frame); 148 } else { 149 bytes_consumed = packet_creator_.CreateStreamFrame( 150 id, data, offset + total_bytes_consumed, fin, &frame); 151 } 152 if (!AddFrame(frame)) { 153 LOG(DFATAL) << "Failed to add stream frame."; 154 // Inability to add a STREAM frame creates an unrecoverable hole in a 155 // the stream, so it's best to close the connection. 156 delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false); 157 return QuicConsumedData(0, false); 158 } 159 160 total_bytes_consumed += bytes_consumed; 161 fin_consumed = fin && total_bytes_consumed == data_size; 162 data.Consume(bytes_consumed); 163 DCHECK(data.Empty() || packet_creator_.BytesFree() == 0u); 164 165 // TODO(ianswett): Restore packet reordering. 166 if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) { 167 SerializeAndSendPacket(); 168 } 169 170 if (data.Empty()) { 171 // We're done writing the data. Exit the loop. 172 // We don't make this a precondition because we could have 0 bytes of data 173 // if we're simply writing a fin. 174 if (fec_protection == MUST_FEC_PROTECT) { 175 // Turn off FEC protection when we're done writing protected data. 176 DVLOG(1) << "Turning FEC protection OFF"; 177 should_fec_protect_ = false; 178 } 179 break; 180 } 181 } 182 183 // Don't allow the handshake to be bundled with other retransmittable frames. 184 if (handshake == IS_HANDSHAKE) { 185 SendQueuedFrames(true); 186 } 187 188 // Try to close FEC group since we've either run out of data to send or we're 189 // blocked. If not in batch mode, force close the group. 190 // TODO(jri): This method should be called with flush=false here 191 // once the timer-based FEC sending is done, to separate FEC sending from 192 // the end of batch operations. 193 MaybeSendFecPacketAndCloseGroup(!InBatchMode()); 194 195 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); 196 return QuicConsumedData(total_bytes_consumed, fin_consumed); 197 } 198 199 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { 200 DCHECK(HasPendingFrames()); 201 HasRetransmittableData retransmittable = 202 (should_send_ack_ || should_send_feedback_ || should_send_stop_waiting_) 203 ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA; 204 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { 205 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. 206 } 207 return delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, retransmittable, 208 NOT_HANDSHAKE); 209 } 210 211 void QuicPacketGenerator::SendQueuedFrames(bool flush) { 212 // Only add pending frames if we are SURE we can then send the whole packet. 213 while (HasPendingFrames() && 214 (flush || CanSendWithNextPendingFrameAddition())) { 215 if (!AddNextPendingFrame()) { 216 // Packet was full, so serialize and send it. 217 SerializeAndSendPacket(); 218 } 219 } 220 221 if (!InBatchMode() || flush) { 222 if (packet_creator_.HasPendingFrames()) { 223 SerializeAndSendPacket(); 224 } 225 // Ensure the FEC group is closed at the end of this method unless other 226 // writes are pending. 227 MaybeSendFecPacketAndCloseGroup(true); 228 } 229 } 230 231 void QuicPacketGenerator::MaybeStartFecProtection() { 232 if (!packet_creator_.IsFecEnabled()) { 233 return; 234 } 235 DVLOG(1) << "Turning FEC protection ON"; 236 should_fec_protect_ = true; 237 if (packet_creator_.IsFecProtected()) { 238 // Only start creator's FEC protection if not already on. 239 return; 240 } 241 if (HasQueuedFrames()) { 242 // TODO(jri): This currently requires that the generator flush out any 243 // pending frames when FEC protection is turned on. If current packet can be 244 // converted to an FEC protected packet, do it. This will require the 245 // generator to check if the resulting expansion still allows the incoming 246 // frame to be added to the packet. 247 SendQueuedFrames(true); 248 } 249 packet_creator_.StartFecProtectingPackets(); 250 DCHECK(packet_creator_.IsFecProtected()); 251 } 252 253 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) { 254 if (!packet_creator_.IsFecProtected() || 255 packet_creator_.HasPendingFrames() || 256 !packet_creator_.ShouldSendFec(force)) { 257 return; 258 } 259 // TODO(jri): SerializeFec can return a NULL packet, and this should 260 // cause an early return, with a call to delegate_->OnPacketGenerationError. 261 SerializedPacket serialized_fec = packet_creator_.SerializeFec(); 262 DCHECK(serialized_fec.packet); 263 delegate_->OnSerializedPacket(serialized_fec); 264 // Turn FEC protection off if creator's protection is on and the creator 265 // does not have an open FEC group. 266 // Note: We only wait until the frames queued in the creator are flushed; 267 // pending frames in the generator will not keep us from turning FEC off. 268 if (!should_fec_protect_ && !packet_creator_.IsFecGroupOpen()) { 269 packet_creator_.StopFecProtectingPackets(); 270 DCHECK(!packet_creator_.IsFecProtected()); 271 } 272 } 273 274 bool QuicPacketGenerator::InBatchMode() { 275 return batch_mode_; 276 } 277 278 void QuicPacketGenerator::StartBatchOperations() { 279 batch_mode_ = true; 280 } 281 282 void QuicPacketGenerator::FinishBatchOperations() { 283 batch_mode_ = false; 284 SendQueuedFrames(false); 285 } 286 287 void QuicPacketGenerator::FlushAllQueuedFrames() { 288 SendQueuedFrames(true); 289 } 290 291 bool QuicPacketGenerator::HasQueuedFrames() const { 292 return packet_creator_.HasPendingFrames() || HasPendingFrames(); 293 } 294 295 bool QuicPacketGenerator::HasPendingFrames() const { 296 return should_send_ack_ || should_send_feedback_ || 297 should_send_stop_waiting_ || !queued_control_frames_.empty(); 298 } 299 300 bool QuicPacketGenerator::AddNextPendingFrame() { 301 if (should_send_ack_) { 302 pending_ack_frame_.reset(delegate_->CreateAckFrame()); 303 // If we can't this add the frame now, then we still need to do so later. 304 should_send_ack_ = !AddFrame(QuicFrame(pending_ack_frame_.get())); 305 // Return success if we have cleared out this flag (i.e., added the frame). 306 // If we still need to send, then the frame is full, and we have failed. 307 return !should_send_ack_; 308 } 309 310 if (should_send_feedback_) { 311 pending_feedback_frame_.reset(delegate_->CreateFeedbackFrame()); 312 // If we can't this add the frame now, then we still need to do so later. 313 should_send_feedback_ = !AddFrame(QuicFrame(pending_feedback_frame_.get())); 314 // Return success if we have cleared out this flag (i.e., added the frame). 315 // If we still need to send, then the frame is full, and we have failed. 316 return !should_send_feedback_; 317 } 318 319 if (should_send_stop_waiting_) { 320 pending_stop_waiting_frame_.reset(delegate_->CreateStopWaitingFrame()); 321 // If we can't this add the frame now, then we still need to do so later. 322 should_send_stop_waiting_ = 323 !AddFrame(QuicFrame(pending_stop_waiting_frame_.get())); 324 // Return success if we have cleared out this flag (i.e., added the frame). 325 // If we still need to send, then the frame is full, and we have failed. 326 return !should_send_stop_waiting_; 327 } 328 329 LOG_IF(DFATAL, queued_control_frames_.empty()) 330 << "AddNextPendingFrame called with no queued control frames."; 331 if (!AddFrame(queued_control_frames_.back())) { 332 // Packet was full. 333 return false; 334 } 335 queued_control_frames_.pop_back(); 336 return true; 337 } 338 339 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) { 340 bool success = packet_creator_.AddSavedFrame(frame); 341 if (success && debug_delegate_) { 342 debug_delegate_->OnFrameAddedToPacket(frame); 343 } 344 return success; 345 } 346 347 void QuicPacketGenerator::SerializeAndSendPacket() { 348 SerializedPacket serialized_packet = packet_creator_.SerializePacket(); 349 DCHECK(serialized_packet.packet); 350 delegate_->OnSerializedPacket(serialized_packet); 351 MaybeSendFecPacketAndCloseGroup(false); 352 } 353 354 void QuicPacketGenerator::StopSendingVersion() { 355 packet_creator_.StopSendingVersion(); 356 } 357 358 QuicPacketSequenceNumber QuicPacketGenerator::sequence_number() const { 359 return packet_creator_.sequence_number(); 360 } 361 362 size_t QuicPacketGenerator::max_packet_length() const { 363 return packet_creator_.max_packet_length(); 364 } 365 366 void QuicPacketGenerator::set_max_packet_length(size_t length) { 367 packet_creator_.set_max_packet_length(length); 368 } 369 370 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket( 371 const QuicVersionVector& supported_versions) { 372 return packet_creator_.SerializeVersionNegotiationPacket(supported_versions); 373 } 374 375 SerializedPacket QuicPacketGenerator::ReserializeAllFrames( 376 const QuicFrames& frames, 377 QuicSequenceNumberLength original_length) { 378 return packet_creator_.ReserializeAllFrames(frames, original_length); 379 } 380 381 void QuicPacketGenerator::UpdateSequenceNumberLength( 382 QuicPacketSequenceNumber least_packet_awaited_by_peer, 383 QuicByteCount congestion_window) { 384 return packet_creator_.UpdateSequenceNumberLength( 385 least_packet_awaited_by_peer, congestion_window); 386 } 387 388 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { 389 packet_creator_.set_encryption_level(level); 390 } 391 392 } // namespace net 393