| 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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "net/quic/crypto/quic_random.h" | 11 #include "net/quic/crypto/quic_random.h" |
| 12 #include "net/quic/quic_bug_tracker.h" | 12 #include "net/quic/quic_bug_tracker.h" |
| 13 #include "net/quic/quic_data_writer.h" | 13 #include "net/quic/quic_data_writer.h" |
| 14 #include "net/quic/quic_fec_group.h" | |
| 15 #include "net/quic/quic_flags.h" | 14 #include "net/quic/quic_flags.h" |
| 16 #include "net/quic/quic_utils.h" | 15 #include "net/quic/quic_utils.h" |
| 17 | 16 |
| 18 using base::StringPiece; | 17 using base::StringPiece; |
| 19 using std::make_pair; | 18 using std::make_pair; |
| 20 using std::max; | 19 using std::max; |
| 21 using std::min; | 20 using std::min; |
| 22 using std::pair; | 21 using std::pair; |
| 23 using std::vector; | 22 using std::vector; |
| 24 | 23 |
| 25 namespace net { | 24 namespace net { |
| 26 | 25 |
| 27 namespace { | |
| 28 | |
| 29 // Default max packets in an FEC group. | |
| 30 static const size_t kDefaultMaxPacketsPerFecGroup = 10; | |
| 31 // Lowest max packets in an FEC group. | |
| 32 static const size_t kLowestMaxPacketsPerFecGroup = 2; | |
| 33 | |
| 34 // We want to put some space between a protected packet and the FEC packet to | |
| 35 // avoid losing them both within the same loss episode. On the other hand, we | |
| 36 // expect to be able to recover from any loss in about an RTT. We resolve this | |
| 37 // tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half | |
| 38 // the max number of in-flight packets, the first protected packet. Since we | |
| 39 // don't want to delay an FEC packet past half an RTT, we set the max FEC group | |
| 40 // size to be half the current congestion window. | |
| 41 const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5; | |
| 42 const float kRttMultiplierForFecTimeout = 0.5; | |
| 43 | |
| 44 // Minimum timeout for FEC alarm, set to half the minimum Tail Loss Probe | |
| 45 // timeout of 10ms. | |
| 46 const int64_t kMinFecTimeoutMs = 5u; | |
| 47 | |
| 48 } // namespace | |
| 49 | |
| 50 // A QuicRandom wrapper that gets a bucket of entropy and distributes it | 26 // A QuicRandom wrapper that gets a bucket of entropy and distributes it |
| 51 // bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this | 27 // bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this |
| 52 // class if single bit randomness is needed elsewhere. | 28 // class if single bit randomness is needed elsewhere. |
| 53 class QuicRandomBoolSource { | 29 class QuicRandomBoolSource { |
| 54 public: | 30 public: |
| 55 // random: Source of entropy. Not owned. | 31 // random: Source of entropy. Not owned. |
| 56 explicit QuicRandomBoolSource(QuicRandom* random) | 32 explicit QuicRandomBoolSource(QuicRandom* random) |
| 57 : random_(random), bit_bucket_(0), bit_mask_(0) {} | 33 : random_(random), bit_bucket_(0), bit_mask_(0) {} |
| 58 | 34 |
| 59 ~QuicRandomBoolSource() {} | 35 ~QuicRandomBoolSource() {} |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 connection_id_length_(PACKET_8BYTE_CONNECTION_ID), | 73 connection_id_length_(PACKET_8BYTE_CONNECTION_ID), |
| 98 packet_size_(0), | 74 packet_size_(0), |
| 99 connection_id_(connection_id), | 75 connection_id_(connection_id), |
| 100 packet_(kDefaultPathId, | 76 packet_(kDefaultPathId, |
| 101 0, | 77 0, |
| 102 next_packet_number_length_, | 78 next_packet_number_length_, |
| 103 nullptr, | 79 nullptr, |
| 104 0, | 80 0, |
| 105 0, | 81 0, |
| 106 false, | 82 false, |
| 107 false), | 83 false) { |
| 108 should_fec_protect_next_packet_(false), | |
| 109 fec_protect_(false), | |
| 110 max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup), | |
| 111 fec_send_policy_(FEC_ANY_TRIGGER), | |
| 112 fec_timeout_(QuicTime::Delta::Zero()), | |
| 113 rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout) { | |
| 114 SetMaxPacketLength(kDefaultMaxPacketSize); | 84 SetMaxPacketLength(kDefaultMaxPacketSize); |
| 115 } | 85 } |
| 116 | 86 |
| 117 QuicPacketCreator::~QuicPacketCreator() { | 87 QuicPacketCreator::~QuicPacketCreator() { |
| 118 QuicUtils::DeleteFrames(&packet_.retransmittable_frames); | 88 QuicUtils::DeleteFrames(&packet_.retransmittable_frames); |
| 119 } | 89 } |
| 120 | 90 |
| 121 void QuicPacketCreator::OnBuiltFecProtectedPayload( | |
| 122 const QuicPacketHeader& header, | |
| 123 StringPiece payload) { | |
| 124 if (fec_group_.get() != nullptr) { | |
| 125 DCHECK_NE(0u, header.fec_group); | |
| 126 fec_group_->Update(packet_.encryption_level, header, payload); | |
| 127 } | |
| 128 } | |
| 129 | |
| 130 void QuicPacketCreator::SetEncrypter(EncryptionLevel level, | 91 void QuicPacketCreator::SetEncrypter(EncryptionLevel level, |
| 131 QuicEncrypter* encrypter) { | 92 QuicEncrypter* encrypter) { |
| 132 framer_->SetEncrypter(level, encrypter); | 93 framer_->SetEncrypter(level, encrypter); |
| 133 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); | 94 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); |
| 134 } | 95 } |
| 135 | 96 |
| 136 bool QuicPacketCreator::CanSetMaxPacketLength() const { | 97 bool QuicPacketCreator::CanSetMaxPacketLength() const { |
| 137 // |max_packet_length_| should not be changed mid-packet or mid-FEC group. | 98 // |max_packet_length_| should not be changed mid-packet. |
| 138 return fec_group_.get() == nullptr && queued_frames_.empty(); | 99 return queued_frames_.empty(); |
| 139 } | 100 } |
| 140 | 101 |
| 141 void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) { | 102 void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) { |
| 142 DCHECK(CanSetMaxPacketLength()); | 103 DCHECK(CanSetMaxPacketLength()); |
| 143 | 104 |
| 144 // Avoid recomputing |max_plaintext_size_| if the length does not actually | 105 // Avoid recomputing |max_plaintext_size_| if the length does not actually |
| 145 // change. | 106 // change. |
| 146 if (length == max_packet_length_) { | 107 if (length == max_packet_length_) { |
| 147 return; | 108 return; |
| 148 } | 109 } |
| 149 | 110 |
| 150 max_packet_length_ = length; | 111 max_packet_length_ = length; |
| 151 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); | 112 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); |
| 152 } | 113 } |
| 153 | 114 |
| 154 void QuicPacketCreator::set_max_packets_per_fec_group( | 115 void QuicPacketCreator::MaybeUpdatePacketNumberLength() { |
| 155 size_t max_packets_per_fec_group) { | 116 if (!queued_frames_.empty()) { |
| 156 max_packets_per_fec_group_ = | 117 // Don't change creator state if there are frames queued. |
| 157 max(kLowestMaxPacketsPerFecGroup, max_packets_per_fec_group); | |
| 158 DCHECK_LT(0u, max_packets_per_fec_group_); | |
| 159 } | |
| 160 | |
| 161 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { | |
| 162 return !HasPendingFrames() && fec_group_.get() != nullptr && | |
| 163 fec_group_->NumReceivedPackets() > 0 && | |
| 164 (force_close || | |
| 165 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); | |
| 166 } | |
| 167 | |
| 168 void QuicPacketCreator::ResetFecGroup() { | |
| 169 if (HasPendingFrames()) { | |
| 170 QUIC_BUG_IF(packet_size_ != 0) | |
| 171 << "Cannot reset FEC group with pending frames."; | |
| 172 return; | 118 return; |
| 173 } | 119 } |
| 174 fec_group_.reset(nullptr); | |
| 175 } | |
| 176 | 120 |
| 177 bool QuicPacketCreator::IsFecGroupOpen() const { | 121 // Update packet number length only on packet boundary. |
| 178 return fec_group_.get() != nullptr; | |
| 179 } | |
| 180 | |
| 181 void QuicPacketCreator::StartFecProtectingPackets() { | |
| 182 if (max_packets_per_fec_group_ == 0) { | |
| 183 QUIC_BUG << "Cannot start FEC protection when FEC is not enabled."; | |
| 184 return; | |
| 185 } | |
| 186 // TODO(jri): This currently requires that the generator flush out any | |
| 187 // pending frames when FEC protection is turned on. If current packet can be | |
| 188 // converted to an FEC protected packet, do it. This will require the | |
| 189 // generator to check if the resulting expansion still allows the incoming | |
| 190 // frame to be added to the packet. | |
| 191 if (HasPendingFrames()) { | |
| 192 QUIC_BUG << "Cannot start FEC protection with pending frames."; | |
| 193 return; | |
| 194 } | |
| 195 DCHECK(!fec_protect_); | |
| 196 fec_protect_ = true; | |
| 197 } | |
| 198 | |
| 199 void QuicPacketCreator::StopFecProtectingPackets() { | |
| 200 if (fec_group_.get() != nullptr) { | |
| 201 QUIC_BUG << "Cannot stop FEC protection with open FEC group."; | |
| 202 return; | |
| 203 } | |
| 204 DCHECK(fec_protect_); | |
| 205 fec_protect_ = false; | |
| 206 } | |
| 207 | |
| 208 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { | |
| 209 if (fec_group_.get() != nullptr) { | |
| 210 // Don't update any lengths when an FEC group is open, to ensure same | |
| 211 // packet header size in all packets within a group. | |
| 212 return IN_FEC_GROUP; | |
| 213 } | |
| 214 if (!queued_frames_.empty()) { | |
| 215 // Don't change creator state if there are frames queued. | |
| 216 return NOT_IN_FEC_GROUP; | |
| 217 } | |
| 218 | |
| 219 // Update packet number length only on packet and FEC group boundaries. | |
| 220 packet_.packet_number_length = next_packet_number_length_; | 122 packet_.packet_number_length = next_packet_number_length_; |
| 221 | |
| 222 if (!fec_protect_) { | |
| 223 return NOT_IN_FEC_GROUP; | |
| 224 } | |
| 225 // Start a new FEC group since protection is on. Set the fec group number to | |
| 226 // the packet number of the next packet. | |
| 227 fec_group_.reset(new QuicFecGroup(packet_.packet_number + 1)); | |
| 228 return IN_FEC_GROUP; | |
| 229 } | 123 } |
| 230 | 124 |
| 231 // Stops serializing version of the protocol in packets sent after this call. | 125 // Stops serializing version of the protocol in packets sent after this call. |
| 232 // A packet that is already open might send kQuicVersionSize bytes less than the | 126 // A packet that is already open might send kQuicVersionSize bytes less than the |
| 233 // maximum packet size if we stop sending version before it is serialized. | 127 // maximum packet size if we stop sending version before it is serialized. |
| 234 void QuicPacketCreator::StopSendingVersion() { | 128 void QuicPacketCreator::StopSendingVersion() { |
| 235 DCHECK(send_version_in_packet_); | 129 DCHECK(send_version_in_packet_); |
| 236 send_version_in_packet_ = false; | 130 send_version_in_packet_ = false; |
| 237 if (packet_size_ > 0) { | 131 if (packet_size_ > 0) { |
| 238 DCHECK_LT(kQuicVersionSize, packet_size_); | 132 DCHECK_LT(kQuicVersionSize, packet_size_); |
| 239 packet_size_ -= kQuicVersionSize; | 133 packet_size_ -= kQuicVersionSize; |
| 240 } | 134 } |
| 241 } | 135 } |
| 242 | 136 |
| 243 void QuicPacketCreator::UpdatePacketNumberLength( | 137 void QuicPacketCreator::UpdatePacketNumberLength( |
| 244 QuicPacketNumber least_packet_awaited_by_peer, | 138 QuicPacketNumber least_packet_awaited_by_peer, |
| 245 QuicPacketCount max_packets_in_flight) { | 139 QuicPacketCount max_packets_in_flight) { |
| 246 DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1); | 140 DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1); |
| 247 // Since the packet creator will not change packet number length mid FEC | 141 const QuicPacketNumber current_delta = |
| 248 // group, include the size of an FEC group to be safe. | 142 packet_.packet_number + 1 - least_packet_awaited_by_peer; |
| 249 const QuicPacketNumber current_delta = max_packets_per_fec_group_ + | |
| 250 packet_.packet_number + 1 - | |
| 251 least_packet_awaited_by_peer; | |
| 252 const uint64_t delta = max(current_delta, max_packets_in_flight); | 143 const uint64_t delta = max(current_delta, max_packets_in_flight); |
| 253 next_packet_number_length_ = | 144 next_packet_number_length_ = |
| 254 QuicFramer::GetMinSequenceNumberLength(delta * 4); | 145 QuicFramer::GetMinSequenceNumberLength(delta * 4); |
| 255 } | 146 } |
| 256 | 147 |
| 257 bool QuicPacketCreator::ConsumeData(QuicStreamId id, | 148 bool QuicPacketCreator::ConsumeData(QuicStreamId id, |
| 258 QuicIOVector iov, | 149 QuicIOVector iov, |
| 259 size_t iov_offset, | 150 size_t iov_offset, |
| 260 QuicStreamOffset offset, | 151 QuicStreamOffset offset, |
| 261 bool fin, | 152 bool fin, |
| 262 bool needs_padding, | 153 bool needs_padding, |
| 263 QuicFrame* frame, | 154 QuicFrame* frame) { |
| 264 FecProtection fec_protection) { | |
| 265 if (!HasRoomForStreamFrame(id, offset)) { | 155 if (!HasRoomForStreamFrame(id, offset)) { |
| 266 return false; | 156 return false; |
| 267 } | 157 } |
| 268 if (fec_protection == MUST_FEC_PROTECT) { | |
| 269 should_fec_protect_next_packet_ = true; | |
| 270 MaybeStartFecProtection(); | |
| 271 } | |
| 272 CreateStreamFrame(id, iov, iov_offset, offset, fin, frame); | 158 CreateStreamFrame(id, iov, iov_offset, offset, fin, frame); |
| 273 if (!AddFrame(*frame, /*save_retransmittable_frames=*/true)) { | 159 if (!AddFrame(*frame, /*save_retransmittable_frames=*/true)) { |
| 274 // Fails if we try to write unencrypted stream data. | 160 // Fails if we try to write unencrypted stream data. |
| 275 delete frame->stream_frame; | 161 delete frame->stream_frame; |
| 276 return false; | 162 return false; |
| 277 } | 163 } |
| 278 if (needs_padding) { | 164 if (needs_padding) { |
| 279 packet_.needs_padding = true; | 165 packet_.needs_padding = true; |
| 280 } | 166 } |
| 281 if (fec_protection == MUST_FEC_PROTECT && | |
| 282 iov_offset + frame->stream_frame->frame_length == iov.total_length) { | |
| 283 // Turn off FEC protection when we're done writing protected data. | |
| 284 DVLOG(1) << "Turning FEC protection OFF"; | |
| 285 should_fec_protect_next_packet_ = false; | |
| 286 } | |
| 287 return true; | 167 return true; |
| 288 } | 168 } |
| 289 | 169 |
| 290 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, | 170 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, |
| 291 QuicStreamOffset offset) { | 171 QuicStreamOffset offset) { |
| 292 // TODO(jri): This is a simple safe decision for now, but make | |
| 293 // is_in_fec_group a parameter. Same as with all public methods in | |
| 294 // QuicPacketCreator. | |
| 295 return BytesFree() > | 172 return BytesFree() > |
| 296 QuicFramer::GetMinStreamFrameSize( | 173 QuicFramer::GetMinStreamFrameSize(id, offset, true, NOT_IN_FEC_GROUP); |
| 297 id, offset, true, fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); | |
| 298 } | 174 } |
| 299 | 175 |
| 300 // static | 176 // static |
| 301 size_t QuicPacketCreator::StreamFramePacketOverhead( | 177 size_t QuicPacketCreator::StreamFramePacketOverhead( |
| 302 QuicConnectionIdLength connection_id_length, | 178 QuicConnectionIdLength connection_id_length, |
| 303 bool include_version, | 179 bool include_version, |
| 304 bool include_path_id, | 180 bool include_path_id, |
| 305 QuicPacketNumberLength packet_number_length, | 181 QuicPacketNumberLength packet_number_length, |
| 306 QuicStreamOffset offset, | 182 QuicStreamOffset offset, |
| 307 InFecGroup is_in_fec_group) { | 183 InFecGroup is_in_fec_group) { |
| 308 return GetPacketHeaderSize(connection_id_length, include_version, | 184 return GetPacketHeaderSize(connection_id_length, include_version, |
| 309 include_path_id, packet_number_length, | 185 include_path_id, packet_number_length, |
| 310 is_in_fec_group) + | 186 is_in_fec_group) + |
| 311 // Assumes this is a stream with a single lone packet. | 187 // Assumes this is a stream with a single lone packet. |
| 312 QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group); | 188 QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group); |
| 313 } | 189 } |
| 314 | 190 |
| 315 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, | 191 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, |
| 316 QuicIOVector iov, | 192 QuicIOVector iov, |
| 317 size_t iov_offset, | 193 size_t iov_offset, |
| 318 QuicStreamOffset offset, | 194 QuicStreamOffset offset, |
| 319 bool fin, | 195 bool fin, |
| 320 QuicFrame* frame) { | 196 QuicFrame* frame) { |
| 321 DCHECK_GT(max_packet_length_, | 197 DCHECK_GT(max_packet_length_, |
| 322 StreamFramePacketOverhead( | 198 StreamFramePacketOverhead( |
| 323 connection_id_length_, kIncludeVersion, kIncludePathId, | 199 connection_id_length_, kIncludeVersion, kIncludePathId, |
| 324 PACKET_6BYTE_PACKET_NUMBER, offset, IN_FEC_GROUP)); | 200 PACKET_6BYTE_PACKET_NUMBER, offset, IN_FEC_GROUP)); |
| 325 | 201 |
| 326 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); | 202 MaybeUpdatePacketNumberLength(); |
| 327 | 203 |
| 328 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) | 204 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) |
| 329 << "No room for Stream frame, BytesFree: " << BytesFree() | 205 << "No room for Stream frame, BytesFree: " << BytesFree() |
| 330 << " MinStreamFrameSize: " | 206 << " MinStreamFrameSize: " |
| 331 << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group); | 207 << QuicFramer::GetMinStreamFrameSize(id, offset, true, NOT_IN_FEC_GROUP); |
| 332 | 208 |
| 333 if (iov_offset == iov.total_length) { | 209 if (iov_offset == iov.total_length) { |
| 334 QUIC_BUG_IF(!fin) << "Creating a stream frame with no data or fin."; | 210 QUIC_BUG_IF(!fin) << "Creating a stream frame with no data or fin."; |
| 335 // Create a new packet for the fin, if necessary. | 211 // Create a new packet for the fin, if necessary. |
| 336 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece())); | 212 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece())); |
| 337 return 0; | 213 return 0; |
| 338 } | 214 } |
| 339 | 215 |
| 340 const size_t data_size = iov.total_length - iov_offset; | 216 const size_t data_size = iov.total_length - iov_offset; |
| 341 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( | 217 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( |
| 342 id, offset, /* last_frame_in_packet= */ true, is_in_fec_group); | 218 id, offset, /* last_frame_in_packet= */ true, NOT_IN_FEC_GROUP); |
| 343 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); | 219 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); |
| 344 | 220 |
| 345 bool set_fin = fin && bytes_consumed == data_size; // Last frame. | 221 bool set_fin = fin && bytes_consumed == data_size; // Last frame. |
| 346 UniqueStreamBuffer buffer = | 222 UniqueStreamBuffer buffer = |
| 347 NewStreamBuffer(buffer_allocator_, bytes_consumed); | 223 NewStreamBuffer(buffer_allocator_, bytes_consumed); |
| 348 CopyToBuffer(iov, iov_offset, bytes_consumed, buffer.get()); | 224 CopyToBuffer(iov, iov_offset, bytes_consumed, buffer.get()); |
| 349 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, bytes_consumed, | 225 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, bytes_consumed, |
| 350 std::move(buffer))); | 226 std::move(buffer))); |
| 351 return bytes_consumed; | 227 return bytes_consumed; |
| 352 } | 228 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 copy_len = min(length, iov.iov[iovnum].iov_len); | 278 copy_len = min(length, iov.iov[iovnum].iov_len); |
| 403 } | 279 } |
| 404 QUIC_BUG_IF(length > 0) << "Failed to copy entire length to buffer."; | 280 QUIC_BUG_IF(length > 0) << "Failed to copy entire length to buffer."; |
| 405 } | 281 } |
| 406 | 282 |
| 407 void QuicPacketCreator::ReserializeAllFrames( | 283 void QuicPacketCreator::ReserializeAllFrames( |
| 408 const PendingRetransmission& retransmission, | 284 const PendingRetransmission& retransmission, |
| 409 char* buffer, | 285 char* buffer, |
| 410 size_t buffer_len) { | 286 size_t buffer_len) { |
| 411 DCHECK(queued_frames_.empty()); | 287 DCHECK(queued_frames_.empty()); |
| 412 DCHECK(fec_group_.get() == nullptr); | |
| 413 DCHECK(!packet_.needs_padding); | 288 DCHECK(!packet_.needs_padding); |
| 414 QUIC_BUG_IF(retransmission.retransmittable_frames.empty()) | 289 QUIC_BUG_IF(retransmission.retransmittable_frames.empty()) |
| 415 << "Attempt to serialize empty packet"; | 290 << "Attempt to serialize empty packet"; |
| 416 const QuicPacketNumberLength saved_length = packet_.packet_number_length; | 291 const QuicPacketNumberLength saved_length = packet_.packet_number_length; |
| 417 const QuicPacketNumberLength saved_next_length = next_packet_number_length_; | 292 const QuicPacketNumberLength saved_next_length = next_packet_number_length_; |
| 418 const bool saved_should_fec_protect = fec_protect_; | |
| 419 const EncryptionLevel default_encryption_level = packet_.encryption_level; | 293 const EncryptionLevel default_encryption_level = packet_.encryption_level; |
| 420 | 294 |
| 421 // Temporarily set the packet number length, stop FEC protection, | 295 // Temporarily set the packet number length, stop FEC protection, |
| 422 // and change the encryption level. | 296 // and change the encryption level. |
| 423 packet_.packet_number_length = retransmission.packet_number_length; | 297 packet_.packet_number_length = retransmission.packet_number_length; |
| 424 next_packet_number_length_ = retransmission.packet_number_length; | 298 next_packet_number_length_ = retransmission.packet_number_length; |
| 425 fec_protect_ = false; | |
| 426 packet_.needs_padding = retransmission.needs_padding; | 299 packet_.needs_padding = retransmission.needs_padding; |
| 427 // Only preserve the original encryption level if it's a handshake packet or | 300 // Only preserve the original encryption level if it's a handshake packet or |
| 428 // if we haven't gone forward secure. | 301 // if we haven't gone forward secure. |
| 429 if (retransmission.has_crypto_handshake || | 302 if (retransmission.has_crypto_handshake || |
| 430 packet_.encryption_level != ENCRYPTION_FORWARD_SECURE) { | 303 packet_.encryption_level != ENCRYPTION_FORWARD_SECURE) { |
| 431 packet_.encryption_level = retransmission.encryption_level; | 304 packet_.encryption_level = retransmission.encryption_level; |
| 432 } | 305 } |
| 433 | 306 |
| 434 // Serialize the packet and restore the FEC and packet number length state. | 307 // Serialize the packet and restore the FEC and packet number length state. |
| 435 for (const QuicFrame& frame : retransmission.retransmittable_frames) { | 308 for (const QuicFrame& frame : retransmission.retransmittable_frames) { |
| 436 bool success = AddFrame(frame, false); | 309 bool success = AddFrame(frame, false); |
| 437 DCHECK(success); | 310 DCHECK(success); |
| 438 } | 311 } |
| 439 SerializePacket(buffer, buffer_len); | 312 SerializePacket(buffer, buffer_len); |
| 440 packet_.original_packet_number = retransmission.packet_number; | 313 packet_.original_packet_number = retransmission.packet_number; |
| 441 packet_.transmission_type = retransmission.transmission_type; | 314 packet_.transmission_type = retransmission.transmission_type; |
| 442 OnSerializedPacket(); | 315 OnSerializedPacket(); |
| 443 // Restore old values. | 316 // Restore old values. |
| 444 packet_.packet_number_length = saved_length; | 317 packet_.packet_number_length = saved_length; |
| 445 next_packet_number_length_ = saved_next_length; | 318 next_packet_number_length_ = saved_next_length; |
| 446 fec_protect_ = saved_should_fec_protect; | |
| 447 packet_.encryption_level = default_encryption_level; | 319 packet_.encryption_level = default_encryption_level; |
| 448 } | 320 } |
| 449 | 321 |
| 450 void QuicPacketCreator::Flush() { | 322 void QuicPacketCreator::Flush() { |
| 451 if (!HasPendingFrames()) { | 323 if (!HasPendingFrames()) { |
| 452 return; | 324 return; |
| 453 } | 325 } |
| 454 | 326 |
| 455 // TODO(rtenneti): Change the default 64 alignas value (used the default | 327 // TODO(rtenneti): Change the default 64 alignas value (used the default |
| 456 // value from CACHELINE_SIZE). | 328 // value from CACHELINE_SIZE). |
| 457 ALIGNAS(64) char seralized_packet_buffer[kMaxPacketSize]; | 329 ALIGNAS(64) char seralized_packet_buffer[kMaxPacketSize]; |
| 458 SerializePacket(seralized_packet_buffer, kMaxPacketSize); | 330 SerializePacket(seralized_packet_buffer, kMaxPacketSize); |
| 459 OnSerializedPacket(); | 331 OnSerializedPacket(); |
| 460 } | 332 } |
| 461 | 333 |
| 462 void QuicPacketCreator::OnSerializedPacket() { | 334 void QuicPacketCreator::OnSerializedPacket() { |
| 463 if (packet_.encrypted_buffer == nullptr) { | 335 if (packet_.encrypted_buffer == nullptr) { |
| 464 QUIC_BUG << "Failed to SerializePacket. fec_policy:" << fec_send_policy() | 336 QUIC_BUG << "Failed to SerializePacket."; |
| 465 << " should_fec_protect_:" << should_fec_protect_next_packet_; | |
| 466 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, | 337 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, |
| 467 ConnectionCloseSource::FROM_SELF); | 338 ConnectionCloseSource::FROM_SELF); |
| 468 return; | 339 return; |
| 469 } | 340 } |
| 470 | 341 |
| 471 delegate_->OnSerializedPacket(&packet_); | 342 delegate_->OnSerializedPacket(&packet_); |
| 472 ClearPacket(); | 343 ClearPacket(); |
| 473 MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false, | |
| 474 /*is_fec_timeout=*/false); | |
| 475 // Maximum packet size may be only enacted while no packet is currently being | 344 // Maximum packet size may be only enacted while no packet is currently being |
| 476 // constructed, so here we have a good opportunity to actually change it. | 345 // constructed, so here we have a good opportunity to actually change it. |
| 477 if (CanSetMaxPacketLength()) { | 346 if (CanSetMaxPacketLength()) { |
| 478 SetMaxPacketLength(max_packet_length_); | 347 SetMaxPacketLength(max_packet_length_); |
| 479 } | 348 } |
| 480 } | 349 } |
| 481 | 350 |
| 482 void QuicPacketCreator::ClearPacket() { | 351 void QuicPacketCreator::ClearPacket() { |
| 483 packet_.has_ack = false; | 352 packet_.has_ack = false; |
| 484 packet_.has_stop_waiting = false; | 353 packet_.has_stop_waiting = false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 495 | 364 |
| 496 bool QuicPacketCreator::HasPendingFrames() const { | 365 bool QuicPacketCreator::HasPendingFrames() const { |
| 497 return !queued_frames_.empty(); | 366 return !queued_frames_.empty(); |
| 498 } | 367 } |
| 499 | 368 |
| 500 bool QuicPacketCreator::HasPendingRetransmittableFrames() const { | 369 bool QuicPacketCreator::HasPendingRetransmittableFrames() const { |
| 501 return !packet_.retransmittable_frames.empty(); | 370 return !packet_.retransmittable_frames.empty(); |
| 502 } | 371 } |
| 503 | 372 |
| 504 size_t QuicPacketCreator::ExpansionOnNewFrame() const { | 373 size_t QuicPacketCreator::ExpansionOnNewFrame() const { |
| 505 // If packet is FEC protected, there's no expansion. | |
| 506 if (fec_protect_) { | |
| 507 return 0; | |
| 508 } | |
| 509 // If the last frame in the packet is a stream frame, then it will expand to | 374 // If the last frame in the packet is a stream frame, then it will expand to |
| 510 // include the stream_length field when a new frame is added. | 375 // include the stream_length field when a new frame is added. |
| 511 bool has_trailing_stream_frame = | 376 bool has_trailing_stream_frame = |
| 512 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; | 377 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; |
| 513 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; | 378 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; |
| 514 } | 379 } |
| 515 | 380 |
| 516 size_t QuicPacketCreator::BytesFree() { | 381 size_t QuicPacketCreator::BytesFree() { |
| 517 DCHECK_GE(max_plaintext_size_, PacketSize()); | 382 DCHECK_GE(max_plaintext_size_, PacketSize()); |
| 518 return max_plaintext_size_ - | 383 return max_plaintext_size_ - |
| 519 min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame()); | 384 min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame()); |
| 520 } | 385 } |
| 521 | 386 |
| 522 size_t QuicPacketCreator::PacketSize() { | 387 size_t QuicPacketCreator::PacketSize() { |
| 523 if (!queued_frames_.empty()) { | 388 if (!queued_frames_.empty()) { |
| 524 return packet_size_; | 389 return packet_size_; |
| 525 } | 390 } |
| 526 if (fec_group_.get() == nullptr) { | 391 // Update packet number length on packet boundary. |
| 527 // Update packet number length on packet and FEC boundary. | 392 packet_.packet_number_length = next_packet_number_length_; |
| 528 packet_.packet_number_length = next_packet_number_length_; | 393 packet_size_ = GetPacketHeaderSize( |
| 529 } | 394 connection_id_length_, send_version_in_packet_, send_path_id_in_packet_, |
| 530 packet_size_ = | 395 packet_.packet_number_length, NOT_IN_FEC_GROUP); |
| 531 GetPacketHeaderSize(connection_id_length_, send_version_in_packet_, | |
| 532 send_path_id_in_packet_, packet_.packet_number_length, | |
| 533 fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); | |
| 534 return packet_size_; | 396 return packet_size_; |
| 535 } | 397 } |
| 536 | 398 |
| 537 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { | 399 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { |
| 538 return AddFrame(frame, /*save_retransmittable_frames=*/true); | 400 return AddFrame(frame, /*save_retransmittable_frames=*/true); |
| 539 } | 401 } |
| 540 | 402 |
| 541 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame) { | 403 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame) { |
| 542 if (AddFrame(frame, /*save_retransmittable_frames=*/true)) { | 404 if (AddFrame(frame, /*save_retransmittable_frames=*/true)) { |
| 543 packet_.needs_padding = true; | 405 packet_.needs_padding = true; |
| 544 return true; | 406 return true; |
| 545 } | 407 } |
| 546 return false; | 408 return false; |
| 547 } | 409 } |
| 548 | 410 |
| 549 void QuicPacketCreator::AddAckListener(QuicAckListenerInterface* listener, | 411 void QuicPacketCreator::AddAckListener(QuicAckListenerInterface* listener, |
| 550 QuicPacketLength length) { | 412 QuicPacketLength length) { |
| 551 DCHECK(!queued_frames_.empty()); | 413 DCHECK(!queued_frames_.empty()); |
| 552 packet_.listeners.emplace_back(listener, length); | 414 packet_.listeners.emplace_back(listener, length); |
| 553 } | 415 } |
| 554 | 416 |
| 555 void QuicPacketCreator::SerializePacket(char* encrypted_buffer, | 417 void QuicPacketCreator::SerializePacket(char* encrypted_buffer, |
| 556 size_t encrypted_buffer_len) { | 418 size_t encrypted_buffer_len) { |
| 557 DCHECK_LT(0u, encrypted_buffer_len); | 419 DCHECK_LT(0u, encrypted_buffer_len); |
| 558 QUIC_BUG_IF(queued_frames_.empty()) << "Attempt to serialize empty packet"; | 420 QUIC_BUG_IF(queued_frames_.empty()) << "Attempt to serialize empty packet"; |
| 559 if (fec_group_.get() != nullptr) { | |
| 560 DCHECK_GE(packet_.packet_number + 1, fec_group_->FecGroupNumber()); | |
| 561 } | |
| 562 QuicPacketHeader header; | 421 QuicPacketHeader header; |
| 563 // FillPacketHeader increments packet_number_. | 422 // FillPacketHeader increments packet_number_. |
| 564 FillPacketHeader(fec_group_ != nullptr ? fec_group_->FecGroupNumber() : 0, | 423 FillPacketHeader(&header); |
| 565 false, &header); | |
| 566 | 424 |
| 567 MaybeAddPadding(); | 425 MaybeAddPadding(); |
| 568 | 426 |
| 569 DCHECK_GE(max_plaintext_size_, packet_size_); | 427 DCHECK_GE(max_plaintext_size_, packet_size_); |
| 570 // ACK Frames will be truncated due to length only if they're the only frame | 428 // ACK Frames will be truncated due to length only if they're the only frame |
| 571 // in the packet, and if packet_size_ was set to max_plaintext_size_. If | 429 // in the packet, and if packet_size_ was set to max_plaintext_size_. If |
| 572 // truncation due to length occurred, then GetSerializedFrameLength will have | 430 // truncation due to length occurred, then GetSerializedFrameLength will have |
| 573 // returned all bytes free. | 431 // returned all bytes free. |
| 574 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && | 432 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && |
| 575 queued_frames_.size() == 1 && | 433 queued_frames_.size() == 1 && |
| 576 queued_frames_.back().type == ACK_FRAME; | 434 queued_frames_.back().type == ACK_FRAME; |
| 577 // Use the packet_size_ instead of the buffer size to ensure smaller | 435 // Use the packet_size_ instead of the buffer size to ensure smaller |
| 578 // packet sizes are properly used. | 436 // packet sizes are properly used. |
| 579 size_t length = framer_->BuildDataPacket(header, queued_frames_, | 437 size_t length = framer_->BuildDataPacket(header, queued_frames_, |
| 580 encrypted_buffer, packet_size_); | 438 encrypted_buffer, packet_size_); |
| 581 if (length == 0) { | 439 if (length == 0) { |
| 582 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames."; | 440 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames."; |
| 583 return; | 441 return; |
| 584 } | 442 } |
| 585 | 443 |
| 586 // TODO(ianswett) Consider replacing QuicPacket with something else, since | 444 // TODO(ianswett) Consider replacing QuicPacket with something else, since |
| 587 // it's only used to provide convenience methods to FEC and encryption. | 445 // it's only used to provide convenience methods to FEC and encryption. |
| 588 QuicPacket packet( | 446 QuicPacket packet( |
| 589 encrypted_buffer, length, | 447 encrypted_buffer, length, |
| 590 /* owns_buffer */ false, header.public_header.connection_id_length, | 448 /* owns_buffer */ false, header.public_header.connection_id_length, |
| 591 header.public_header.version_flag, header.public_header.multipath_flag, | 449 header.public_header.version_flag, header.public_header.multipath_flag, |
| 592 header.public_header.packet_number_length); | 450 header.public_header.packet_number_length); |
| 593 OnBuiltFecProtectedPayload(header, packet.FecProtectedData()); | |
| 594 | 451 |
| 595 // Because of possible truncation, we can't be confident that our | 452 // Because of possible truncation, we can't be confident that our |
| 596 // packet size calculation worked correctly. | 453 // packet size calculation worked correctly. |
| 597 if (!possibly_truncated_by_length) { | 454 if (!possibly_truncated_by_length) { |
| 598 DCHECK_EQ(packet_size_, length); | 455 DCHECK_EQ(packet_size_, length); |
| 599 } | 456 } |
| 600 // Immediately encrypt the packet, to ensure we don't encrypt the same | 457 // Immediately encrypt the packet, to ensure we don't encrypt the same |
| 601 // packet number multiple times. | 458 // packet number multiple times. |
| 602 size_t encrypted_length = framer_->EncryptPayload( | 459 size_t encrypted_length = framer_->EncryptPayload( |
| 603 packet_.encryption_level, packet_.path_id, packet_.packet_number, packet, | 460 packet_.encryption_level, packet_.path_id, packet_.packet_number, packet, |
| 604 encrypted_buffer, encrypted_buffer_len); | 461 encrypted_buffer, encrypted_buffer_len); |
| 605 if (encrypted_length == 0) { | 462 if (encrypted_length == 0) { |
| 606 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number; | 463 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number; |
| 607 return; | 464 return; |
| 608 } | 465 } |
| 609 | 466 |
| 610 packet_size_ = 0; | 467 packet_size_ = 0; |
| 611 queued_frames_.clear(); | 468 queued_frames_.clear(); |
| 612 packet_.entropy_hash = QuicFramer::GetPacketEntropyHash(header); | 469 packet_.entropy_hash = QuicFramer::GetPacketEntropyHash(header); |
| 613 packet_.encrypted_buffer = encrypted_buffer; | 470 packet_.encrypted_buffer = encrypted_buffer; |
| 614 packet_.encrypted_length = encrypted_length; | 471 packet_.encrypted_length = encrypted_length; |
| 615 } | 472 } |
| 616 | 473 |
| 617 void QuicPacketCreator::SerializeFec(char* buffer, size_t buffer_len) { | |
| 618 DCHECK_LT(0u, buffer_len); | |
| 619 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { | |
| 620 QUIC_BUG << "SerializeFEC called but no group or zero packets in group."; | |
| 621 return; | |
| 622 } | |
| 623 if (FLAGS_quic_no_unencrypted_fec && | |
| 624 packet_.encryption_level == ENCRYPTION_NONE) { | |
| 625 QUIC_BUG << "SerializeFEC must be called with encryption."; | |
| 626 delegate_->OnUnrecoverableError(QUIC_UNENCRYPTED_FEC_DATA, | |
| 627 ConnectionCloseSource::FROM_SELF); | |
| 628 return; | |
| 629 } | |
| 630 DCHECK_EQ(0u, queued_frames_.size()); | |
| 631 QuicPacketHeader header; | |
| 632 FillPacketHeader(fec_group_->FecGroupNumber(), true, &header); | |
| 633 scoped_ptr<QuicPacket> packet( | |
| 634 framer_->BuildFecPacket(header, fec_group_->PayloadParity())); | |
| 635 fec_group_.reset(nullptr); | |
| 636 packet_size_ = 0; | |
| 637 QUIC_BUG_IF(packet == nullptr) << "Failed to serialize fec packet for group:" | |
| 638 << fec_group_->FecGroupNumber(); | |
| 639 DCHECK_GE(max_packet_length_, packet->length()); | |
| 640 // Immediately encrypt the packet, to ensure we don't encrypt the same packet | |
| 641 // packet number multiple times. | |
| 642 size_t encrypted_length = framer_->EncryptPayload( | |
| 643 packet_.encryption_level, packet_.path_id, packet_.packet_number, *packet, | |
| 644 buffer, buffer_len); | |
| 645 if (encrypted_length == 0) { | |
| 646 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number; | |
| 647 return; | |
| 648 } | |
| 649 packet_.entropy_hash = QuicFramer::GetPacketEntropyHash(header); | |
| 650 packet_.encrypted_buffer = buffer; | |
| 651 packet_.encrypted_length = encrypted_length; | |
| 652 packet_.is_fec_packet = true; | |
| 653 } | |
| 654 | |
| 655 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( | 474 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( |
| 656 const QuicVersionVector& supported_versions) { | 475 const QuicVersionVector& supported_versions) { |
| 657 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); | 476 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); |
| 658 QuicEncryptedPacket* encrypted = QuicFramer::BuildVersionNegotiationPacket( | 477 QuicEncryptedPacket* encrypted = QuicFramer::BuildVersionNegotiationPacket( |
| 659 connection_id_, supported_versions); | 478 connection_id_, supported_versions); |
| 660 DCHECK(encrypted); | 479 DCHECK(encrypted); |
| 661 DCHECK_GE(max_packet_length_, encrypted->length()); | 480 DCHECK_GE(max_packet_length_, encrypted->length()); |
| 662 return encrypted; | 481 return encrypted; |
| 663 } | 482 } |
| 664 | 483 |
| 665 // TODO(jri): Make this a public method of framer? | 484 // TODO(jri): Make this a public method of framer? |
| 666 SerializedPacket QuicPacketCreator::NoPacket() { | 485 SerializedPacket QuicPacketCreator::NoPacket() { |
| 667 return SerializedPacket(kInvalidPathId, 0, PACKET_1BYTE_PACKET_NUMBER, | 486 return SerializedPacket(kInvalidPathId, 0, PACKET_1BYTE_PACKET_NUMBER, |
| 668 nullptr, 0, 0, false, false); | 487 nullptr, 0, 0, false, false); |
| 669 } | 488 } |
| 670 | 489 |
| 671 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, | 490 void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) { |
| 672 bool fec_flag, | |
| 673 QuicPacketHeader* header) { | |
| 674 header->public_header.connection_id = connection_id_; | 491 header->public_header.connection_id = connection_id_; |
| 675 header->public_header.connection_id_length = connection_id_length_; | 492 header->public_header.connection_id_length = connection_id_length_; |
| 676 header->public_header.multipath_flag = send_path_id_in_packet_; | 493 header->public_header.multipath_flag = send_path_id_in_packet_; |
| 677 header->public_header.reset_flag = false; | 494 header->public_header.reset_flag = false; |
| 678 header->public_header.version_flag = send_version_in_packet_; | 495 header->public_header.version_flag = send_version_in_packet_; |
| 679 header->fec_flag = fec_flag; | 496 header->fec_flag = false; |
| 680 header->path_id = packet_.path_id; | 497 header->path_id = packet_.path_id; |
| 681 header->packet_number = ++packet_.packet_number; | 498 header->packet_number = ++packet_.packet_number; |
| 682 header->public_header.packet_number_length = packet_.packet_number_length; | 499 header->public_header.packet_number_length = packet_.packet_number_length; |
| 683 header->entropy_flag = random_bool_source_->RandBool(); | 500 header->entropy_flag = random_bool_source_->RandBool(); |
| 684 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; | 501 header->is_in_fec_group = NOT_IN_FEC_GROUP; |
| 685 header->fec_group = fec_group; | 502 header->fec_group = 0; |
| 686 } | 503 } |
| 687 | 504 |
| 688 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { | 505 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { |
| 689 switch (frame.type) { | 506 switch (frame.type) { |
| 690 case ACK_FRAME: | 507 case ACK_FRAME: |
| 691 case PADDING_FRAME: | 508 case PADDING_FRAME: |
| 692 case STOP_WAITING_FRAME: | 509 case STOP_WAITING_FRAME: |
| 693 case MTU_DISCOVERY_FRAME: | 510 case MTU_DISCOVERY_FRAME: |
| 694 return false; | 511 return false; |
| 695 default: | 512 default: |
| 696 return true; | 513 return true; |
| 697 } | 514 } |
| 698 } | 515 } |
| 699 | 516 |
| 700 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, | 517 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, |
| 701 bool save_retransmittable_frames) { | 518 bool save_retransmittable_frames) { |
| 702 DVLOG(1) << "Adding frame: " << frame; | 519 DVLOG(1) << "Adding frame: " << frame; |
| 703 if (FLAGS_quic_never_write_unencrypted_data && frame.type == STREAM_FRAME && | 520 if (FLAGS_quic_never_write_unencrypted_data && frame.type == STREAM_FRAME && |
| 704 frame.stream_frame->stream_id != kCryptoStreamId && | 521 frame.stream_frame->stream_id != kCryptoStreamId && |
| 705 packet_.encryption_level == ENCRYPTION_NONE) { | 522 packet_.encryption_level == ENCRYPTION_NONE) { |
| 706 QUIC_BUG << "Cannot send stream data without encryption."; | 523 QUIC_BUG << "Cannot send stream data without encryption."; |
| 707 delegate_->OnUnrecoverableError(QUIC_UNENCRYPTED_STREAM_DATA, | 524 delegate_->OnUnrecoverableError(QUIC_UNENCRYPTED_STREAM_DATA, |
| 708 ConnectionCloseSource::FROM_SELF); | 525 ConnectionCloseSource::FROM_SELF); |
| 709 return false; | 526 return false; |
| 710 } | 527 } |
| 711 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); | 528 MaybeUpdatePacketNumberLength(); |
| 712 | 529 |
| 713 size_t frame_len = framer_->GetSerializedFrameLength( | 530 size_t frame_len = framer_->GetSerializedFrameLength( |
| 714 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 531 frame, BytesFree(), queued_frames_.empty(), true, NOT_IN_FEC_GROUP, |
| 715 packet_.packet_number_length); | 532 packet_.packet_number_length); |
| 716 if (frame_len == 0) { | 533 if (frame_len == 0) { |
| 717 // Current open packet is full. | 534 // Current open packet is full. |
| 718 Flush(); | 535 Flush(); |
| 719 return false; | 536 return false; |
| 720 } | 537 } |
| 721 DCHECK_LT(0u, packet_size_); | 538 DCHECK_LT(0u, packet_size_); |
| 722 packet_size_ += ExpansionOnNewFrame() + frame_len; | 539 packet_size_ += ExpansionOnNewFrame() + frame_len; |
| 723 | 540 |
| 724 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | 541 if (save_retransmittable_frames && ShouldRetransmit(frame)) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 755 | 572 |
| 756 if (BytesFree() == 0) { | 573 if (BytesFree() == 0) { |
| 757 // Don't pad full packets. | 574 // Don't pad full packets. |
| 758 return; | 575 return; |
| 759 } | 576 } |
| 760 | 577 |
| 761 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false); | 578 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false); |
| 762 DCHECK(success); | 579 DCHECK(success); |
| 763 } | 580 } |
| 764 | 581 |
| 765 void QuicPacketCreator::MaybeStartFecProtection() { | |
| 766 if (max_packets_per_fec_group_ == 0 || fec_protect_) { | |
| 767 // Do not start FEC protection when FEC protection is not enabled or FEC | |
| 768 // protection is already on. | |
| 769 return; | |
| 770 } | |
| 771 DVLOG(1) << "Turning FEC protection ON"; | |
| 772 // Flush current open packet. | |
| 773 Flush(); | |
| 774 | |
| 775 StartFecProtectingPackets(); | |
| 776 DCHECK(fec_protect_); | |
| 777 } | |
| 778 | |
| 779 void QuicPacketCreator::MaybeSendFecPacketAndCloseGroup(bool force_send_fec, | |
| 780 bool is_fec_timeout) { | |
| 781 if (ShouldSendFec(force_send_fec)) { | |
| 782 if ((FLAGS_quic_no_unencrypted_fec && | |
| 783 packet_.encryption_level == ENCRYPTION_NONE) || | |
| 784 (fec_send_policy_ == FEC_ALARM_TRIGGER && !is_fec_timeout)) { | |
| 785 ResetFecGroup(); | |
| 786 delegate_->OnResetFecGroup(); | |
| 787 } else { | |
| 788 // TODO(zhongyi): Change the default 64 alignas value (used the default | |
| 789 // value from CACHELINE_SIZE). | |
| 790 ALIGNAS(64) char seralized_fec_buffer[kMaxPacketSize]; | |
| 791 SerializeFec(seralized_fec_buffer, kMaxPacketSize); | |
| 792 OnSerializedPacket(); | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 if (!should_fec_protect_next_packet_ && fec_protect_ && !IsFecGroupOpen()) { | |
| 797 StopFecProtectingPackets(); | |
| 798 } | |
| 799 } | |
| 800 | |
| 801 QuicTime::Delta QuicPacketCreator::GetFecTimeout( | |
| 802 QuicPacketNumber packet_number) { | |
| 803 // Do not set up FEC alarm for |packet_number| it is not the first packet in | |
| 804 // the current group. | |
| 805 if (fec_group_.get() != nullptr && | |
| 806 (packet_number == fec_group_->FecGroupNumber())) { | |
| 807 return QuicTime::Delta::Max( | |
| 808 fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs)); | |
| 809 } | |
| 810 return QuicTime::Delta::Infinite(); | |
| 811 } | |
| 812 | |
| 813 void QuicPacketCreator::OnCongestionWindowChange( | |
| 814 QuicPacketCount max_packets_in_flight) { | |
| 815 set_max_packets_per_fec_group(static_cast<size_t>( | |
| 816 kMaxPacketsInFlightMultiplierForFecGroupSize * max_packets_in_flight)); | |
| 817 } | |
| 818 | |
| 819 void QuicPacketCreator::OnRttChange(QuicTime::Delta rtt) { | |
| 820 fec_timeout_ = rtt.Multiply(rtt_multiplier_for_fec_timeout_); | |
| 821 } | |
| 822 | |
| 823 void QuicPacketCreator::SetCurrentPath( | 582 void QuicPacketCreator::SetCurrentPath( |
| 824 QuicPathId path_id, | 583 QuicPathId path_id, |
| 825 QuicPacketNumber least_packet_awaited_by_peer, | 584 QuicPacketNumber least_packet_awaited_by_peer, |
| 826 QuicPacketCount max_packets_in_flight) { | 585 QuicPacketCount max_packets_in_flight) { |
| 827 if (packet_.path_id == path_id) { | 586 if (packet_.path_id == path_id) { |
| 828 return; | 587 return; |
| 829 } | 588 } |
| 830 | 589 |
| 831 if (HasPendingFrames()) { | 590 if (HasPendingFrames()) { |
| 832 QUIC_BUG << "Unable to change paths when a packet is under construction."; | 591 QUIC_BUG << "Unable to change paths when a packet is under construction."; |
| 833 return; | 592 return; |
| 834 } | 593 } |
| 835 | |
| 836 // Send FEC packet and close FEC group. | |
| 837 MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true, | |
| 838 /*is_fec_timeout=*/false); | |
| 839 // Save current packet number and load switching path's packet number. | 594 // Save current packet number and load switching path's packet number. |
| 840 multipath_packet_number_[packet_.path_id] = packet_.packet_number; | 595 multipath_packet_number_[packet_.path_id] = packet_.packet_number; |
| 841 std::unordered_map<QuicPathId, QuicPacketNumber>::iterator it = | 596 std::unordered_map<QuicPathId, QuicPacketNumber>::iterator it = |
| 842 multipath_packet_number_.find(path_id); | 597 multipath_packet_number_.find(path_id); |
| 843 // If path_id is not in the map, it's a new path. Set packet_number to 0. | 598 // If path_id is not in the map, it's a new path. Set packet_number to 0. |
| 844 packet_.packet_number = it == multipath_packet_number_.end() ? 0 : it->second; | 599 packet_.packet_number = it == multipath_packet_number_.end() ? 0 : it->second; |
| 845 packet_.path_id = path_id; | 600 packet_.path_id = path_id; |
| 846 DCHECK(packet_.path_id != kInvalidPathId); | 601 DCHECK(packet_.path_id != kInvalidPathId); |
| 847 // Send path in packet if current path is not the default path. | 602 // Send path in packet if current path is not the default path. |
| 848 send_path_id_in_packet_ = packet_.path_id != kDefaultPathId ? true : false; | 603 send_path_id_in_packet_ = packet_.path_id != kDefaultPathId ? true : false; |
| 849 // Switching path needs to update packet number length. | 604 // Switching path needs to update packet number length. |
| 850 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); | 605 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); |
| 851 } | 606 } |
| 852 | 607 |
| 853 } // namespace net | 608 } // namespace net |
| OLD | NEW |