| OLD | NEW |
| (Empty) |
| 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_ack_notifier.h" | |
| 10 #include "net/quic/quic_fec_group.h" | |
| 11 #include "net/quic/quic_flags.h" | |
| 12 #include "net/quic/quic_utils.h" | |
| 13 | |
| 14 using base::StringPiece; | |
| 15 | |
| 16 namespace net { | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 // We want to put some space between a protected packet and the FEC packet to | |
| 21 // avoid losing them both within the same loss episode. On the other hand, we | |
| 22 // expect to be able to recover from any loss in about an RTT. We resolve this | |
| 23 // tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half | |
| 24 // the max number of in-flight packets, the first protected packet. Since we | |
| 25 // don't want to delay an FEC packet past half an RTT, we set the max FEC group | |
| 26 // size to be half the current congestion window. | |
| 27 const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5; | |
| 28 const float kRttMultiplierForFecTimeout = 0.5; | |
| 29 | |
| 30 // Minimum timeout for FEC alarm, set to half the minimum Tail Loss Probe | |
| 31 // timeout of 10ms. | |
| 32 const int64 kMinFecTimeoutMs = 5u; | |
| 33 | |
| 34 } // namespace | |
| 35 | |
| 36 class QuicAckNotifier; | |
| 37 | |
| 38 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, | |
| 39 QuicFramer* framer, | |
| 40 QuicRandom* random_generator, | |
| 41 DelegateInterface* delegate) | |
| 42 : delegate_(delegate), | |
| 43 debug_delegate_(nullptr), | |
| 44 packet_creator_(connection_id, framer, random_generator), | |
| 45 batch_mode_(false), | |
| 46 fec_timeout_(QuicTime::Delta::Zero()), | |
| 47 should_fec_protect_(false), | |
| 48 should_send_ack_(false), | |
| 49 should_send_stop_waiting_(false), | |
| 50 ack_queued_(false), | |
| 51 stop_waiting_queued_(false) { | |
| 52 } | |
| 53 | |
| 54 QuicPacketGenerator::~QuicPacketGenerator() { | |
| 55 for (QuicFrames::iterator it = queued_control_frames_.begin(); | |
| 56 it != queued_control_frames_.end(); ++it) { | |
| 57 switch (it->type) { | |
| 58 case PADDING_FRAME: | |
| 59 delete it->padding_frame; | |
| 60 break; | |
| 61 case STREAM_FRAME: | |
| 62 delete it->stream_frame; | |
| 63 break; | |
| 64 case ACK_FRAME: | |
| 65 delete it->ack_frame; | |
| 66 break; | |
| 67 case RST_STREAM_FRAME: | |
| 68 delete it->rst_stream_frame; | |
| 69 break; | |
| 70 case CONNECTION_CLOSE_FRAME: | |
| 71 delete it->connection_close_frame; | |
| 72 break; | |
| 73 case GOAWAY_FRAME: | |
| 74 delete it->goaway_frame; | |
| 75 break; | |
| 76 case WINDOW_UPDATE_FRAME: | |
| 77 delete it->window_update_frame; | |
| 78 break; | |
| 79 case BLOCKED_FRAME: | |
| 80 delete it->blocked_frame; | |
| 81 break; | |
| 82 case STOP_WAITING_FRAME: | |
| 83 delete it->stop_waiting_frame; | |
| 84 break; | |
| 85 case PING_FRAME: | |
| 86 delete it->ping_frame; | |
| 87 break; | |
| 88 case NUM_FRAME_TYPES: | |
| 89 DCHECK(false) << "Cannot delete type: " << it->type; | |
| 90 } | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 void QuicPacketGenerator::OnCongestionWindowChange( | |
| 95 QuicPacketCount max_packets_in_flight) { | |
| 96 packet_creator_.set_max_packets_per_fec_group( | |
| 97 static_cast<size_t>(kMaxPacketsInFlightMultiplierForFecGroupSize * | |
| 98 max_packets_in_flight)); | |
| 99 } | |
| 100 | |
| 101 void QuicPacketGenerator::OnRttChange(QuicTime::Delta rtt) { | |
| 102 fec_timeout_ = rtt.Multiply(kRttMultiplierForFecTimeout); | |
| 103 } | |
| 104 | |
| 105 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { | |
| 106 if (ack_queued_) { | |
| 107 // Ack already queued, nothing to do. | |
| 108 return; | |
| 109 } | |
| 110 | |
| 111 if (also_send_stop_waiting && stop_waiting_queued_) { | |
| 112 LOG(DFATAL) << "Should only ever be one pending stop waiting frame."; | |
| 113 return; | |
| 114 } | |
| 115 | |
| 116 should_send_ack_ = true; | |
| 117 should_send_stop_waiting_ = also_send_stop_waiting; | |
| 118 SendQueuedFrames(false); | |
| 119 } | |
| 120 | |
| 121 void QuicPacketGenerator::SetShouldSendStopWaiting() { | |
| 122 should_send_stop_waiting_ = true; | |
| 123 SendQueuedFrames(false); | |
| 124 } | |
| 125 | |
| 126 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { | |
| 127 queued_control_frames_.push_back(frame); | |
| 128 SendQueuedFrames(false); | |
| 129 } | |
| 130 | |
| 131 QuicConsumedData QuicPacketGenerator::ConsumeData( | |
| 132 QuicStreamId id, | |
| 133 const IOVector& data_to_write, | |
| 134 QuicStreamOffset offset, | |
| 135 bool fin, | |
| 136 FecProtection fec_protection, | |
| 137 QuicAckNotifier::DelegateInterface* delegate) { | |
| 138 bool has_handshake = id == kCryptoStreamId; | |
| 139 // To make reasoning about crypto frames easier, we don't combine them with | |
| 140 // other retransmittable frames in a single packet. | |
| 141 const bool flush = | |
| 142 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); | |
| 143 SendQueuedFrames(flush); | |
| 144 | |
| 145 size_t total_bytes_consumed = 0; | |
| 146 bool fin_consumed = false; | |
| 147 | |
| 148 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { | |
| 149 SerializeAndSendPacket(); | |
| 150 } | |
| 151 | |
| 152 if (fec_protection == MUST_FEC_PROTECT) { | |
| 153 MaybeStartFecProtection(); | |
| 154 } | |
| 155 | |
| 156 // This notifier will be owned by the AckNotifierManager (or deleted below) if | |
| 157 // not attached to a packet. | |
| 158 QuicAckNotifier* notifier = nullptr; | |
| 159 if (delegate != nullptr) { | |
| 160 notifier = new QuicAckNotifier(delegate); | |
| 161 } | |
| 162 | |
| 163 IOVector data = data_to_write; | |
| 164 size_t data_size = data.TotalBufferSize(); | |
| 165 if (!fin && (data_size == 0)) { | |
| 166 LOG(DFATAL) << "Attempt to consume empty data without FIN."; | |
| 167 return QuicConsumedData(0, false); | |
| 168 } | |
| 169 | |
| 170 int frames_created = 0; | |
| 171 while (delegate_->ShouldGeneratePacket( | |
| 172 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, | |
| 173 has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { | |
| 174 QuicFrame frame; | |
| 175 size_t bytes_consumed = packet_creator_.CreateStreamFrame( | |
| 176 id, data, offset + total_bytes_consumed, fin, &frame); | |
| 177 ++frames_created; | |
| 178 | |
| 179 // We want to track which packet this stream frame ends up in. | |
| 180 if (FLAGS_quic_attach_ack_notifiers_to_packets) { | |
| 181 if (notifier != nullptr) { | |
| 182 ack_notifiers_.push_back(notifier); | |
| 183 } | |
| 184 } else { | |
| 185 frame.stream_frame->notifier = notifier; | |
| 186 } | |
| 187 | |
| 188 if (!AddFrame(frame)) { | |
| 189 LOG(DFATAL) << "Failed to add stream frame."; | |
| 190 // Inability to add a STREAM frame creates an unrecoverable hole in a | |
| 191 // the stream, so it's best to close the connection. | |
| 192 delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false); | |
| 193 delete notifier; | |
| 194 return QuicConsumedData(0, false); | |
| 195 } | |
| 196 | |
| 197 total_bytes_consumed += bytes_consumed; | |
| 198 fin_consumed = fin && total_bytes_consumed == data_size; | |
| 199 data.Consume(bytes_consumed); | |
| 200 DCHECK(data.Empty() || packet_creator_.BytesFree() == 0u); | |
| 201 | |
| 202 // TODO(ianswett): Restore packet reordering. | |
| 203 if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) { | |
| 204 SerializeAndSendPacket(); | |
| 205 } | |
| 206 | |
| 207 if (data.Empty()) { | |
| 208 // We're done writing the data. Exit the loop. | |
| 209 // We don't make this a precondition because we could have 0 bytes of data | |
| 210 // if we're simply writing a fin. | |
| 211 if (fec_protection == MUST_FEC_PROTECT) { | |
| 212 // Turn off FEC protection when we're done writing protected data. | |
| 213 DVLOG(1) << "Turning FEC protection OFF"; | |
| 214 should_fec_protect_ = false; | |
| 215 } | |
| 216 break; | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 if (notifier != nullptr && frames_created == 0) { | |
| 221 // Safe to delete the AckNotifer as it was never attached to a packet. | |
| 222 delete notifier; | |
| 223 } | |
| 224 | |
| 225 // Don't allow the handshake to be bundled with other retransmittable frames. | |
| 226 if (has_handshake) { | |
| 227 SendQueuedFrames(true); | |
| 228 } | |
| 229 | |
| 230 // Try to close FEC group since we've either run out of data to send or we're | |
| 231 // blocked. If not in batch mode, force close the group. | |
| 232 MaybeSendFecPacketAndCloseGroup(/*force=*/false); | |
| 233 | |
| 234 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); | |
| 235 return QuicConsumedData(total_bytes_consumed, fin_consumed); | |
| 236 } | |
| 237 | |
| 238 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { | |
| 239 DCHECK(HasPendingFrames()); | |
| 240 HasRetransmittableData retransmittable = | |
| 241 (should_send_ack_ || should_send_stop_waiting_) | |
| 242 ? NO_RETRANSMITTABLE_DATA | |
| 243 : HAS_RETRANSMITTABLE_DATA; | |
| 244 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | |
| 245 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | |
| 246 } | |
| 247 return delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, retransmittable, | |
| 248 NOT_HANDSHAKE); | |
| 249 } | |
| 250 | |
| 251 void QuicPacketGenerator::SendQueuedFrames(bool flush) { | |
| 252 // Only add pending frames if we are SURE we can then send the whole packet. | |
| 253 while (HasPendingFrames() && | |
| 254 (flush || CanSendWithNextPendingFrameAddition())) { | |
| 255 if (!AddNextPendingFrame()) { | |
| 256 // Packet was full, so serialize and send it. | |
| 257 SerializeAndSendPacket(); | |
| 258 } | |
| 259 } | |
| 260 if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) { | |
| 261 SerializeAndSendPacket(); | |
| 262 } | |
| 263 MaybeSendFecPacketAndCloseGroup(flush); | |
| 264 } | |
| 265 | |
| 266 void QuicPacketGenerator::MaybeStartFecProtection() { | |
| 267 if (!packet_creator_.IsFecEnabled()) { | |
| 268 return; | |
| 269 } | |
| 270 DVLOG(1) << "Turning FEC protection ON"; | |
| 271 should_fec_protect_ = true; | |
| 272 if (packet_creator_.IsFecProtected()) { | |
| 273 // Only start creator's FEC protection if not already on. | |
| 274 return; | |
| 275 } | |
| 276 if (HasQueuedFrames()) { | |
| 277 // TODO(jri): This currently requires that the generator flush out any | |
| 278 // pending frames when FEC protection is turned on. If current packet can be | |
| 279 // converted to an FEC protected packet, do it. This will require the | |
| 280 // generator to check if the resulting expansion still allows the incoming | |
| 281 // frame to be added to the packet. | |
| 282 SendQueuedFrames(true); | |
| 283 } | |
| 284 packet_creator_.StartFecProtectingPackets(); | |
| 285 DCHECK(packet_creator_.IsFecProtected()); | |
| 286 } | |
| 287 | |
| 288 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) { | |
| 289 if (!ShouldSendFecPacket(force)) { | |
| 290 return; | |
| 291 } | |
| 292 // TODO(jri): SerializeFec can return a NULL packet, and this should | |
| 293 // cause an early return, with a call to delegate_->OnPacketGenerationError. | |
| 294 SerializedPacket serialized_fec = packet_creator_.SerializeFec(); | |
| 295 DCHECK(serialized_fec.packet); | |
| 296 delegate_->OnSerializedPacket(serialized_fec); | |
| 297 // Turn FEC protection off if creator's protection is on and the creator | |
| 298 // does not have an open FEC group. | |
| 299 // Note: We only wait until the frames queued in the creator are flushed; | |
| 300 // pending frames in the generator will not keep us from turning FEC off. | |
| 301 if (!should_fec_protect_ && !packet_creator_.IsFecGroupOpen()) { | |
| 302 packet_creator_.StopFecProtectingPackets(); | |
| 303 DCHECK(!packet_creator_.IsFecProtected()); | |
| 304 } | |
| 305 } | |
| 306 | |
| 307 bool QuicPacketGenerator::ShouldSendFecPacket(bool force) { | |
| 308 return packet_creator_.IsFecProtected() && | |
| 309 !packet_creator_.HasPendingFrames() && | |
| 310 packet_creator_.ShouldSendFec(force); | |
| 311 } | |
| 312 | |
| 313 void QuicPacketGenerator::OnFecTimeout() { | |
| 314 DCHECK(!InBatchMode()); | |
| 315 if (!ShouldSendFecPacket(true)) { | |
| 316 LOG(DFATAL) << "No FEC packet to send on FEC timeout."; | |
| 317 return; | |
| 318 } | |
| 319 // Flush out any pending frames in the generator and the creator, and then | |
| 320 // send out FEC packet. | |
| 321 SendQueuedFrames(true); | |
| 322 MaybeSendFecPacketAndCloseGroup(/*force=*/true); | |
| 323 } | |
| 324 | |
| 325 QuicTime::Delta QuicPacketGenerator::GetFecTimeout( | |
| 326 QuicPacketSequenceNumber sequence_number) { | |
| 327 // Do not set up FEC alarm for |sequence_number| it is not the first packet in | |
| 328 // the current group. | |
| 329 if (packet_creator_.IsFecGroupOpen() && | |
| 330 (sequence_number == packet_creator_.fec_group_number())) { | |
| 331 return QuicTime::Delta::Max( | |
| 332 fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs)); | |
| 333 } | |
| 334 return QuicTime::Delta::Infinite(); | |
| 335 } | |
| 336 | |
| 337 bool QuicPacketGenerator::InBatchMode() { | |
| 338 return batch_mode_; | |
| 339 } | |
| 340 | |
| 341 void QuicPacketGenerator::StartBatchOperations() { | |
| 342 batch_mode_ = true; | |
| 343 } | |
| 344 | |
| 345 void QuicPacketGenerator::FinishBatchOperations() { | |
| 346 batch_mode_ = false; | |
| 347 SendQueuedFrames(false); | |
| 348 } | |
| 349 | |
| 350 void QuicPacketGenerator::FlushAllQueuedFrames() { | |
| 351 SendQueuedFrames(true); | |
| 352 } | |
| 353 | |
| 354 bool QuicPacketGenerator::HasQueuedFrames() const { | |
| 355 return packet_creator_.HasPendingFrames() || HasPendingFrames(); | |
| 356 } | |
| 357 | |
| 358 bool QuicPacketGenerator::HasPendingFrames() const { | |
| 359 return should_send_ack_ || should_send_stop_waiting_ || | |
| 360 !queued_control_frames_.empty(); | |
| 361 } | |
| 362 | |
| 363 bool QuicPacketGenerator::AddNextPendingFrame() { | |
| 364 if (should_send_ack_) { | |
| 365 delegate_->PopulateAckFrame(&pending_ack_frame_); | |
| 366 ack_queued_ = true; | |
| 367 // If we can't this add the frame now, then we still need to do so later. | |
| 368 should_send_ack_ = !AddFrame(QuicFrame(&pending_ack_frame_)); | |
| 369 // Return success if we have cleared out this flag (i.e., added the frame). | |
| 370 // If we still need to send, then the frame is full, and we have failed. | |
| 371 return !should_send_ack_; | |
| 372 } | |
| 373 | |
| 374 if (should_send_stop_waiting_) { | |
| 375 delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_); | |
| 376 stop_waiting_queued_ = true; | |
| 377 // If we can't this add the frame now, then we still need to do so later. | |
| 378 should_send_stop_waiting_ = | |
| 379 !AddFrame(QuicFrame(&pending_stop_waiting_frame_)); | |
| 380 // Return success if we have cleared out this flag (i.e., added the frame). | |
| 381 // If we still need to send, then the frame is full, and we have failed. | |
| 382 return !should_send_stop_waiting_; | |
| 383 } | |
| 384 | |
| 385 LOG_IF(DFATAL, queued_control_frames_.empty()) | |
| 386 << "AddNextPendingFrame called with no queued control frames."; | |
| 387 if (!AddFrame(queued_control_frames_.back())) { | |
| 388 // Packet was full. | |
| 389 return false; | |
| 390 } | |
| 391 queued_control_frames_.pop_back(); | |
| 392 return true; | |
| 393 } | |
| 394 | |
| 395 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) { | |
| 396 bool success = packet_creator_.AddSavedFrame(frame); | |
| 397 if (success && debug_delegate_) { | |
| 398 debug_delegate_->OnFrameAddedToPacket(frame); | |
| 399 } | |
| 400 return success; | |
| 401 } | |
| 402 | |
| 403 void QuicPacketGenerator::SerializeAndSendPacket() { | |
| 404 SerializedPacket serialized_packet = packet_creator_.SerializePacket(); | |
| 405 DCHECK(serialized_packet.packet); | |
| 406 | |
| 407 // There may be AckNotifiers interested in this packet. | |
| 408 if (FLAGS_quic_attach_ack_notifiers_to_packets) { | |
| 409 serialized_packet.notifiers.swap(ack_notifiers_); | |
| 410 ack_notifiers_.clear(); | |
| 411 } | |
| 412 | |
| 413 delegate_->OnSerializedPacket(serialized_packet); | |
| 414 MaybeSendFecPacketAndCloseGroup(/*force=*/false); | |
| 415 | |
| 416 // The packet has now been serialized, so the frames are no longer queued. | |
| 417 ack_queued_ = false; | |
| 418 stop_waiting_queued_ = false; | |
| 419 } | |
| 420 | |
| 421 void QuicPacketGenerator::StopSendingVersion() { | |
| 422 packet_creator_.StopSendingVersion(); | |
| 423 } | |
| 424 | |
| 425 QuicPacketSequenceNumber QuicPacketGenerator::sequence_number() const { | |
| 426 return packet_creator_.sequence_number(); | |
| 427 } | |
| 428 | |
| 429 QuicByteCount QuicPacketGenerator::max_packet_length() const { | |
| 430 return packet_creator_.max_packet_length(); | |
| 431 } | |
| 432 | |
| 433 void QuicPacketGenerator::set_max_packet_length(QuicByteCount length) { | |
| 434 packet_creator_.set_max_packet_length(length); | |
| 435 } | |
| 436 | |
| 437 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket( | |
| 438 const QuicVersionVector& supported_versions) { | |
| 439 return packet_creator_.SerializeVersionNegotiationPacket(supported_versions); | |
| 440 } | |
| 441 | |
| 442 SerializedPacket QuicPacketGenerator::ReserializeAllFrames( | |
| 443 const RetransmittableFrames& frames, | |
| 444 QuicSequenceNumberLength original_length) { | |
| 445 return packet_creator_.ReserializeAllFrames(frames, original_length); | |
| 446 } | |
| 447 | |
| 448 void QuicPacketGenerator::UpdateSequenceNumberLength( | |
| 449 QuicPacketSequenceNumber least_packet_awaited_by_peer, | |
| 450 QuicPacketCount max_packets_in_flight) { | |
| 451 return packet_creator_.UpdateSequenceNumberLength( | |
| 452 least_packet_awaited_by_peer, max_packets_in_flight); | |
| 453 } | |
| 454 | |
| 455 void QuicPacketGenerator::SetConnectionIdLength(uint32 length) { | |
| 456 if (length == 0) { | |
| 457 packet_creator_.set_connection_id_length(PACKET_0BYTE_CONNECTION_ID); | |
| 458 } else if (length == 1) { | |
| 459 packet_creator_.set_connection_id_length(PACKET_1BYTE_CONNECTION_ID); | |
| 460 } else if (length <= 4) { | |
| 461 packet_creator_.set_connection_id_length(PACKET_4BYTE_CONNECTION_ID); | |
| 462 } else { | |
| 463 packet_creator_.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID); | |
| 464 } | |
| 465 } | |
| 466 | |
| 467 | |
| 468 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { | |
| 469 packet_creator_.set_encryption_level(level); | |
| 470 } | |
| 471 | |
| 472 } // namespace net | |
| OLD | NEW |