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 1459343009: Make QuicPacketCreator be able to serialize packet itself when it does not have room for next strea… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@107733506
Patch Set: 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 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698