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 while (delegate_->ShouldGeneratePacket( | 154 while (delegate_->ShouldGeneratePacket( |
155 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { | 155 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { |
156 QuicFrame frame; | 156 QuicFrame frame; |
157 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, | 157 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, |
158 offset + total_bytes_consumed, fin, | 158 offset + total_bytes_consumed, fin, |
159 has_handshake, &frame)) { | 159 has_handshake, &frame)) { |
160 LOG(DFATAL) << "Created but failed to add a stream frame."; | 160 // Current packet is full and flushed. |
161 // Inability to add a STREAM frame creates an unrecoverable hole in a | 161 continue; |
162 // the stream, so it's best to close the connection. | |
163 delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false); | |
164 return QuicConsumedData(0, false); | |
165 } | 162 } |
166 DCHECK(frame.stream_frame); | 163 |
| 164 // A stream frame is created and added. |
167 size_t bytes_consumed = frame.stream_frame->data.length(); | 165 size_t bytes_consumed = frame.stream_frame->data.length(); |
168 if (debug_delegate_ != nullptr) { | 166 if (debug_delegate_ != nullptr) { |
169 debug_delegate_->OnFrameAddedToPacket(frame); | 167 debug_delegate_->OnFrameAddedToPacket(frame); |
170 } | 168 } |
171 | 169 |
172 if (listener != nullptr) { | 170 if (listener != nullptr) { |
173 ack_listeners_.push_back(AckListenerWrapper(listener, bytes_consumed)); | 171 ack_listeners_.push_back(AckListenerWrapper(listener, bytes_consumed)); |
174 } | 172 } |
175 | 173 |
176 total_bytes_consumed += bytes_consumed; | 174 total_bytes_consumed += bytes_consumed; |
177 fin_consumed = fin && total_bytes_consumed == iov.total_length; | 175 fin_consumed = fin && total_bytes_consumed == iov.total_length; |
178 DCHECK(total_bytes_consumed == iov.total_length || | 176 DCHECK(total_bytes_consumed == iov.total_length || |
179 packet_creator_.BytesFree() == 0u); | 177 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); |
180 | 178 |
181 if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) { | 179 if (!InBatchMode()) { |
182 // TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside | 180 // TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside |
183 // SerializeAndSendPacket() and make it an explicit call here (and | 181 // SerializeAndSendPacket() and make it an explicit call here (and |
184 // elsewhere where we call SerializeAndSendPacket?). | 182 // elsewhere where we call SerializeAndSendPacket?). |
185 SerializeAndSendPacket(); | 183 packet_creator_.Flush(); |
186 } | 184 } |
187 | 185 |
188 if (total_bytes_consumed == iov.total_length) { | 186 if (total_bytes_consumed == iov.total_length) { |
189 // We're done writing the data. Exit the loop. | 187 // We're done writing the data. Exit the loop. |
190 // 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 |
191 // if we're simply writing a fin. | 189 // if we're simply writing a fin. |
192 if (fec_protection == MUST_FEC_PROTECT) { | 190 if (fec_protection == MUST_FEC_PROTECT) { |
193 // Turn off FEC protection when we're done writing protected data. | 191 // Turn off FEC protection when we're done writing protected data. |
194 DVLOG(1) << "Turning FEC protection OFF"; | 192 DVLOG(1) << "Turning FEC protection OFF"; |
195 should_fec_protect_ = false; | 193 should_fec_protect_ = false; |
(...skipping 26 matching lines...) Expand all Loading... |
222 // serialized within this function. | 220 // serialized within this function. |
223 QuicMtuDiscoveryFrame mtu_discovery_frame; | 221 QuicMtuDiscoveryFrame mtu_discovery_frame; |
224 QuicFrame frame(mtu_discovery_frame); | 222 QuicFrame frame(mtu_discovery_frame); |
225 | 223 |
226 // Send the probe packet with the new length. | 224 // Send the probe packet with the new length. |
227 SetMaxPacketLength(target_mtu, /*force=*/true); | 225 SetMaxPacketLength(target_mtu, /*force=*/true); |
228 const bool success = AddFrame(frame, nullptr, /*needs_padding=*/true); | 226 const bool success = AddFrame(frame, nullptr, /*needs_padding=*/true); |
229 if (listener != nullptr) { | 227 if (listener != nullptr) { |
230 ack_listeners_.push_back(AckListenerWrapper(listener, 0)); | 228 ack_listeners_.push_back(AckListenerWrapper(listener, 0)); |
231 } | 229 } |
232 SerializeAndSendPacket(); | 230 packet_creator_.Flush(); |
233 // 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 |
234 // a ping. This is not possible for any sane MTU. | 232 // a ping. This is not possible for any sane MTU. |
235 DCHECK(success); | 233 DCHECK(success); |
236 | 234 |
237 // Reset the packet length back. | 235 // Reset the packet length back. |
238 SetMaxPacketLength(current_mtu, /*force=*/true); | 236 SetMaxPacketLength(current_mtu, /*force=*/true); |
239 } | 237 } |
240 | 238 |
241 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { | 239 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { |
242 DCHECK(HasPendingFrames()); | 240 DCHECK(HasPendingFrames()); |
243 HasRetransmittableData retransmittable = | 241 HasRetransmittableData retransmittable = |
244 (should_send_ack_ || should_send_stop_waiting_) | 242 (should_send_ack_ || should_send_stop_waiting_) |
245 ? NO_RETRANSMITTABLE_DATA | 243 ? NO_RETRANSMITTABLE_DATA |
246 : HAS_RETRANSMITTABLE_DATA; | 244 : HAS_RETRANSMITTABLE_DATA; |
247 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | 245 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { |
248 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | 246 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. |
249 } | 247 } |
250 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); | 248 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); |
251 } | 249 } |
252 | 250 |
253 void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) { | 251 void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) { |
254 // 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. |
255 while (HasPendingFrames() && | 253 while (HasPendingFrames() && |
256 (flush || CanSendWithNextPendingFrameAddition())) { | 254 (flush || CanSendWithNextPendingFrameAddition())) { |
257 if (!AddNextPendingFrame()) { | 255 AddNextPendingFrame(); |
258 // Packet was full, so serialize and send it. | |
259 SerializeAndSendPacket(); | |
260 } | |
261 } | 256 } |
262 if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) { | 257 if (flush || !InBatchMode()) { |
263 SerializeAndSendPacket(); | 258 packet_creator_.Flush(); |
264 } | 259 } |
265 MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout); | 260 MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout); |
266 } | 261 } |
267 | 262 |
268 void QuicPacketGenerator::MaybeStartFecProtection() { | 263 void QuicPacketGenerator::MaybeStartFecProtection() { |
269 if (!packet_creator_.IsFecEnabled()) { | 264 if (!packet_creator_.IsFecEnabled()) { |
270 return; | 265 return; |
271 } | 266 } |
272 DVLOG(1) << "Turning FEC protection ON"; | 267 DVLOG(1) << "Turning FEC protection ON"; |
273 should_fec_protect_ = true; | 268 should_fec_protect_ = true; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 bool needs_padding) { | 413 bool needs_padding) { |
419 bool success = needs_padding | 414 bool success = needs_padding |
420 ? packet_creator_.AddPaddedSavedFrame(frame, buffer.Pass()) | 415 ? packet_creator_.AddPaddedSavedFrame(frame, buffer.Pass()) |
421 : packet_creator_.AddSavedFrame(frame, buffer.Pass()); | 416 : packet_creator_.AddSavedFrame(frame, buffer.Pass()); |
422 if (success && debug_delegate_) { | 417 if (success && debug_delegate_) { |
423 debug_delegate_->OnFrameAddedToPacket(frame); | 418 debug_delegate_->OnFrameAddedToPacket(frame); |
424 } | 419 } |
425 return success; | 420 return success; |
426 } | 421 } |
427 | 422 |
428 void QuicPacketGenerator::SerializeAndSendPacket() { | |
429 // The optimized encryption algorithm implementations run faster when | |
430 // operating on aligned memory. | |
431 // | |
432 // TODO(rtenneti): Change the default 64 alignas value (used the default | |
433 // value from CACHELINE_SIZE). | |
434 ALIGNAS(64) char buffer[kMaxPacketSize]; | |
435 SerializedPacket serialized_packet = | |
436 packet_creator_.SerializePacket(buffer, kMaxPacketSize); | |
437 if (serialized_packet.packet == nullptr) { | |
438 LOG(DFATAL) << "Failed to SerializePacket. fec_policy:" << fec_send_policy_ | |
439 << " should_fec_protect_:" << should_fec_protect_; | |
440 delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false); | |
441 return; | |
442 } | |
443 | |
444 // There may be AckListeners interested in this packet. | |
445 serialized_packet.listeners.swap(ack_listeners_); | |
446 ack_listeners_.clear(); | |
447 | |
448 delegate_->OnSerializedPacket(serialized_packet); | |
449 MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false); | |
450 | |
451 // Maximum packet size may be only enacted while no packet is currently being | |
452 // constructed, so here we have a good opportunity to actually change it. | |
453 if (packet_creator_.CanSetMaxPacketLength()) { | |
454 packet_creator_.SetMaxPacketLength(max_packet_length_); | |
455 } | |
456 | |
457 // The packet has now been serialized, so the frames are no longer queued. | |
458 ack_queued_ = false; | |
459 stop_waiting_queued_ = false; | |
460 } | |
461 | |
462 void QuicPacketGenerator::StopSendingVersion() { | 423 void QuicPacketGenerator::StopSendingVersion() { |
463 packet_creator_.StopSendingVersion(); | 424 packet_creator_.StopSendingVersion(); |
464 } | 425 } |
465 | 426 |
466 QuicPacketNumber QuicPacketGenerator::packet_number() const { | 427 QuicPacketNumber QuicPacketGenerator::packet_number() const { |
467 return packet_creator_.packet_number(); | 428 return packet_creator_.packet_number(); |
468 } | 429 } |
469 | 430 |
470 QuicByteCount QuicPacketGenerator::GetMaxPacketLength() const { | 431 QuicByteCount QuicPacketGenerator::GetMaxPacketLength() const { |
471 return max_packet_length_; | 432 return max_packet_length_; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 | 487 |
527 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { | 488 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { |
528 packet_creator_.set_encryption_level(level); | 489 packet_creator_.set_encryption_level(level); |
529 } | 490 } |
530 | 491 |
531 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, | 492 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, |
532 QuicEncrypter* encrypter) { | 493 QuicEncrypter* encrypter) { |
533 packet_creator_.SetEncrypter(level, encrypter); | 494 packet_creator_.SetEncrypter(level, encrypter); |
534 } | 495 } |
535 | 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 |
536 } // namespace net | 525 } // namespace net |
OLD | NEW |