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

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

Issue 300623009: Fixes bugs in packet size computation in the creator and in the framer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_packet_creator.h ('k') | net/quic/quic_packet_creator_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_creator.h" 5 #include "net/quic/quic_packet_creator.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/crypto/quic_random.h" 9 #include "net/quic/crypto/quic_random.h"
10 #include "net/quic/quic_ack_notifier.h" 10 #include "net/quic/quic_ack_notifier.h"
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 return options_.max_packets_per_fec_group; 130 return options_.max_packets_per_fec_group;
131 } 131 }
132 132
133 void QuicPacketCreator::set_max_packets_per_fec_group( 133 void QuicPacketCreator::set_max_packets_per_fec_group(
134 size_t max_packets_per_fec_group) { 134 size_t max_packets_per_fec_group) {
135 // To turn off FEC protection, use StopFecProtectingPackets(). 135 // To turn off FEC protection, use StopFecProtectingPackets().
136 DCHECK_NE(0u, max_packets_per_fec_group); 136 DCHECK_NE(0u, max_packets_per_fec_group);
137 options_.max_packets_per_fec_group = max_packets_per_fec_group; 137 options_.max_packets_per_fec_group = max_packets_per_fec_group;
138 } 138 }
139 139
140 InFecGroup QuicPacketCreator::MaybeStartFec() { 140 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
141 if (should_fec_protect_ && fec_group_.get() == NULL) { 141 if (fec_group_.get() != NULL) {
142 DCHECK(queued_frames_.empty()); 142 // Don't update any lengths when an FEC group is open, to ensure same
143 // Set the fec group number to the sequence number of the next packet. 143 // packet header size in all packets within a group.
144 fec_group_number_ = sequence_number() + 1; 144 return IN_FEC_GROUP;
145 fec_group_.reset(new QuicFecGroup());
146 } 145 }
147 return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; 146 if (!queued_frames_.empty()) {
147 // Don't change creator state if there are frames queued.
148 return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
149 }
150 // TODO(jri): Add max_packet_length and send_connection_id_length here too.
151 sequence_number_length_ = options_.send_sequence_number_length;
152
153 if (!should_fec_protect_) {
154 return NOT_IN_FEC_GROUP;
155 }
156 // Start a new FEC group since protection is on. Set the fec group number to
157 // the sequence number of the next packet.
158 fec_group_number_ = sequence_number() + 1;
159 fec_group_.reset(new QuicFecGroup());
160 return IN_FEC_GROUP;
148 } 161 }
149 162
150 // Stops serializing version of the protocol in packets sent after this call. 163 // Stops serializing version of the protocol in packets sent after this call.
151 // A packet that is already open might send kQuicVersionSize bytes less than the 164 // A packet that is already open might send kQuicVersionSize bytes less than the
152 // maximum packet size if we stop sending version before it is serialized. 165 // maximum packet size if we stop sending version before it is serialized.
153 void QuicPacketCreator::StopSendingVersion() { 166 void QuicPacketCreator::StopSendingVersion() {
154 DCHECK(send_version_in_packet_); 167 DCHECK(send_version_in_packet_);
155 send_version_in_packet_ = false; 168 send_version_in_packet_ = false;
156 if (packet_size_ > 0) { 169 if (packet_size_ > 0) {
157 DCHECK_LT(kQuicVersionSize, packet_size_); 170 DCHECK_LT(kQuicVersionSize, packet_size_);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, 215 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
203 const IOVector& data, 216 const IOVector& data,
204 QuicStreamOffset offset, 217 QuicStreamOffset offset,
205 bool fin, 218 bool fin,
206 QuicFrame* frame) { 219 QuicFrame* frame) {
207 DCHECK_GT(options_.max_packet_length, 220 DCHECK_GT(options_.max_packet_length,
208 StreamFramePacketOverhead( 221 StreamFramePacketOverhead(
209 framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, 222 framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
210 PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP)); 223 PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP));
211 224
212 InFecGroup is_in_fec_group = MaybeStartFec(); 225 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
213 226
214 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) 227 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
215 << "No room for Stream frame, BytesFree: " << BytesFree() 228 << "No room for Stream frame, BytesFree: " << BytesFree()
216 << " MinStreamFrameSize: " 229 << " MinStreamFrameSize: "
217 << QuicFramer::GetMinStreamFrameSize( 230 << QuicFramer::GetMinStreamFrameSize(
218 framer_->version(), id, offset, true, is_in_fec_group); 231 framer_->version(), id, offset, true, is_in_fec_group);
219 232
220 if (data.Empty()) { 233 if (data.Empty()) {
221 LOG_IF(DFATAL, !fin) 234 LOG_IF(DFATAL, !fin)
222 << "Creating a stream frame with no data or fin."; 235 << "Creating a stream frame with no data or fin.";
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 << "Attempt to serialize empty packet"; 360 << "Attempt to serialize empty packet";
348 DCHECK_GE(sequence_number_ + 1, fec_group_number_); 361 DCHECK_GE(sequence_number_ + 1, fec_group_number_);
349 QuicPacketHeader header; 362 QuicPacketHeader header;
350 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header); 363 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header);
351 364
352 MaybeAddPadding(); 365 MaybeAddPadding();
353 366
354 size_t max_plaintext_size = 367 size_t max_plaintext_size =
355 framer_->GetMaxPlaintextSize(options_.max_packet_length); 368 framer_->GetMaxPlaintextSize(options_.max_packet_length);
356 DCHECK_GE(max_plaintext_size, packet_size_); 369 DCHECK_GE(max_plaintext_size, packet_size_);
357 // ACK and CONNECTION_CLOSE Frames will be truncated only if they're 370 // ACK Frames will be truncated only if they're the only frame in the packet,
358 // the first frame in the packet. If truncation is to occur, then 371 // and if packet_size_ was set to max_plaintext_size. If truncation occurred,
359 // GetSerializedFrameLength will have returned all bytes free. 372 // then GetSerializedFrameLength will have returned all bytes free.
360 bool possibly_truncated = 373 bool possibly_truncated = packet_size_ == max_plaintext_size &&
361 packet_size_ != max_plaintext_size || 374 queued_frames_.size() == 1 &&
362 queued_frames_.size() != 1 || 375 queued_frames_.back().type == ACK_FRAME;
363 (queued_frames_.back().type == ACK_FRAME ||
364 queued_frames_.back().type == CONNECTION_CLOSE_FRAME);
365 SerializedPacket serialized = 376 SerializedPacket serialized =
366 framer_->BuildDataPacket(header, queued_frames_, packet_size_); 377 framer_->BuildDataPacket(header, queued_frames_, packet_size_);
367 LOG_IF(DFATAL, !serialized.packet) 378 LOG_IF(DFATAL, !serialized.packet)
368 << "Failed to serialize " << queued_frames_.size() << " frames."; 379 << "Failed to serialize " << queued_frames_.size() << " frames.";
369 // Because of possible truncation, we can't be confident that our 380 // Because of possible truncation, we can't be confident that our
370 // packet size calculation worked correctly. 381 // packet size calculation worked correctly.
371 if (!possibly_truncated) 382 if (!possibly_truncated) {
372 DCHECK_EQ(packet_size_, serialized.packet->length()); 383 DCHECK_EQ(packet_size_, serialized.packet->length());
384 }
373 385
374 packet_size_ = 0; 386 packet_size_ = 0;
375 queued_frames_.clear(); 387 queued_frames_.clear();
376 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); 388 serialized.retransmittable_frames = queued_retransmittable_frames_.release();
377 return serialized; 389 return serialized;
378 } 390 }
379 391
380 SerializedPacket QuicPacketCreator::SerializeFec() { 392 SerializedPacket QuicPacketCreator::SerializeFec() {
381 if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) { 393 if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) {
382 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; 394 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group.";
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 case STOP_WAITING_FRAME: 455 case STOP_WAITING_FRAME:
444 return false; 456 return false;
445 default: 457 default:
446 return true; 458 return true;
447 } 459 }
448 } 460 }
449 461
450 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, 462 bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
451 bool save_retransmittable_frames) { 463 bool save_retransmittable_frames) {
452 DVLOG(1) << "Adding frame: " << frame; 464 DVLOG(1) << "Adding frame: " << frame;
453 InFecGroup is_in_fec_group = MaybeStartFec(); 465 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
466
454 size_t frame_len = framer_->GetSerializedFrameLength( 467 size_t frame_len = framer_->GetSerializedFrameLength(
455 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, 468 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
456 options()->send_sequence_number_length); 469 sequence_number_length_);
457 if (frame_len == 0) { 470 if (frame_len == 0) {
458 return false; 471 return false;
459 } 472 }
460 DCHECK_LT(0u, packet_size_); 473 DCHECK_LT(0u, packet_size_);
461 packet_size_ += ExpansionOnNewFrame() + frame_len; 474 packet_size_ += ExpansionOnNewFrame() + frame_len;
462 475
463 if (save_retransmittable_frames && ShouldRetransmit(frame)) { 476 if (save_retransmittable_frames && ShouldRetransmit(frame)) {
464 if (queued_retransmittable_frames_.get() == NULL) { 477 if (queued_retransmittable_frames_.get() == NULL) {
465 queued_retransmittable_frames_.reset(new RetransmittableFrames()); 478 queued_retransmittable_frames_.reset(new RetransmittableFrames());
466 } 479 }
(...skipping 29 matching lines...) Expand all
496 if (!is_handshake) { 509 if (!is_handshake) {
497 return; 510 return;
498 } 511 }
499 512
500 QuicPaddingFrame padding; 513 QuicPaddingFrame padding;
501 bool success = AddFrame(QuicFrame(&padding), false); 514 bool success = AddFrame(QuicFrame(&padding), false);
502 DCHECK(success); 515 DCHECK(success);
503 } 516 }
504 517
505 } // namespace net 518 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_packet_creator.h ('k') | net/quic/quic_packet_creator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698