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

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

Issue 1470713003: Landing Recent QUIC changes until and including Mon Nov 16 14:15:48 2015 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding NET_EXPORT_PRIVATE to DelegateInterface. Created 5 years 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
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_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
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
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
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
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
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) << "Failed to SerializePacket. fec_policy:" << fec_send_policy_
501 << " should_fec_protect_:" << should_fec_protect_;
502 delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false);
503 return;
504 }
505
506 // There may be AckListeners interested in this packet.
507 serialized_packet->listeners.swap(ack_listeners_);
508 ack_listeners_.clear();
509
510 delegate_->OnSerializedPacket(*serialized_packet);
511 MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false);
512
513 // Maximum packet size may be only enacted while no packet is currently being
514 // constructed, so here we have a good opportunity to actually change it.
515 if (packet_creator_.CanSetMaxPacketLength()) {
516 packet_creator_.SetMaxPacketLength(max_packet_length_);
517 }
518
519 // The packet has now been serialized, so the frames are no longer queued.
520 ack_queued_ = false;
521 stop_waiting_queued_ = false;
522 }
523
535 } // namespace net 524 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698