| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 void QuicPacketCreator::set_max_packets_per_fec_group( | 98 void QuicPacketCreator::set_max_packets_per_fec_group( |
| 99 size_t max_packets_per_fec_group) { | 99 size_t max_packets_per_fec_group) { |
| 100 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, | 100 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, |
| 101 max_packets_per_fec_group); | 101 max_packets_per_fec_group); |
| 102 DCHECK_LT(0u, max_packets_per_fec_group_); | 102 DCHECK_LT(0u, max_packets_per_fec_group_); |
| 103 } | 103 } |
| 104 | 104 |
| 105 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { | 105 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { |
| 106 DCHECK(!HasPendingFrames()); | 106 DCHECK(!HasPendingFrames()); |
| 107 return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 && | 107 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 && |
| 108 (force_close || fec_group_->NumReceivedPackets() >= | 108 (force_close || |
| 109 max_packets_per_fec_group_); | 109 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); |
| 110 } | 110 } |
| 111 | 111 |
| 112 bool QuicPacketCreator::IsFecGroupOpen() const { | 112 bool QuicPacketCreator::IsFecGroupOpen() const { |
| 113 return fec_group_.get() != NULL; | 113 return fec_group_.get() != nullptr; |
| 114 } | 114 } |
| 115 | 115 |
| 116 void QuicPacketCreator::StartFecProtectingPackets() { | 116 void QuicPacketCreator::StartFecProtectingPackets() { |
| 117 if (!IsFecEnabled()) { | 117 if (!IsFecEnabled()) { |
| 118 LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled."; | 118 LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled."; |
| 119 return; | 119 return; |
| 120 } | 120 } |
| 121 // TODO(jri): This currently requires that the generator flush out any | 121 // TODO(jri): This currently requires that the generator flush out any |
| 122 // pending frames when FEC protection is turned on. If current packet can be | 122 // pending frames when FEC protection is turned on. If current packet can be |
| 123 // converted to an FEC protected packet, do it. This will require the | 123 // converted to an FEC protected packet, do it. This will require the |
| 124 // generator to check if the resulting expansion still allows the incoming | 124 // generator to check if the resulting expansion still allows the incoming |
| 125 // frame to be added to the packet. | 125 // frame to be added to the packet. |
| 126 if (HasPendingFrames()) { | 126 if (HasPendingFrames()) { |
| 127 LOG(DFATAL) << "Cannot start FEC protection with pending frames."; | 127 LOG(DFATAL) << "Cannot start FEC protection with pending frames."; |
| 128 return; | 128 return; |
| 129 } | 129 } |
| 130 DCHECK(!should_fec_protect_); | 130 DCHECK(!should_fec_protect_); |
| 131 should_fec_protect_ = true; | 131 should_fec_protect_ = true; |
| 132 } | 132 } |
| 133 | 133 |
| 134 void QuicPacketCreator::StopFecProtectingPackets() { | 134 void QuicPacketCreator::StopFecProtectingPackets() { |
| 135 if (fec_group_.get() != NULL) { | 135 if (fec_group_.get() != nullptr) { |
| 136 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; | 136 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; |
| 137 return; | 137 return; |
| 138 } | 138 } |
| 139 DCHECK(should_fec_protect_); | 139 DCHECK(should_fec_protect_); |
| 140 should_fec_protect_ = false; | 140 should_fec_protect_ = false; |
| 141 fec_group_number_ = 0; | 141 fec_group_number_ = 0; |
| 142 } | 142 } |
| 143 | 143 |
| 144 bool QuicPacketCreator::IsFecProtected() const { | 144 bool QuicPacketCreator::IsFecProtected() const { |
| 145 return should_fec_protect_; | 145 return should_fec_protect_; |
| 146 } | 146 } |
| 147 | 147 |
| 148 bool QuicPacketCreator::IsFecEnabled() const { | 148 bool QuicPacketCreator::IsFecEnabled() const { |
| 149 return max_packets_per_fec_group_ > 0; | 149 return max_packets_per_fec_group_ > 0; |
| 150 } | 150 } |
| 151 | 151 |
| 152 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { | 152 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { |
| 153 if (fec_group_.get() != NULL) { | 153 if (fec_group_.get() != nullptr) { |
| 154 // Don't update any lengths when an FEC group is open, to ensure same | 154 // Don't update any lengths when an FEC group is open, to ensure same |
| 155 // packet header size in all packets within a group. | 155 // packet header size in all packets within a group. |
| 156 return IN_FEC_GROUP; | 156 return IN_FEC_GROUP; |
| 157 } | 157 } |
| 158 if (!queued_frames_.empty()) { | 158 if (!queued_frames_.empty()) { |
| 159 // Don't change creator state if there are frames queued. | 159 // Don't change creator state if there are frames queued. |
| 160 return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; | 160 return fec_group_.get() == nullptr ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; |
| 161 } | 161 } |
| 162 | 162 |
| 163 // Update sequence number length only on packet and FEC group boundaries. | 163 // Update sequence number length only on packet and FEC group boundaries. |
| 164 sequence_number_length_ = next_sequence_number_length_; | 164 sequence_number_length_ = next_sequence_number_length_; |
| 165 | 165 |
| 166 if (!should_fec_protect_) { | 166 if (!should_fec_protect_) { |
| 167 return NOT_IN_FEC_GROUP; | 167 return NOT_IN_FEC_GROUP; |
| 168 } | 168 } |
| 169 // Start a new FEC group since protection is on. Set the fec group number to | 169 // Start a new FEC group since protection is on. Set the fec group number to |
| 170 // the sequence number of the next packet. | 170 // the sequence number of the next packet. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 // a packet. At that point the notifier is informed of the sequence number | 276 // a packet. At that point the notifier is informed of the sequence number |
| 277 // of the packet that this frame was eventually sent in. | 277 // of the packet that this frame was eventually sent in. |
| 278 frame->stream_frame->notifier = notifier; | 278 frame->stream_frame->notifier = notifier; |
| 279 | 279 |
| 280 return bytes_consumed; | 280 return bytes_consumed; |
| 281 } | 281 } |
| 282 | 282 |
| 283 SerializedPacket QuicPacketCreator::ReserializeAllFrames( | 283 SerializedPacket QuicPacketCreator::ReserializeAllFrames( |
| 284 const QuicFrames& frames, | 284 const QuicFrames& frames, |
| 285 QuicSequenceNumberLength original_length) { | 285 QuicSequenceNumberLength original_length) { |
| 286 DCHECK(fec_group_.get() == NULL); | 286 DCHECK(fec_group_.get() == nullptr); |
| 287 const QuicSequenceNumberLength saved_length = sequence_number_length_; | 287 const QuicSequenceNumberLength saved_length = sequence_number_length_; |
| 288 const QuicSequenceNumberLength saved_next_length = | 288 const QuicSequenceNumberLength saved_next_length = |
| 289 next_sequence_number_length_; | 289 next_sequence_number_length_; |
| 290 const bool saved_should_fec_protect = should_fec_protect_; | 290 const bool saved_should_fec_protect = should_fec_protect_; |
| 291 | 291 |
| 292 // Temporarily set the sequence number length and stop FEC protection. | 292 // Temporarily set the sequence number length and stop FEC protection. |
| 293 sequence_number_length_ = original_length; | 293 sequence_number_length_ = original_length; |
| 294 next_sequence_number_length_ = original_length; | 294 next_sequence_number_length_ = original_length; |
| 295 should_fec_protect_ = false; | 295 should_fec_protect_ = false; |
| 296 | 296 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 309 // frames from SendStreamData()[send_stream_should_flush_ == false && | 309 // frames from SendStreamData()[send_stream_should_flush_ == false && |
| 310 // data.empty() == true] and retransmit due to RTO. | 310 // data.empty() == true] and retransmit due to RTO. |
| 311 DCHECK_EQ(0u, queued_frames_.size()); | 311 DCHECK_EQ(0u, queued_frames_.size()); |
| 312 LOG_IF(DFATAL, frames.empty()) | 312 LOG_IF(DFATAL, frames.empty()) |
| 313 << "Attempt to serialize empty packet"; | 313 << "Attempt to serialize empty packet"; |
| 314 for (size_t i = 0; i < frames.size(); ++i) { | 314 for (size_t i = 0; i < frames.size(); ++i) { |
| 315 bool success = AddFrame(frames[i], false); | 315 bool success = AddFrame(frames[i], false); |
| 316 DCHECK(success); | 316 DCHECK(success); |
| 317 } | 317 } |
| 318 SerializedPacket packet = SerializePacket(); | 318 SerializedPacket packet = SerializePacket(); |
| 319 DCHECK(packet.retransmittable_frames == NULL); | 319 DCHECK(packet.retransmittable_frames == nullptr); |
| 320 return packet; | 320 return packet; |
| 321 } | 321 } |
| 322 | 322 |
| 323 bool QuicPacketCreator::HasPendingFrames() const { | 323 bool QuicPacketCreator::HasPendingFrames() const { |
| 324 return !queued_frames_.empty(); | 324 return !queued_frames_.empty(); |
| 325 } | 325 } |
| 326 | 326 |
| 327 bool QuicPacketCreator::HasPendingRetransmittableFrames() const { | 327 bool QuicPacketCreator::HasPendingRetransmittableFrames() const { |
| 328 return queued_retransmittable_frames_.get() != NULL && | 328 return queued_retransmittable_frames_.get() != nullptr && |
| 329 !queued_retransmittable_frames_->frames().empty(); | 329 !queued_retransmittable_frames_->frames().empty(); |
| 330 } | 330 } |
| 331 | 331 |
| 332 size_t QuicPacketCreator::ExpansionOnNewFrame() const { | 332 size_t QuicPacketCreator::ExpansionOnNewFrame() const { |
| 333 // If packet is FEC protected, there's no expansion. | 333 // If packet is FEC protected, there's no expansion. |
| 334 if (should_fec_protect_) { | 334 if (should_fec_protect_) { |
| 335 return 0; | 335 return 0; |
| 336 } | 336 } |
| 337 // If the last frame in the packet is a stream frame, then it will expand to | 337 // If the last frame in the packet is a stream frame, then it will expand to |
| 338 // include the stream_length field when a new frame is added. | 338 // include the stream_length field when a new frame is added. |
| 339 bool has_trailing_stream_frame = | 339 bool has_trailing_stream_frame = |
| 340 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; | 340 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; |
| 341 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; | 341 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; |
| 342 } | 342 } |
| 343 | 343 |
| 344 size_t QuicPacketCreator::BytesFree() const { | 344 size_t QuicPacketCreator::BytesFree() const { |
| 345 const size_t max_plaintext_size = | 345 const size_t max_plaintext_size = |
| 346 framer_->GetMaxPlaintextSize(max_packet_length_); | 346 framer_->GetMaxPlaintextSize(max_packet_length_); |
| 347 DCHECK_GE(max_plaintext_size, PacketSize()); | 347 DCHECK_GE(max_plaintext_size, PacketSize()); |
| 348 return max_plaintext_size - min(max_plaintext_size, PacketSize() | 348 return max_plaintext_size - min(max_plaintext_size, PacketSize() |
| 349 + ExpansionOnNewFrame()); | 349 + ExpansionOnNewFrame()); |
| 350 } | 350 } |
| 351 | 351 |
| 352 size_t QuicPacketCreator::PacketSize() const { | 352 size_t QuicPacketCreator::PacketSize() const { |
| 353 if (!queued_frames_.empty()) { | 353 if (!queued_frames_.empty()) { |
| 354 return packet_size_; | 354 return packet_size_; |
| 355 } | 355 } |
| 356 if (fec_group_.get() == NULL) { | 356 if (fec_group_.get() == nullptr) { |
| 357 // Update sequence number length on packet and FEC boundary. | 357 // Update sequence number length on packet and FEC boundary. |
| 358 sequence_number_length_ = next_sequence_number_length_; | 358 sequence_number_length_ = next_sequence_number_length_; |
| 359 } | 359 } |
| 360 packet_size_ = GetPacketHeaderSize( | 360 packet_size_ = GetPacketHeaderSize( |
| 361 connection_id_length_, send_version_in_packet_, sequence_number_length_, | 361 connection_id_length_, send_version_in_packet_, sequence_number_length_, |
| 362 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); | 362 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); |
| 363 return packet_size_; | 363 return packet_size_; |
| 364 } | 364 } |
| 365 | 365 |
| 366 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { | 366 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 395 if (!possibly_truncated_by_length) { | 395 if (!possibly_truncated_by_length) { |
| 396 DCHECK_EQ(packet_size_, serialized.packet->length()); | 396 DCHECK_EQ(packet_size_, serialized.packet->length()); |
| 397 } | 397 } |
| 398 packet_size_ = 0; | 398 packet_size_ = 0; |
| 399 queued_frames_.clear(); | 399 queued_frames_.clear(); |
| 400 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); | 400 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); |
| 401 return serialized; | 401 return serialized; |
| 402 } | 402 } |
| 403 | 403 |
| 404 SerializedPacket QuicPacketCreator::SerializeFec() { | 404 SerializedPacket QuicPacketCreator::SerializeFec() { |
| 405 if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) { | 405 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { |
| 406 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; | 406 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; |
| 407 // TODO(jri): Make this a public method of framer? | 407 // TODO(jri): Make this a public method of framer? |
| 408 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL); | 408 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, |
| 409 nullptr); |
| 409 return kNoPacket; | 410 return kNoPacket; |
| 410 } | 411 } |
| 411 DCHECK_EQ(0u, queued_frames_.size()); | 412 DCHECK_EQ(0u, queued_frames_.size()); |
| 412 QuicPacketHeader header; | 413 QuicPacketHeader header; |
| 413 FillPacketHeader(fec_group_number_, true, &header); | 414 FillPacketHeader(fec_group_number_, true, &header); |
| 414 QuicFecData fec_data; | 415 QuicFecData fec_data; |
| 415 fec_data.fec_group = fec_group_->min_protected_packet(); | 416 fec_data.fec_group = fec_group_->min_protected_packet(); |
| 416 fec_data.redundancy = fec_group_->payload_parity(); | 417 fec_data.redundancy = fec_group_->payload_parity(); |
| 417 SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data); | 418 SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data); |
| 418 fec_group_.reset(NULL); | 419 fec_group_.reset(nullptr); |
| 419 packet_size_ = 0; | 420 packet_size_ = 0; |
| 420 LOG_IF(DFATAL, !serialized.packet) | 421 LOG_IF(DFATAL, !serialized.packet) |
| 421 << "Failed to serialize fec packet for group:" << fec_data.fec_group; | 422 << "Failed to serialize fec packet for group:" << fec_data.fec_group; |
| 422 DCHECK_GE(max_packet_length_, serialized.packet->length()); | 423 DCHECK_GE(max_packet_length_, serialized.packet->length()); |
| 423 return serialized; | 424 return serialized; |
| 424 } | 425 } |
| 425 | 426 |
| 426 SerializedPacket QuicPacketCreator::SerializeConnectionClose( | 427 SerializedPacket QuicPacketCreator::SerializeConnectionClose( |
| 427 QuicConnectionCloseFrame* close_frame) { | 428 QuicConnectionCloseFrame* close_frame) { |
| 428 QuicFrames frames; | 429 QuicFrames frames; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 size_t frame_len = framer_->GetSerializedFrameLength( | 480 size_t frame_len = framer_->GetSerializedFrameLength( |
| 480 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 481 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, |
| 481 sequence_number_length_); | 482 sequence_number_length_); |
| 482 if (frame_len == 0) { | 483 if (frame_len == 0) { |
| 483 return false; | 484 return false; |
| 484 } | 485 } |
| 485 DCHECK_LT(0u, packet_size_); | 486 DCHECK_LT(0u, packet_size_); |
| 486 packet_size_ += ExpansionOnNewFrame() + frame_len; | 487 packet_size_ += ExpansionOnNewFrame() + frame_len; |
| 487 | 488 |
| 488 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | 489 if (save_retransmittable_frames && ShouldRetransmit(frame)) { |
| 489 if (queued_retransmittable_frames_.get() == NULL) { | 490 if (queued_retransmittable_frames_.get() == nullptr) { |
| 490 queued_retransmittable_frames_.reset(new RetransmittableFrames()); | 491 queued_retransmittable_frames_.reset(new RetransmittableFrames()); |
| 491 } | 492 } |
| 492 if (frame.type == STREAM_FRAME) { | 493 if (frame.type == STREAM_FRAME) { |
| 493 queued_frames_.push_back( | 494 queued_frames_.push_back( |
| 494 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame)); | 495 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame)); |
| 495 } else { | 496 } else { |
| 496 queued_frames_.push_back( | 497 queued_frames_.push_back( |
| 497 queued_retransmittable_frames_->AddNonStreamFrame(frame)); | 498 queued_retransmittable_frames_->AddNonStreamFrame(frame)); |
| 498 } | 499 } |
| 499 } else { | 500 } else { |
| 500 queued_frames_.push_back(frame); | 501 queued_frames_.push_back(frame); |
| 501 } | 502 } |
| 502 return true; | 503 return true; |
| 503 } | 504 } |
| 504 | 505 |
| 505 void QuicPacketCreator::MaybeAddPadding() { | 506 void QuicPacketCreator::MaybeAddPadding() { |
| 506 if (queued_retransmittable_frames_.get() == NULL) { | 507 if (queued_retransmittable_frames_.get() == nullptr) { |
| 507 return; | 508 return; |
| 508 } | 509 } |
| 509 if (!queued_retransmittable_frames_->HasCryptoHandshake()) { | 510 if (!queued_retransmittable_frames_->HasCryptoHandshake()) { |
| 510 return; | 511 return; |
| 511 } | 512 } |
| 512 if (BytesFree() == 0) { | 513 if (BytesFree() == 0) { |
| 513 // Don't pad full packets. | 514 // Don't pad full packets. |
| 514 return; | 515 return; |
| 515 } | 516 } |
| 516 QuicPaddingFrame padding; | 517 QuicPaddingFrame padding; |
| 517 bool success = AddFrame(QuicFrame(&padding), false); | 518 bool success = AddFrame(QuicFrame(&padding), false); |
| 518 DCHECK(success); | 519 DCHECK(success); |
| 519 } | 520 } |
| 520 | 521 |
| 521 } // namespace net | 522 } // namespace net |
| OLD | NEW |