| 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 |