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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |