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 27 matching lines...) Expand all Loading... |
185 should_fec_protect_ ? IN_FEC_GROUP : | 198 should_fec_protect_ ? IN_FEC_GROUP : |
186 NOT_IN_FEC_GROUP); | 199 NOT_IN_FEC_GROUP); |
187 } | 200 } |
188 | 201 |
189 // static | 202 // static |
190 size_t QuicPacketCreator::StreamFramePacketOverhead( | 203 size_t QuicPacketCreator::StreamFramePacketOverhead( |
191 QuicVersion version, | 204 QuicVersion version, |
192 QuicConnectionIdLength connection_id_length, | 205 QuicConnectionIdLength connection_id_length, |
193 bool include_version, | 206 bool include_version, |
194 QuicSequenceNumberLength sequence_number_length, | 207 QuicSequenceNumberLength sequence_number_length, |
| 208 QuicStreamOffset offset, |
195 InFecGroup is_in_fec_group) { | 209 InFecGroup is_in_fec_group) { |
196 return GetPacketHeaderSize(connection_id_length, include_version, | 210 return GetPacketHeaderSize(connection_id_length, include_version, |
197 sequence_number_length, is_in_fec_group) + | 211 sequence_number_length, is_in_fec_group) + |
198 // Assumes this is a stream with a single lone packet. | 212 // Assumes this is a stream with a single lone packet. |
199 QuicFramer::GetMinStreamFrameSize(version, 1u, 0u, true, is_in_fec_group); | 213 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true, |
| 214 is_in_fec_group); |
200 } | 215 } |
201 | 216 |
202 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, | 217 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, |
203 const IOVector& data, | 218 const IOVector& data, |
204 QuicStreamOffset offset, | 219 QuicStreamOffset offset, |
205 bool fin, | 220 bool fin, |
206 QuicFrame* frame) { | 221 QuicFrame* frame) { |
207 DCHECK_GT(options_.max_packet_length, | 222 DCHECK_GT(options_.max_packet_length, |
208 StreamFramePacketOverhead( | 223 StreamFramePacketOverhead( |
209 framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, | 224 framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, |
210 PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP)); | 225 PACKET_6BYTE_SEQUENCE_NUMBER, offset, IN_FEC_GROUP)); |
211 | 226 |
212 InFecGroup is_in_fec_group = MaybeStartFec(); | 227 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
213 | 228 |
214 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) | 229 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) |
215 << "No room for Stream frame, BytesFree: " << BytesFree() | 230 << "No room for Stream frame, BytesFree: " << BytesFree() |
216 << " MinStreamFrameSize: " | 231 << " MinStreamFrameSize: " |
217 << QuicFramer::GetMinStreamFrameSize( | 232 << QuicFramer::GetMinStreamFrameSize( |
218 framer_->version(), id, offset, true, is_in_fec_group); | 233 framer_->version(), id, offset, true, is_in_fec_group); |
219 | 234 |
220 if (data.Empty()) { | 235 if (data.Empty()) { |
221 LOG_IF(DFATAL, !fin) | 236 LOG_IF(DFATAL, !fin) |
222 << "Creating a stream frame with no data or fin."; | 237 << "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"; | 362 << "Attempt to serialize empty packet"; |
348 DCHECK_GE(sequence_number_ + 1, fec_group_number_); | 363 DCHECK_GE(sequence_number_ + 1, fec_group_number_); |
349 QuicPacketHeader header; | 364 QuicPacketHeader header; |
350 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header); | 365 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header); |
351 | 366 |
352 MaybeAddPadding(); | 367 MaybeAddPadding(); |
353 | 368 |
354 size_t max_plaintext_size = | 369 size_t max_plaintext_size = |
355 framer_->GetMaxPlaintextSize(options_.max_packet_length); | 370 framer_->GetMaxPlaintextSize(options_.max_packet_length); |
356 DCHECK_GE(max_plaintext_size, packet_size_); | 371 DCHECK_GE(max_plaintext_size, packet_size_); |
357 // ACK and CONNECTION_CLOSE Frames will be truncated only if they're | 372 // 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 | 373 // and if packet_size_ was set to max_plaintext_size. If truncation occurred, |
359 // GetSerializedFrameLength will have returned all bytes free. | 374 // then GetSerializedFrameLength will have returned all bytes free. |
360 bool possibly_truncated = | 375 bool possibly_truncated = packet_size_ == max_plaintext_size && |
361 packet_size_ != max_plaintext_size || | 376 queued_frames_.size() == 1 && |
362 queued_frames_.size() != 1 || | 377 queued_frames_.back().type == ACK_FRAME; |
363 (queued_frames_.back().type == ACK_FRAME || | |
364 queued_frames_.back().type == CONNECTION_CLOSE_FRAME); | |
365 SerializedPacket serialized = | 378 SerializedPacket serialized = |
366 framer_->BuildDataPacket(header, queued_frames_, packet_size_); | 379 framer_->BuildDataPacket(header, queued_frames_, packet_size_); |
367 LOG_IF(DFATAL, !serialized.packet) | 380 LOG_IF(DFATAL, !serialized.packet) |
368 << "Failed to serialize " << queued_frames_.size() << " frames."; | 381 << "Failed to serialize " << queued_frames_.size() << " frames."; |
369 // Because of possible truncation, we can't be confident that our | 382 // Because of possible truncation, we can't be confident that our |
370 // packet size calculation worked correctly. | 383 // packet size calculation worked correctly. |
371 if (!possibly_truncated) | 384 if (!possibly_truncated) { |
372 DCHECK_EQ(packet_size_, serialized.packet->length()); | 385 DCHECK_EQ(packet_size_, serialized.packet->length()); |
| 386 } |
373 | 387 |
374 packet_size_ = 0; | 388 packet_size_ = 0; |
375 queued_frames_.clear(); | 389 queued_frames_.clear(); |
376 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); | 390 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); |
377 return serialized; | 391 return serialized; |
378 } | 392 } |
379 | 393 |
380 SerializedPacket QuicPacketCreator::SerializeFec() { | 394 SerializedPacket QuicPacketCreator::SerializeFec() { |
381 if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) { | 395 if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) { |
382 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; | 396 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: | 457 case STOP_WAITING_FRAME: |
444 return false; | 458 return false; |
445 default: | 459 default: |
446 return true; | 460 return true; |
447 } | 461 } |
448 } | 462 } |
449 | 463 |
450 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, | 464 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, |
451 bool save_retransmittable_frames) { | 465 bool save_retransmittable_frames) { |
452 DVLOG(1) << "Adding frame: " << frame; | 466 DVLOG(1) << "Adding frame: " << frame; |
453 InFecGroup is_in_fec_group = MaybeStartFec(); | 467 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
| 468 |
454 size_t frame_len = framer_->GetSerializedFrameLength( | 469 size_t frame_len = framer_->GetSerializedFrameLength( |
455 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 470 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, |
456 options()->send_sequence_number_length); | 471 sequence_number_length_); |
457 if (frame_len == 0) { | 472 if (frame_len == 0) { |
458 return false; | 473 return false; |
459 } | 474 } |
460 DCHECK_LT(0u, packet_size_); | 475 DCHECK_LT(0u, packet_size_); |
461 packet_size_ += ExpansionOnNewFrame() + frame_len; | 476 packet_size_ += ExpansionOnNewFrame() + frame_len; |
462 | 477 |
463 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | 478 if (save_retransmittable_frames && ShouldRetransmit(frame)) { |
464 if (queued_retransmittable_frames_.get() == NULL) { | 479 if (queued_retransmittable_frames_.get() == NULL) { |
465 queued_retransmittable_frames_.reset(new RetransmittableFrames()); | 480 queued_retransmittable_frames_.reset(new RetransmittableFrames()); |
466 } | 481 } |
(...skipping 29 matching lines...) Expand all Loading... |
496 if (!is_handshake) { | 511 if (!is_handshake) { |
497 return; | 512 return; |
498 } | 513 } |
499 | 514 |
500 QuicPaddingFrame padding; | 515 QuicPaddingFrame padding; |
501 bool success = AddFrame(QuicFrame(&padding), false); | 516 bool success = AddFrame(QuicFrame(&padding), false); |
502 DCHECK(success); | 517 DCHECK(success); |
503 } | 518 } |
504 | 519 |
505 } // namespace net | 520 } // namespace net |
OLD | NEW |