Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: net/quic/quic_packet_generator.cc

Issue 849123003: Land Recent QUIC Changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed extra blank line Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_packet_generator.h ('k') | net/quic/quic_packet_generator_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ack_notifier.h" 9 #include "net/quic/quic_ack_notifier.h"
10 #include "net/quic/quic_fec_group.h" 10 #include "net/quic/quic_fec_group.h"
11 #include "net/quic/quic_flags.h" 11 #include "net/quic/quic_flags.h"
12 #include "net/quic/quic_utils.h" 12 #include "net/quic/quic_utils.h"
13 13
14 using base::StringPiece; 14 using base::StringPiece;
15 15
16 namespace net { 16 namespace net {
17 17
18 namespace { 18 namespace {
19 19
20 // We want to put some space between a protected packet and the FEC packet to 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, 21 // avoid losing them both within the same loss episode. On the other hand, we
22 // we expect to be able to recover from any loss in about an RTT. 22 // expect to be able to recover from any loss in about an RTT. We resolve this
23 // We resolve this tradeoff by sending an FEC packet atmost half an RTT, 23 // tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half
24 // or equivalently, half the max number of in-flight packets, the first 24 // the max number of in-flight packets, the first protected packet. Since we
25 // protected packet. Since we don't want to delay an FEC packet past half an 25 // don't want to delay an FEC packet past half an RTT, we set the max FEC group
26 // RTT, we set the max FEC group size to be half the current congestion window. 26 // size to be half the current congestion window.
27 const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5; 27 const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5;
28 const float kRttMultiplierForFecTimeout = 0.5; 28 const float kRttMultiplierForFecTimeout = 0.5;
29 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
30 } // namespace 34 } // namespace
31 35
32 class QuicAckNotifier; 36 class QuicAckNotifier;
33 37
34 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, 38 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
35 QuicFramer* framer, 39 QuicFramer* framer,
36 QuicRandom* random_generator, 40 QuicRandom* random_generator,
37 DelegateInterface* delegate) 41 DelegateInterface* delegate)
38 : delegate_(delegate), 42 : delegate_(delegate),
39 debug_delegate_(nullptr), 43 debug_delegate_(nullptr),
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 delete notifier; 232 delete notifier;
229 } 233 }
230 234
231 // Don't allow the handshake to be bundled with other retransmittable frames. 235 // Don't allow the handshake to be bundled with other retransmittable frames.
232 if (handshake == IS_HANDSHAKE) { 236 if (handshake == IS_HANDSHAKE) {
233 SendQueuedFrames(true); 237 SendQueuedFrames(true);
234 } 238 }
235 239
236 // Try to close FEC group since we've either run out of data to send or we're 240 // Try to close FEC group since we've either run out of data to send or we're
237 // blocked. If not in batch mode, force close the group. 241 // blocked. If not in batch mode, force close the group.
238 // TODO(jri): This method should be called with flush=false here 242 MaybeSendFecPacketAndCloseGroup(/*flush=*/false);
239 // once the timer-based FEC sending is done, to separate FEC sending from
240 // the end of batch operations.
241 MaybeSendFecPacketAndCloseGroup(!InBatchMode());
242 243
243 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); 244 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames());
244 return QuicConsumedData(total_bytes_consumed, fin_consumed); 245 return QuicConsumedData(total_bytes_consumed, fin_consumed);
245 } 246 }
246 247
247 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { 248 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
248 DCHECK(HasPendingFrames()); 249 DCHECK(HasPendingFrames());
249 HasRetransmittableData retransmittable = 250 HasRetransmittableData retransmittable =
250 (should_send_ack_ || should_send_feedback_ || should_send_stop_waiting_) 251 (should_send_ack_ || should_send_feedback_ || should_send_stop_waiting_)
251 ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA; 252 ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA;
252 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { 253 if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
253 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. 254 DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
254 } 255 }
255 return delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, retransmittable, 256 return delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, retransmittable,
256 NOT_HANDSHAKE); 257 NOT_HANDSHAKE);
257 } 258 }
258 259
259 void QuicPacketGenerator::SendQueuedFrames(bool flush) { 260 void QuicPacketGenerator::SendQueuedFrames(bool flush) {
260 // Only add pending frames if we are SURE we can then send the whole packet. 261 // Only add pending frames if we are SURE we can then send the whole packet.
261 while (HasPendingFrames() && 262 while (HasPendingFrames() &&
262 (flush || CanSendWithNextPendingFrameAddition())) { 263 (flush || CanSendWithNextPendingFrameAddition())) {
263 if (!AddNextPendingFrame()) { 264 if (!AddNextPendingFrame()) {
264 // Packet was full, so serialize and send it. 265 // Packet was full, so serialize and send it.
265 SerializeAndSendPacket(); 266 SerializeAndSendPacket();
266 } 267 }
267 } 268 }
268 269 if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) {
269 if (!InBatchMode() || flush) { 270 SerializeAndSendPacket();
270 if (packet_creator_.HasPendingFrames()) {
271 SerializeAndSendPacket();
272 }
273 // Ensure the FEC group is closed at the end of this method unless other
274 // writes are pending.
275 MaybeSendFecPacketAndCloseGroup(true);
276 } 271 }
272 MaybeSendFecPacketAndCloseGroup(flush);
277 } 273 }
278 274
279 void QuicPacketGenerator::MaybeStartFecProtection() { 275 void QuicPacketGenerator::MaybeStartFecProtection() {
280 if (!packet_creator_.IsFecEnabled()) { 276 if (!packet_creator_.IsFecEnabled()) {
281 return; 277 return;
282 } 278 }
283 DVLOG(1) << "Turning FEC protection ON"; 279 DVLOG(1) << "Turning FEC protection ON";
284 should_fec_protect_ = true; 280 should_fec_protect_ = true;
285 if (packet_creator_.IsFecProtected()) { 281 if (packet_creator_.IsFecProtected()) {
286 // Only start creator's FEC protection if not already on. 282 // Only start creator's FEC protection if not already on.
287 return; 283 return;
288 } 284 }
289 if (HasQueuedFrames()) { 285 if (HasQueuedFrames()) {
290 // TODO(jri): This currently requires that the generator flush out any 286 // TODO(jri): This currently requires that the generator flush out any
291 // pending frames when FEC protection is turned on. If current packet can be 287 // pending frames when FEC protection is turned on. If current packet can be
292 // converted to an FEC protected packet, do it. This will require the 288 // converted to an FEC protected packet, do it. This will require the
293 // generator to check if the resulting expansion still allows the incoming 289 // generator to check if the resulting expansion still allows the incoming
294 // frame to be added to the packet. 290 // frame to be added to the packet.
295 SendQueuedFrames(true); 291 SendQueuedFrames(true);
296 } 292 }
297 packet_creator_.StartFecProtectingPackets(); 293 packet_creator_.StartFecProtectingPackets();
298 DCHECK(packet_creator_.IsFecProtected()); 294 DCHECK(packet_creator_.IsFecProtected());
299 } 295 }
300 296
301 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) { 297 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) {
302 if (!packet_creator_.IsFecProtected() || 298 if (!ShouldSendFecPacket(force)) {
303 packet_creator_.HasPendingFrames() ||
304 !packet_creator_.ShouldSendFec(force)) {
305 return; 299 return;
306 } 300 }
307 // TODO(jri): SerializeFec can return a NULL packet, and this should 301 // TODO(jri): SerializeFec can return a NULL packet, and this should
308 // cause an early return, with a call to delegate_->OnPacketGenerationError. 302 // cause an early return, with a call to delegate_->OnPacketGenerationError.
309 SerializedPacket serialized_fec = packet_creator_.SerializeFec(); 303 SerializedPacket serialized_fec = packet_creator_.SerializeFec();
310 DCHECK(serialized_fec.packet); 304 DCHECK(serialized_fec.packet);
311 delegate_->OnSerializedPacket(serialized_fec); 305 delegate_->OnSerializedPacket(serialized_fec);
312 // Turn FEC protection off if creator's protection is on and the creator 306 // Turn FEC protection off if creator's protection is on and the creator
313 // does not have an open FEC group. 307 // does not have an open FEC group.
314 // Note: We only wait until the frames queued in the creator are flushed; 308 // Note: We only wait until the frames queued in the creator are flushed;
315 // pending frames in the generator will not keep us from turning FEC off. 309 // pending frames in the generator will not keep us from turning FEC off.
316 if (!should_fec_protect_ && !packet_creator_.IsFecGroupOpen()) { 310 if (!should_fec_protect_ && !packet_creator_.IsFecGroupOpen()) {
317 packet_creator_.StopFecProtectingPackets(); 311 packet_creator_.StopFecProtectingPackets();
318 DCHECK(!packet_creator_.IsFecProtected()); 312 DCHECK(!packet_creator_.IsFecProtected());
319 } 313 }
320 } 314 }
321 315
316 bool QuicPacketGenerator::ShouldSendFecPacket(bool force) {
317 return packet_creator_.IsFecProtected() &&
318 !packet_creator_.HasPendingFrames() &&
319 packet_creator_.ShouldSendFec(force);
320 }
321
322 void QuicPacketGenerator::OnFecTimeout() {
323 DCHECK(!InBatchMode());
324 if (!ShouldSendFecPacket(true)) {
325 LOG(DFATAL) << "No FEC packet to send on FEC timeout.";
326 return;
327 }
328 // Flush out any pending frames in the generator and the creator, and then
329 // send out FEC packet.
330 SendQueuedFrames(true);
331 MaybeSendFecPacketAndCloseGroup(/*flush=*/true);
332 }
333
334 QuicTime::Delta QuicPacketGenerator::GetFecTimeout(
335 QuicPacketSequenceNumber sequence_number) {
336 // Do not set up FEC alarm for |sequence_number| it is not the first packet in
337 // the current group.
338 if (packet_creator_.IsFecGroupOpen() &&
339 (sequence_number == packet_creator_.fec_group_number())) {
340 return QuicTime::Delta::Max(
341 fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs));
342 }
343 return QuicTime::Delta::Infinite();
344 }
345
322 bool QuicPacketGenerator::InBatchMode() { 346 bool QuicPacketGenerator::InBatchMode() {
323 return batch_mode_; 347 return batch_mode_;
324 } 348 }
325 349
326 void QuicPacketGenerator::StartBatchOperations() { 350 void QuicPacketGenerator::StartBatchOperations() {
327 batch_mode_ = true; 351 batch_mode_ = true;
328 } 352 }
329 353
330 void QuicPacketGenerator::FinishBatchOperations() { 354 void QuicPacketGenerator::FinishBatchOperations() {
331 batch_mode_ = false; 355 batch_mode_ = false;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 SerializedPacket serialized_packet = packet_creator_.SerializePacket(); 420 SerializedPacket serialized_packet = packet_creator_.SerializePacket();
397 DCHECK(serialized_packet.packet); 421 DCHECK(serialized_packet.packet);
398 422
399 // There may be AckNotifiers interested in this packet. 423 // There may be AckNotifiers interested in this packet.
400 if (FLAGS_quic_attach_ack_notifiers_to_packets) { 424 if (FLAGS_quic_attach_ack_notifiers_to_packets) {
401 serialized_packet.notifiers.swap(ack_notifiers_); 425 serialized_packet.notifiers.swap(ack_notifiers_);
402 ack_notifiers_.clear(); 426 ack_notifiers_.clear();
403 } 427 }
404 428
405 delegate_->OnSerializedPacket(serialized_packet); 429 delegate_->OnSerializedPacket(serialized_packet);
406 MaybeSendFecPacketAndCloseGroup(false); 430 MaybeSendFecPacketAndCloseGroup(/*flush=*/false);
407 431
408 // The packet has now been serialized, safe to delete pending frames. 432 // The packet has now been serialized, safe to delete pending frames.
409 if (FLAGS_quic_disallow_multiple_pending_ack_frames) { 433 if (FLAGS_quic_disallow_multiple_pending_ack_frames) {
410 pending_ack_frame_.reset(); 434 pending_ack_frame_.reset();
411 pending_feedback_frame_.reset(); 435 pending_feedback_frame_.reset();
412 pending_stop_waiting_frame_.reset(); 436 pending_stop_waiting_frame_.reset();
413 } 437 }
414 } 438 }
415 439
416 void QuicPacketGenerator::StopSendingVersion() { 440 void QuicPacketGenerator::StopSendingVersion() {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 packet_creator_.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID); 482 packet_creator_.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID);
459 } 483 }
460 } 484 }
461 485
462 486
463 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { 487 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
464 packet_creator_.set_encryption_level(level); 488 packet_creator_.set_encryption_level(level);
465 } 489 }
466 490
467 } // namespace net 491 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_packet_generator.h ('k') | net/quic/quic_packet_generator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698