| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_packet_generator.h" | 5 #include "net/quic/quic_packet_generator.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "net/quic/quic_fec_group.h" | 9 #include "net/quic/quic_fec_group.h" |
| 10 #include "net/quic/quic_flags.h" | 10 #include "net/quic/quic_flags.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 } // namespace | 33 } // namespace |
| 34 | 34 |
| 35 class QuicAckNotifier; | 35 class QuicAckNotifier; |
| 36 | 36 |
| 37 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, | 37 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, |
| 38 QuicFramer* framer, | 38 QuicFramer* framer, |
| 39 QuicRandom* random_generator, | 39 QuicRandom* random_generator, |
| 40 DelegateInterface* delegate) | 40 DelegateInterface* delegate) |
| 41 : delegate_(delegate), | 41 : delegate_(delegate), |
| 42 debug_delegate_(nullptr), | 42 debug_delegate_(nullptr), |
| 43 packet_creator_(connection_id, framer, random_generator), | 43 packet_creator_(connection_id, framer, random_generator, this), |
| 44 batch_mode_(false), | 44 batch_mode_(false), |
| 45 fec_timeout_(QuicTime::Delta::Zero()), | 45 fec_timeout_(QuicTime::Delta::Zero()), |
| 46 rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout), | 46 rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout), |
| 47 should_fec_protect_(false), | 47 should_fec_protect_(false), |
| 48 fec_send_policy_(FEC_ANY_TRIGGER), | 48 fec_send_policy_(FEC_ANY_TRIGGER), |
| 49 should_send_ack_(false), | 49 should_send_ack_(false), |
| 50 should_send_stop_waiting_(false), | 50 should_send_stop_waiting_(false), |
| 51 ack_queued_(false), | 51 ack_queued_(false), |
| 52 stop_waiting_queued_(false), | 52 stop_waiting_queued_(false), |
| 53 max_packet_length_(kDefaultMaxPacketSize) {} | 53 max_packet_length_(kDefaultMaxPacketSize) {} |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 // To make reasoning about crypto frames easier, we don't combine them with | 132 // To make reasoning about crypto frames easier, we don't combine them with |
| 133 // other retransmittable frames in a single packet. | 133 // other retransmittable frames in a single packet. |
| 134 const bool flush = | 134 const bool flush = |
| 135 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); | 135 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); |
| 136 SendQueuedFrames(flush, /*is_fec_timeout=*/false); | 136 SendQueuedFrames(flush, /*is_fec_timeout=*/false); |
| 137 | 137 |
| 138 size_t total_bytes_consumed = 0; | 138 size_t total_bytes_consumed = 0; |
| 139 bool fin_consumed = false; | 139 bool fin_consumed = false; |
| 140 | 140 |
| 141 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { | 141 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { |
| 142 SerializeAndSendPacket(); | 142 packet_creator_.Flush(); |
| 143 } | 143 } |
| 144 | 144 |
| 145 if (fec_protection == MUST_FEC_PROTECT) { | 145 if (fec_protection == MUST_FEC_PROTECT) { |
| 146 MaybeStartFecProtection(); | 146 MaybeStartFecProtection(); |
| 147 } | 147 } |
| 148 | 148 |
| 149 if (!fin && (iov.total_length == 0)) { | 149 if (!fin && (iov.total_length == 0)) { |
| 150 LOG(DFATAL) << "Attempt to consume empty data without FIN."; | 150 LOG(DFATAL) << "Attempt to consume empty data without FIN."; |
| 151 return QuicConsumedData(0, false); | 151 return QuicConsumedData(0, false); |
| 152 } | 152 } |
| 153 | 153 |
| 154 int frames_created = 0; | |
| 155 while (delegate_->ShouldGeneratePacket( | 154 while (delegate_->ShouldGeneratePacket( |
| 156 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { | 155 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { |
| 157 QuicFrame frame; | 156 QuicFrame frame; |
| 158 UniqueStreamBuffer buffer; | 157 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, |
| 159 size_t bytes_consumed = packet_creator_.CreateStreamFrame( | 158 offset + total_bytes_consumed, fin, |
| 160 id, iov, total_bytes_consumed, offset + total_bytes_consumed, fin, | 159 has_handshake, &frame)) { |
| 161 &frame, &buffer); | 160 // Current packet is full and flushed. |
| 162 ++frames_created; | 161 continue; |
| 162 } |
| 163 | 163 |
| 164 if (!AddFrame(frame, buffer.Pass(), has_handshake)) { | 164 // A stream frame is created and added. |
| 165 LOG(DFATAL) << "Failed to add stream frame."; | 165 size_t bytes_consumed = frame.stream_frame->data.length(); |
| 166 // Inability to add a STREAM frame creates an unrecoverable hole in a | 166 if (debug_delegate_ != nullptr) { |
| 167 // the stream, so it's best to close the connection. | 167 debug_delegate_->OnFrameAddedToPacket(frame); |
| 168 delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false); | |
| 169 return QuicConsumedData(0, false); | |
| 170 } | 168 } |
| 169 |
| 171 if (listener != nullptr) { | 170 if (listener != nullptr) { |
| 172 ack_listeners_.push_back(AckListenerWrapper(listener, bytes_consumed)); | 171 ack_listeners_.push_back(AckListenerWrapper(listener, bytes_consumed)); |
| 173 } | 172 } |
| 174 | 173 |
| 175 total_bytes_consumed += bytes_consumed; | 174 total_bytes_consumed += bytes_consumed; |
| 176 fin_consumed = fin && total_bytes_consumed == iov.total_length; | 175 fin_consumed = fin && total_bytes_consumed == iov.total_length; |
| 177 DCHECK(total_bytes_consumed == iov.total_length || | 176 DCHECK(total_bytes_consumed == iov.total_length || |
| 178 packet_creator_.BytesFree() == 0u); | 177 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); |
| 179 | 178 |
| 180 if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) { | 179 if (!InBatchMode()) { |
| 181 // TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside | 180 // TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside |
| 182 // SerializeAndSendPacket() and make it an explicit call here (and | 181 // SerializeAndSendPacket() and make it an explicit call here (and |
| 183 // elsewhere where we call SerializeAndSendPacket?). | 182 // elsewhere where we call SerializeAndSendPacket?). |
| 184 SerializeAndSendPacket(); | 183 packet_creator_.Flush(); |
| 185 } | 184 } |
| 186 | 185 |
| 187 if (total_bytes_consumed == iov.total_length) { | 186 if (total_bytes_consumed == iov.total_length) { |
| 188 // We're done writing the data. Exit the loop. | 187 // We're done writing the data. Exit the loop. |
| 189 // We don't make this a precondition because we could have 0 bytes of data | 188 // We don't make this a precondition because we could have 0 bytes of data |
| 190 // if we're simply writing a fin. | 189 // if we're simply writing a fin. |
| 191 if (fec_protection == MUST_FEC_PROTECT) { | 190 if (fec_protection == MUST_FEC_PROTECT) { |
| 192 // Turn off FEC protection when we're done writing protected data. | 191 // Turn off FEC protection when we're done writing protected data. |
| 193 DVLOG(1) << "Turning FEC protection OFF"; | 192 DVLOG(1) << "Turning FEC protection OFF"; |
| 194 should_fec_protect_ = false; | 193 should_fec_protect_ = false; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 221 // serialized within this function. | 220 // serialized within this function. |
| 222 QuicMtuDiscoveryFrame mtu_discovery_frame; | 221 QuicMtuDiscoveryFrame mtu_discovery_frame; |
| 223 QuicFrame frame(mtu_discovery_frame); | 222 QuicFrame frame(mtu_discovery_frame); |
| 224 | 223 |
| 225 // Send the probe packet with the new length. | 224 // Send the probe packet with the new length. |
| 226 SetMaxPacketLength(target_mtu, /*force=*/true); | 225 SetMaxPacketLength(target_mtu, /*force=*/true); |
| 227 const bool success = AddFrame(frame, nullptr, /*needs_padding=*/true); | 226 const bool success = AddFrame(frame, nullptr, /*needs_padding=*/true); |
| 228 if (listener != nullptr) { | 227 if (listener != nullptr) { |
| 229 ack_listeners_.push_back(AckListenerWrapper(listener, 0)); | 228 ack_listeners_.push_back(AckListenerWrapper(listener, 0)); |
| 230 } | 229 } |
| 231 SerializeAndSendPacket(); | 230 packet_creator_.Flush(); |
| 232 // The only reason AddFrame can fail is that the packet is too full to fit in | 231 // The only reason AddFrame can fail is that the packet is too full to fit in |
| 233 // a ping. This is not possible for any sane MTU. | 232 // a ping. This is not possible for any sane MTU. |
| 234 DCHECK(success); | 233 DCHECK(success); |
| 235 | 234 |
| 236 // Reset the packet length back. | 235 // Reset the packet length back. |
| 237 SetMaxPacketLength(current_mtu, /*force=*/true); | 236 SetMaxPacketLength(current_mtu, /*force=*/true); |
| 238 } | 237 } |
| 239 | 238 |
| 240 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { | 239 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { |
| 241 DCHECK(HasPendingFrames()); | 240 DCHECK(HasPendingFrames()); |
| 242 HasRetransmittableData retransmittable = | 241 HasRetransmittableData retransmittable = |
| 243 (should_send_ack_ || should_send_stop_waiting_) | 242 (should_send_ack_ || should_send_stop_waiting_) |
| 244 ? NO_RETRANSMITTABLE_DATA | 243 ? NO_RETRANSMITTABLE_DATA |
| 245 : HAS_RETRANSMITTABLE_DATA; | 244 : HAS_RETRANSMITTABLE_DATA; |
| 246 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | 245 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { |
| 247 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | 246 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. |
| 248 } | 247 } |
| 249 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); | 248 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); |
| 250 } | 249 } |
| 251 | 250 |
| 252 void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) { | 251 void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) { |
| 253 // Only add pending frames if we are SURE we can then send the whole packet. | 252 // Only add pending frames if we are SURE we can then send the whole packet. |
| 254 while (HasPendingFrames() && | 253 while (HasPendingFrames() && |
| 255 (flush || CanSendWithNextPendingFrameAddition())) { | 254 (flush || CanSendWithNextPendingFrameAddition())) { |
| 256 if (!AddNextPendingFrame()) { | 255 AddNextPendingFrame(); |
| 257 // Packet was full, so serialize and send it. | |
| 258 SerializeAndSendPacket(); | |
| 259 } | |
| 260 } | 256 } |
| 261 if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) { | 257 if (flush || !InBatchMode()) { |
| 262 SerializeAndSendPacket(); | 258 packet_creator_.Flush(); |
| 263 } | 259 } |
| 264 MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout); | 260 MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout); |
| 265 } | 261 } |
| 266 | 262 |
| 267 void QuicPacketGenerator::MaybeStartFecProtection() { | 263 void QuicPacketGenerator::MaybeStartFecProtection() { |
| 268 if (!packet_creator_.IsFecEnabled()) { | 264 if (!packet_creator_.IsFecEnabled()) { |
| 269 return; | 265 return; |
| 270 } | 266 } |
| 271 DVLOG(1) << "Turning FEC protection ON"; | 267 DVLOG(1) << "Turning FEC protection ON"; |
| 272 should_fec_protect_ = true; | 268 should_fec_protect_ = true; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 bool needs_padding) { | 413 bool needs_padding) { |
| 418 bool success = needs_padding | 414 bool success = needs_padding |
| 419 ? packet_creator_.AddPaddedSavedFrame(frame, buffer.Pass()) | 415 ? packet_creator_.AddPaddedSavedFrame(frame, buffer.Pass()) |
| 420 : packet_creator_.AddSavedFrame(frame, buffer.Pass()); | 416 : packet_creator_.AddSavedFrame(frame, buffer.Pass()); |
| 421 if (success && debug_delegate_) { | 417 if (success && debug_delegate_) { |
| 422 debug_delegate_->OnFrameAddedToPacket(frame); | 418 debug_delegate_->OnFrameAddedToPacket(frame); |
| 423 } | 419 } |
| 424 return success; | 420 return success; |
| 425 } | 421 } |
| 426 | 422 |
| 427 void QuicPacketGenerator::SerializeAndSendPacket() { | |
| 428 // The optimized encryption algorithm implementations run faster when | |
| 429 // operating on aligned memory. | |
| 430 // | |
| 431 // TODO(rtenneti): Change the default 64 alignas value (used the default | |
| 432 // value from CACHELINE_SIZE). | |
| 433 ALIGNAS(64) char buffer[kMaxPacketSize]; | |
| 434 SerializedPacket serialized_packet = | |
| 435 packet_creator_.SerializePacket(buffer, kMaxPacketSize); | |
| 436 if (serialized_packet.packet == nullptr) { | |
| 437 LOG(DFATAL) << "Failed to SerializePacket. fec_policy:" << fec_send_policy_ | |
| 438 << " should_fec_protect_:" << should_fec_protect_; | |
| 439 delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false); | |
| 440 return; | |
| 441 } | |
| 442 | |
| 443 // There may be AckListeners interested in this packet. | |
| 444 serialized_packet.listeners.swap(ack_listeners_); | |
| 445 ack_listeners_.clear(); | |
| 446 | |
| 447 delegate_->OnSerializedPacket(serialized_packet); | |
| 448 MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false); | |
| 449 | |
| 450 // Maximum packet size may be only enacted while no packet is currently being | |
| 451 // constructed, so here we have a good opportunity to actually change it. | |
| 452 if (packet_creator_.CanSetMaxPacketLength()) { | |
| 453 packet_creator_.SetMaxPacketLength(max_packet_length_); | |
| 454 } | |
| 455 | |
| 456 // The packet has now been serialized, so the frames are no longer queued. | |
| 457 ack_queued_ = false; | |
| 458 stop_waiting_queued_ = false; | |
| 459 } | |
| 460 | |
| 461 void QuicPacketGenerator::StopSendingVersion() { | 423 void QuicPacketGenerator::StopSendingVersion() { |
| 462 packet_creator_.StopSendingVersion(); | 424 packet_creator_.StopSendingVersion(); |
| 463 } | 425 } |
| 464 | 426 |
| 465 QuicPacketNumber QuicPacketGenerator::packet_number() const { | 427 QuicPacketNumber QuicPacketGenerator::packet_number() const { |
| 466 return packet_creator_.packet_number(); | 428 return packet_creator_.packet_number(); |
| 467 } | 429 } |
| 468 | 430 |
| 469 QuicByteCount QuicPacketGenerator::GetMaxPacketLength() const { | 431 QuicByteCount QuicPacketGenerator::GetMaxPacketLength() const { |
| 470 return max_packet_length_; | 432 return max_packet_length_; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 | 487 |
| 526 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { | 488 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { |
| 527 packet_creator_.set_encryption_level(level); | 489 packet_creator_.set_encryption_level(level); |
| 528 } | 490 } |
| 529 | 491 |
| 530 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, | 492 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, |
| 531 QuicEncrypter* encrypter) { | 493 QuicEncrypter* encrypter) { |
| 532 packet_creator_.SetEncrypter(level, encrypter); | 494 packet_creator_.SetEncrypter(level, encrypter); |
| 533 } | 495 } |
| 534 | 496 |
| 497 void QuicPacketGenerator::OnSerializedPacket( |
| 498 SerializedPacket* serialized_packet) { |
| 499 if (serialized_packet->packet == nullptr) { |
| 500 LOG(DFATAL) |
| 501 << "Failed to SerializePacket. fec_policy:" << fec_send_policy_ |
| 502 << " should_fec_protect_:" << should_fec_protect_; |
| 503 delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false); |
| 504 return; |
| 505 } |
| 506 |
| 507 // There may be AckListeners interested in this packet. |
| 508 serialized_packet->listeners.swap(ack_listeners_); |
| 509 ack_listeners_.clear(); |
| 510 |
| 511 delegate_->OnSerializedPacket(*serialized_packet); |
| 512 MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false); |
| 513 |
| 514 // Maximum packet size may be only enacted while no packet is currently being |
| 515 // constructed, so here we have a good opportunity to actually change it. |
| 516 if (packet_creator_.CanSetMaxPacketLength()) { |
| 517 packet_creator_.SetMaxPacketLength(max_packet_length_); |
| 518 } |
| 519 |
| 520 // The packet has now been serialized, so the frames are no longer queued. |
| 521 ack_queued_ = false; |
| 522 stop_waiting_queued_ = false; |
| 523 } |
| 524 |
| 535 } // namespace net | 525 } // namespace net |
| OLD | NEW |