| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 | 69 |
| 70 QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id, | 70 QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id, |
| 71 QuicFramer* framer, | 71 QuicFramer* framer, |
| 72 QuicRandom* random_generator) | 72 QuicRandom* random_generator) |
| 73 : connection_id_(connection_id), | 73 : connection_id_(connection_id), |
| 74 encryption_level_(ENCRYPTION_NONE), | 74 encryption_level_(ENCRYPTION_NONE), |
| 75 framer_(framer), | 75 framer_(framer), |
| 76 random_bool_source_(new QuicRandomBoolSource(random_generator)), | 76 random_bool_source_(new QuicRandomBoolSource(random_generator)), |
| 77 packet_number_(0), | 77 packet_number_(0), |
| 78 should_fec_protect_(false), | 78 should_fec_protect_(false), |
| 79 fec_group_number_(0), | |
| 80 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT), | 79 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT), |
| 81 max_packet_length_(0), | 80 max_packet_length_(0), |
| 82 max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup), | 81 max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup), |
| 83 connection_id_length_(PACKET_8BYTE_CONNECTION_ID), | 82 connection_id_length_(PACKET_8BYTE_CONNECTION_ID), |
| 84 next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER), | 83 next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER), |
| 85 packet_number_length_(next_packet_number_length_), | 84 packet_number_length_(next_packet_number_length_), |
| 86 packet_size_(0), | 85 packet_size_(0), |
| 87 needs_padding_(false) { | 86 needs_padding_(false) { |
| 88 SetMaxPacketLength(kDefaultMaxPacketSize); | 87 SetMaxPacketLength(kDefaultMaxPacketSize); |
| 89 } | 88 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); | 122 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); |
| 124 } | 123 } |
| 125 | 124 |
| 126 void QuicPacketCreator::set_max_packets_per_fec_group( | 125 void QuicPacketCreator::set_max_packets_per_fec_group( |
| 127 size_t max_packets_per_fec_group) { | 126 size_t max_packets_per_fec_group) { |
| 128 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, | 127 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, |
| 129 max_packets_per_fec_group); | 128 max_packets_per_fec_group); |
| 130 DCHECK_LT(0u, max_packets_per_fec_group_); | 129 DCHECK_LT(0u, max_packets_per_fec_group_); |
| 131 } | 130 } |
| 132 | 131 |
| 132 QuicFecGroupNumber QuicPacketCreator::fec_group_number() { |
| 133 return fec_group_ != nullptr ? fec_group_->FecGroupNumber() : 0; |
| 134 } |
| 135 |
| 133 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { | 136 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { |
| 134 DCHECK(!HasPendingFrames()); | 137 DCHECK(!HasPendingFrames()); |
| 135 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 && | 138 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 && |
| 136 (force_close || | 139 (force_close || |
| 137 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); | 140 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); |
| 138 } | 141 } |
| 139 | 142 |
| 140 void QuicPacketCreator::ResetFecGroup() { | 143 void QuicPacketCreator::ResetFecGroup() { |
| 141 if (HasPendingFrames()) { | 144 if (HasPendingFrames()) { |
| 142 LOG_IF(DFATAL, packet_size_ != 0) | 145 LOG_IF(DFATAL, packet_size_ != 0) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 168 should_fec_protect_ = true; | 171 should_fec_protect_ = true; |
| 169 } | 172 } |
| 170 | 173 |
| 171 void QuicPacketCreator::StopFecProtectingPackets() { | 174 void QuicPacketCreator::StopFecProtectingPackets() { |
| 172 if (fec_group_.get() != nullptr) { | 175 if (fec_group_.get() != nullptr) { |
| 173 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; | 176 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; |
| 174 return; | 177 return; |
| 175 } | 178 } |
| 176 DCHECK(should_fec_protect_); | 179 DCHECK(should_fec_protect_); |
| 177 should_fec_protect_ = false; | 180 should_fec_protect_ = false; |
| 178 fec_group_number_ = 0; | |
| 179 } | 181 } |
| 180 | 182 |
| 181 bool QuicPacketCreator::IsFecProtected() const { | 183 bool QuicPacketCreator::IsFecProtected() const { |
| 182 return should_fec_protect_; | 184 return should_fec_protect_; |
| 183 } | 185 } |
| 184 | 186 |
| 185 bool QuicPacketCreator::IsFecEnabled() const { | 187 bool QuicPacketCreator::IsFecEnabled() const { |
| 186 return max_packets_per_fec_group_ > 0; | 188 return max_packets_per_fec_group_ > 0; |
| 187 } | 189 } |
| 188 | 190 |
| 189 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { | 191 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { |
| 190 if (fec_group_.get() != nullptr) { | 192 if (fec_group_.get() != nullptr) { |
| 191 // Don't update any lengths when an FEC group is open, to ensure same | 193 // Don't update any lengths when an FEC group is open, to ensure same |
| 192 // packet header size in all packets within a group. | 194 // packet header size in all packets within a group. |
| 193 return IN_FEC_GROUP; | 195 return IN_FEC_GROUP; |
| 194 } | 196 } |
| 195 if (!queued_frames_.empty()) { | 197 if (!queued_frames_.empty()) { |
| 196 // Don't change creator state if there are frames queued. | 198 // Don't change creator state if there are frames queued. |
| 197 return NOT_IN_FEC_GROUP; | 199 return NOT_IN_FEC_GROUP; |
| 198 } | 200 } |
| 199 | 201 |
| 200 // Update packet number length only on packet and FEC group boundaries. | 202 // Update packet number length only on packet and FEC group boundaries. |
| 201 packet_number_length_ = next_packet_number_length_; | 203 packet_number_length_ = next_packet_number_length_; |
| 202 | 204 |
| 203 if (!should_fec_protect_) { | 205 if (!should_fec_protect_) { |
| 204 return NOT_IN_FEC_GROUP; | 206 return NOT_IN_FEC_GROUP; |
| 205 } | 207 } |
| 206 // Start a new FEC group since protection is on. Set the fec group number to | 208 // Start a new FEC group since protection is on. Set the fec group number to |
| 207 // the packet number of the next packet. | 209 // the packet number of the next packet. |
| 208 fec_group_number_ = packet_number() + 1; | 210 fec_group_.reset(new QuicFecGroup(packet_number_ + 1)); |
| 209 fec_group_.reset(new QuicFecGroup(fec_group_number_)); | |
| 210 return IN_FEC_GROUP; | 211 return IN_FEC_GROUP; |
| 211 } | 212 } |
| 212 | 213 |
| 213 // Stops serializing version of the protocol in packets sent after this call. | 214 // Stops serializing version of the protocol in packets sent after this call. |
| 214 // A packet that is already open might send kQuicVersionSize bytes less than the | 215 // A packet that is already open might send kQuicVersionSize bytes less than the |
| 215 // maximum packet size if we stop sending version before it is serialized. | 216 // maximum packet size if we stop sending version before it is serialized. |
| 216 void QuicPacketCreator::StopSendingVersion() { | 217 void QuicPacketCreator::StopSendingVersion() { |
| 217 DCHECK(send_version_in_packet_); | 218 DCHECK(send_version_in_packet_); |
| 218 send_version_in_packet_ = false; | 219 send_version_in_packet_ = false; |
| 219 if (packet_size_ > 0) { | 220 if (packet_size_ > 0) { |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 /*save_retransmittable_frames=*/true, | 473 /*save_retransmittable_frames=*/true, |
| 473 /*needs_padding=*/true, buffer.Pass()); | 474 /*needs_padding=*/true, buffer.Pass()); |
| 474 } | 475 } |
| 475 | 476 |
| 476 SerializedPacket QuicPacketCreator::SerializePacket( | 477 SerializedPacket QuicPacketCreator::SerializePacket( |
| 477 char* encrypted_buffer, | 478 char* encrypted_buffer, |
| 478 size_t encrypted_buffer_len) { | 479 size_t encrypted_buffer_len) { |
| 479 DCHECK_LT(0u, encrypted_buffer_len); | 480 DCHECK_LT(0u, encrypted_buffer_len); |
| 480 LOG_IF(DFATAL, queued_frames_.empty()) | 481 LOG_IF(DFATAL, queued_frames_.empty()) |
| 481 << "Attempt to serialize empty packet"; | 482 << "Attempt to serialize empty packet"; |
| 482 DCHECK_GE(packet_number_ + 1, fec_group_number_); | 483 if (fec_group_.get() != nullptr) { |
| 484 DCHECK_GE(packet_number_ + 1, fec_group_->FecGroupNumber()); |
| 485 } |
| 483 QuicPacketHeader header; | 486 QuicPacketHeader header; |
| 484 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header); | 487 // FillPacketHeader increments packet_number_. |
| 488 FillPacketHeader(fec_group_number(), false, &header); |
| 485 | 489 |
| 486 MaybeAddPadding(); | 490 MaybeAddPadding(); |
| 487 | 491 |
| 488 DCHECK_GE(max_plaintext_size_, packet_size_); | 492 DCHECK_GE(max_plaintext_size_, packet_size_); |
| 489 // ACK Frames will be truncated due to length only if they're the only frame | 493 // ACK Frames will be truncated due to length only if they're the only frame |
| 490 // in the packet, and if packet_size_ was set to max_plaintext_size_. If | 494 // in the packet, and if packet_size_ was set to max_plaintext_size_. If |
| 491 // truncation due to length occurred, then GetSerializedFrameLength will have | 495 // truncation due to length occurred, then GetSerializedFrameLength will have |
| 492 // returned all bytes free. | 496 // returned all bytes free. |
| 493 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && | 497 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && |
| 494 queued_frames_.size() == 1 && | 498 queued_frames_.size() == 1 && |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer, | 564 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer, |
| 561 size_t buffer_len) { | 565 size_t buffer_len) { |
| 562 DCHECK_LT(0u, buffer_len); | 566 DCHECK_LT(0u, buffer_len); |
| 563 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { | 567 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { |
| 564 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; | 568 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; |
| 565 // TODO(jri): Make this a public method of framer? | 569 // TODO(jri): Make this a public method of framer? |
| 566 return NoPacket(); | 570 return NoPacket(); |
| 567 } | 571 } |
| 568 DCHECK_EQ(0u, queued_frames_.size()); | 572 DCHECK_EQ(0u, queued_frames_.size()); |
| 569 QuicPacketHeader header; | 573 QuicPacketHeader header; |
| 570 FillPacketHeader(fec_group_number_, true, &header); | 574 FillPacketHeader(fec_group_->FecGroupNumber(), true, &header); |
| 571 scoped_ptr<QuicPacket> packet( | 575 scoped_ptr<QuicPacket> packet( |
| 572 framer_->BuildFecPacket(header, fec_group_->PayloadParity())); | 576 framer_->BuildFecPacket(header, fec_group_->PayloadParity())); |
| 573 fec_group_.reset(nullptr); | 577 fec_group_.reset(nullptr); |
| 574 packet_size_ = 0; | 578 packet_size_ = 0; |
| 575 LOG_IF(DFATAL, packet == nullptr) | 579 LOG_IF(DFATAL, packet == nullptr) |
| 576 << "Failed to serialize fec packet for group:" << fec_group_number_; | 580 << "Failed to serialize fec packet for group:" |
| 581 << fec_group_->FecGroupNumber(); |
| 577 DCHECK_GE(max_packet_length_, packet->length()); | 582 DCHECK_GE(max_packet_length_, packet->length()); |
| 578 // Immediately encrypt the packet, to ensure we don't encrypt the same packet | 583 // Immediately encrypt the packet, to ensure we don't encrypt the same packet |
| 579 // packet number multiple times. | 584 // packet number multiple times. |
| 580 size_t encrypted_length = framer_->EncryptPayload( | 585 size_t encrypted_length = framer_->EncryptPayload( |
| 581 encryption_level_, packet_number_, *packet, buffer, buffer_len); | 586 encryption_level_, packet_number_, *packet, buffer, buffer_len); |
| 582 if (encrypted_length == 0) { | 587 if (encrypted_length == 0) { |
| 583 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; | 588 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; |
| 584 return NoPacket(); | 589 return NoPacket(); |
| 585 } | 590 } |
| 586 SerializedPacket serialized( | 591 SerializedPacket serialized( |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 if (BytesFree() == 0) { | 685 if (BytesFree() == 0) { |
| 681 // Don't pad full packets. | 686 // Don't pad full packets. |
| 682 return; | 687 return; |
| 683 } | 688 } |
| 684 | 689 |
| 685 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false, false, nullptr); | 690 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false, false, nullptr); |
| 686 DCHECK(success); | 691 DCHECK(success); |
| 687 } | 692 } |
| 688 | 693 |
| 689 } // namespace net | 694 } // namespace net |
| OLD | NEW |