| 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_generator.h" | 5 #include "net/quic/quic_packet_generator.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "net/quic/quic_bug_tracker.h" | 8 #include "net/quic/quic_bug_tracker.h" |
| 9 #include "net/quic/quic_fec_group.h" | |
| 10 #include "net/quic/quic_flags.h" | 9 #include "net/quic/quic_flags.h" |
| 11 #include "net/quic/quic_utils.h" | 10 #include "net/quic/quic_utils.h" |
| 12 | 11 |
| 13 using base::StringPiece; | 12 using base::StringPiece; |
| 14 | 13 |
| 15 namespace net { | 14 namespace net { |
| 16 | 15 |
| 17 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, | 16 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, |
| 18 QuicFramer* framer, | 17 QuicFramer* framer, |
| 19 QuicRandom* random_generator, | 18 QuicRandom* random_generator, |
| 20 QuicBufferAllocator* buffer_allocator, | 19 QuicBufferAllocator* buffer_allocator, |
| 21 DelegateInterface* delegate) | 20 DelegateInterface* delegate) |
| 22 : delegate_(delegate), | 21 : delegate_(delegate), |
| 23 packet_creator_(connection_id, | 22 packet_creator_(connection_id, |
| 24 framer, | 23 framer, |
| 25 random_generator, | 24 random_generator, |
| 26 buffer_allocator, | 25 buffer_allocator, |
| 27 delegate), | 26 delegate), |
| 28 batch_mode_(false), | 27 batch_mode_(false), |
| 29 should_send_ack_(false), | 28 should_send_ack_(false), |
| 30 should_send_stop_waiting_(false), | 29 should_send_stop_waiting_(false), |
| 31 max_packet_length_(kDefaultMaxPacketSize) {} | 30 max_packet_length_(kDefaultMaxPacketSize) {} |
| 32 | 31 |
| 33 QuicPacketGenerator::~QuicPacketGenerator() { | 32 QuicPacketGenerator::~QuicPacketGenerator() { |
| 34 QuicUtils::DeleteFrames(&queued_control_frames_); | 33 QuicUtils::DeleteFrames(&queued_control_frames_); |
| 35 } | 34 } |
| 36 | 35 |
| 37 void QuicPacketGenerator::OnCongestionWindowChange( | |
| 38 QuicPacketCount max_packets_in_flight) { | |
| 39 packet_creator_.OnCongestionWindowChange(max_packets_in_flight); | |
| 40 } | |
| 41 | |
| 42 void QuicPacketGenerator::OnRttChange(QuicTime::Delta rtt) { | |
| 43 packet_creator_.OnRttChange(rtt); | |
| 44 } | |
| 45 | |
| 46 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { | 36 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { |
| 47 if (packet_creator_.has_ack()) { | 37 if (packet_creator_.has_ack()) { |
| 48 // Ack already queued, nothing to do. | 38 // Ack already queued, nothing to do. |
| 49 return; | 39 return; |
| 50 } | 40 } |
| 51 | 41 |
| 52 if (also_send_stop_waiting && packet_creator_.has_stop_waiting()) { | 42 if (also_send_stop_waiting && packet_creator_.has_stop_waiting()) { |
| 53 QUIC_BUG << "Should only ever be one pending stop waiting frame."; | 43 QUIC_BUG << "Should only ever be one pending stop waiting frame."; |
| 54 return; | 44 return; |
| 55 } | 45 } |
| 56 | 46 |
| 57 should_send_ack_ = true; | 47 should_send_ack_ = true; |
| 58 should_send_stop_waiting_ = also_send_stop_waiting; | 48 should_send_stop_waiting_ = also_send_stop_waiting; |
| 59 SendQueuedFrames(/*flush=*/false, /*is_fec_timeout=*/false); | 49 SendQueuedFrames(/*flush=*/false); |
| 60 } | 50 } |
| 61 | 51 |
| 62 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { | 52 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { |
| 63 queued_control_frames_.push_back(frame); | 53 queued_control_frames_.push_back(frame); |
| 64 SendQueuedFrames(/*flush=*/false, /*is_fec_timeout=*/false); | 54 SendQueuedFrames(/*flush=*/false); |
| 65 } | 55 } |
| 66 | 56 |
| 67 QuicConsumedData QuicPacketGenerator::ConsumeData( | 57 QuicConsumedData QuicPacketGenerator::ConsumeData( |
| 68 QuicStreamId id, | 58 QuicStreamId id, |
| 69 QuicIOVector iov, | 59 QuicIOVector iov, |
| 70 QuicStreamOffset offset, | 60 QuicStreamOffset offset, |
| 71 bool fin, | 61 bool fin, |
| 72 FecProtection fec_protection, | |
| 73 QuicAckListenerInterface* listener) { | 62 QuicAckListenerInterface* listener) { |
| 74 bool has_handshake = id == kCryptoStreamId; | 63 bool has_handshake = id == kCryptoStreamId; |
| 75 // To make reasoning about crypto frames easier, we don't combine them with | 64 // To make reasoning about crypto frames easier, we don't combine them with |
| 76 // other retransmittable frames in a single packet. | 65 // other retransmittable frames in a single packet. |
| 77 const bool flush = | 66 const bool flush = |
| 78 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); | 67 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); |
| 79 SendQueuedFrames(flush, /*is_fec_timeout=*/false); | 68 SendQueuedFrames(flush); |
| 80 | 69 |
| 81 size_t total_bytes_consumed = 0; | 70 size_t total_bytes_consumed = 0; |
| 82 bool fin_consumed = false; | 71 bool fin_consumed = false; |
| 83 | 72 |
| 84 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { | 73 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { |
| 85 packet_creator_.Flush(); | 74 packet_creator_.Flush(); |
| 86 } | 75 } |
| 87 | 76 |
| 88 if (!fin && (iov.total_length == 0)) { | 77 if (!fin && (iov.total_length == 0)) { |
| 89 QUIC_BUG << "Attempt to consume empty data without FIN."; | 78 QUIC_BUG << "Attempt to consume empty data without FIN."; |
| 90 return QuicConsumedData(0, false); | 79 return QuicConsumedData(0, false); |
| 91 } | 80 } |
| 92 | 81 |
| 93 while (delegate_->ShouldGeneratePacket( | 82 while (delegate_->ShouldGeneratePacket( |
| 94 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { | 83 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { |
| 95 QuicFrame frame; | 84 QuicFrame frame; |
| 96 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, | 85 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, |
| 97 offset + total_bytes_consumed, fin, | 86 offset + total_bytes_consumed, fin, |
| 98 has_handshake, &frame, fec_protection)) { | 87 has_handshake, &frame)) { |
| 99 // The creator is always flushed if there's not enough room for a new | 88 // The creator is always flushed if there's not enough room for a new |
| 100 // stream frame before ConsumeData, so ConsumeData should always succeed. | 89 // stream frame before ConsumeData, so ConsumeData should always succeed. |
| 101 QUIC_BUG << "Failed to ConsumeData, stream:" << id; | 90 QUIC_BUG << "Failed to ConsumeData, stream:" << id; |
| 102 return QuicConsumedData(0, false); | 91 return QuicConsumedData(0, false); |
| 103 } | 92 } |
| 104 | 93 |
| 105 // A stream frame is created and added. | 94 // A stream frame is created and added. |
| 106 size_t bytes_consumed = frame.stream_frame->frame_length; | 95 size_t bytes_consumed = frame.stream_frame->frame_length; |
| 107 if (listener != nullptr) { | 96 if (listener != nullptr) { |
| 108 packet_creator_.AddAckListener(listener, bytes_consumed); | 97 packet_creator_.AddAckListener(listener, bytes_consumed); |
| 109 } | 98 } |
| 110 total_bytes_consumed += bytes_consumed; | 99 total_bytes_consumed += bytes_consumed; |
| 111 fin_consumed = fin && total_bytes_consumed == iov.total_length; | 100 fin_consumed = fin && total_bytes_consumed == iov.total_length; |
| 112 DCHECK(total_bytes_consumed == iov.total_length || | 101 DCHECK(total_bytes_consumed == iov.total_length || |
| 113 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); | 102 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); |
| 114 | 103 |
| 115 if (!InBatchMode()) { | 104 if (!InBatchMode()) { |
| 116 // TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside | |
| 117 // SerializeAndSendPacket() and make it an explicit call here (and | |
| 118 // elsewhere where we call SerializeAndSendPacket?). | |
| 119 packet_creator_.Flush(); | 105 packet_creator_.Flush(); |
| 120 } | 106 } |
| 121 | 107 |
| 122 if (total_bytes_consumed == iov.total_length) { | 108 if (total_bytes_consumed == iov.total_length) { |
| 123 // We're done writing the data. Exit the loop. | 109 // We're done writing the data. Exit the loop. |
| 124 // We don't make this a precondition because we could have 0 bytes of data | 110 // We don't make this a precondition because we could have 0 bytes of data |
| 125 // if we're simply writing a fin. | 111 // if we're simply writing a fin. |
| 126 break; | 112 break; |
| 127 } | 113 } |
| 128 // TODO(ianswett): Move to having the creator flush itself when it's full. | 114 // TODO(ianswett): Move to having the creator flush itself when it's full. |
| 129 packet_creator_.Flush(); | 115 packet_creator_.Flush(); |
| 130 } | 116 } |
| 131 | 117 |
| 132 // Don't allow the handshake to be bundled with other retransmittable frames. | 118 // Don't allow the handshake to be bundled with other retransmittable frames. |
| 133 if (has_handshake) { | 119 if (has_handshake) { |
| 134 SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false); | 120 SendQueuedFrames(/*flush=*/true); |
| 135 } | 121 } |
| 136 | 122 |
| 137 // Try to close FEC group since we've either run out of data to send or we're | |
| 138 // blocked. | |
| 139 packet_creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false, | |
| 140 /*is_fec_timeout=*/false); | |
| 141 | |
| 142 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); | 123 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); |
| 143 return QuicConsumedData(total_bytes_consumed, fin_consumed); | 124 return QuicConsumedData(total_bytes_consumed, fin_consumed); |
| 144 } | 125 } |
| 145 | 126 |
| 146 void QuicPacketGenerator::GenerateMtuDiscoveryPacket( | 127 void QuicPacketGenerator::GenerateMtuDiscoveryPacket( |
| 147 QuicByteCount target_mtu, | 128 QuicByteCount target_mtu, |
| 148 QuicAckListenerInterface* listener) { | 129 QuicAckListenerInterface* listener) { |
| 149 // MTU discovery frames must be sent by themselves. | 130 // MTU discovery frames must be sent by themselves. |
| 150 DCHECK(!InBatchMode() && !packet_creator_.HasPendingFrames()); | 131 DCHECK(!InBatchMode() && !packet_creator_.HasPendingFrames()); |
| 151 const QuicByteCount current_mtu = GetMaxPacketLength(); | 132 const QuicByteCount current_mtu = GetMaxPacketLength(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 175 HasRetransmittableData retransmittable = | 156 HasRetransmittableData retransmittable = |
| 176 (should_send_ack_ || should_send_stop_waiting_) | 157 (should_send_ack_ || should_send_stop_waiting_) |
| 177 ? NO_RETRANSMITTABLE_DATA | 158 ? NO_RETRANSMITTABLE_DATA |
| 178 : HAS_RETRANSMITTABLE_DATA; | 159 : HAS_RETRANSMITTABLE_DATA; |
| 179 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | 160 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { |
| 180 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | 161 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. |
| 181 } | 162 } |
| 182 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); | 163 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); |
| 183 } | 164 } |
| 184 | 165 |
| 185 void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) { | 166 void QuicPacketGenerator::SendQueuedFrames(bool flush) { |
| 186 // Only add pending frames if we are SURE we can then send the whole packet. | 167 // Only add pending frames if we are SURE we can then send the whole packet. |
| 187 while (HasPendingFrames() && | 168 while (HasPendingFrames() && |
| 188 (flush || CanSendWithNextPendingFrameAddition())) { | 169 (flush || CanSendWithNextPendingFrameAddition())) { |
| 189 AddNextPendingFrame(); | 170 AddNextPendingFrame(); |
| 190 } | 171 } |
| 191 if (flush || !InBatchMode()) { | 172 if (flush || !InBatchMode()) { |
| 192 packet_creator_.Flush(); | 173 packet_creator_.Flush(); |
| 193 } | 174 } |
| 194 packet_creator_.MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout); | |
| 195 } | |
| 196 | |
| 197 void QuicPacketGenerator::OnFecTimeout() { | |
| 198 DCHECK(!InBatchMode()); | |
| 199 if (!packet_creator_.ShouldSendFec(true)) { | |
| 200 QUIC_BUG << "No FEC packet to send on FEC timeout."; | |
| 201 return; | |
| 202 } | |
| 203 // Flush out any pending frames in the generator and the creator, and then | |
| 204 // send out FEC packet. | |
| 205 SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/true); | |
| 206 } | |
| 207 | |
| 208 QuicTime::Delta QuicPacketGenerator::GetFecTimeout( | |
| 209 QuicPacketNumber packet_number) { | |
| 210 return packet_creator_.GetFecTimeout(packet_number); | |
| 211 } | 175 } |
| 212 | 176 |
| 213 bool QuicPacketGenerator::InBatchMode() { | 177 bool QuicPacketGenerator::InBatchMode() { |
| 214 return batch_mode_; | 178 return batch_mode_; |
| 215 } | 179 } |
| 216 | 180 |
| 217 void QuicPacketGenerator::StartBatchOperations() { | 181 void QuicPacketGenerator::StartBatchOperations() { |
| 218 batch_mode_ = true; | 182 batch_mode_ = true; |
| 219 } | 183 } |
| 220 | 184 |
| 221 void QuicPacketGenerator::FinishBatchOperations() { | 185 void QuicPacketGenerator::FinishBatchOperations() { |
| 222 batch_mode_ = false; | 186 batch_mode_ = false; |
| 223 SendQueuedFrames(/*flush=*/false, /*is_fec_timeout=*/false); | 187 SendQueuedFrames(/*flush=*/false); |
| 224 } | 188 } |
| 225 | 189 |
| 226 void QuicPacketGenerator::FlushAllQueuedFrames() { | 190 void QuicPacketGenerator::FlushAllQueuedFrames() { |
| 227 SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false); | 191 SendQueuedFrames(/*flush=*/true); |
| 228 } | 192 } |
| 229 | 193 |
| 230 bool QuicPacketGenerator::HasQueuedFrames() const { | 194 bool QuicPacketGenerator::HasQueuedFrames() const { |
| 231 return packet_creator_.HasPendingFrames() || HasPendingFrames(); | 195 return packet_creator_.HasPendingFrames() || HasPendingFrames(); |
| 232 } | 196 } |
| 233 | 197 |
| 234 bool QuicPacketGenerator::HasPendingFrames() const { | 198 bool QuicPacketGenerator::HasPendingFrames() const { |
| 235 return should_send_ack_ || should_send_stop_waiting_ || | 199 return should_send_ack_ || should_send_stop_waiting_ || |
| 236 !queued_control_frames_.empty(); | 200 !queued_control_frames_.empty(); |
| 237 } | 201 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 QuicByteCount QuicPacketGenerator::GetMaxPacketLength() const { | 242 QuicByteCount QuicPacketGenerator::GetMaxPacketLength() const { |
| 279 return max_packet_length_; | 243 return max_packet_length_; |
| 280 } | 244 } |
| 281 | 245 |
| 282 QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const { | 246 QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const { |
| 283 return packet_creator_.max_packet_length(); | 247 return packet_creator_.max_packet_length(); |
| 284 } | 248 } |
| 285 | 249 |
| 286 void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length, bool force) { | 250 void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length, bool force) { |
| 287 // If we cannot immediately set new maximum packet length, and the |force| | 251 // If we cannot immediately set new maximum packet length, and the |force| |
| 288 // flag is set, we have to flush the contents of the queue and close existing | 252 // flag is set, we have to flush the contents of the queue. |
| 289 // FEC group. | |
| 290 if (!packet_creator_.CanSetMaxPacketLength() && force) { | 253 if (!packet_creator_.CanSetMaxPacketLength() && force) { |
| 291 SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false); | 254 SendQueuedFrames(/*flush=*/true); |
| 292 packet_creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true, | |
| 293 /*is_fec_timeout=*/false); | |
| 294 DCHECK(packet_creator_.CanSetMaxPacketLength()); | 255 DCHECK(packet_creator_.CanSetMaxPacketLength()); |
| 295 } | 256 } |
| 296 | 257 |
| 297 max_packet_length_ = length; | 258 max_packet_length_ = length; |
| 298 if (packet_creator_.CanSetMaxPacketLength()) { | 259 if (packet_creator_.CanSetMaxPacketLength()) { |
| 299 packet_creator_.SetMaxPacketLength(length); | 260 packet_creator_.SetMaxPacketLength(length); |
| 300 } | 261 } |
| 301 } | 262 } |
| 302 | 263 |
| 303 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket( | 264 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 } | 302 } |
| 342 | 303 |
| 343 void QuicPacketGenerator::SetCurrentPath( | 304 void QuicPacketGenerator::SetCurrentPath( |
| 344 QuicPathId path_id, | 305 QuicPathId path_id, |
| 345 QuicPacketNumber least_packet_awaited_by_peer, | 306 QuicPacketNumber least_packet_awaited_by_peer, |
| 346 QuicPacketCount max_packets_in_flight) { | 307 QuicPacketCount max_packets_in_flight) { |
| 347 packet_creator_.SetCurrentPath(path_id, least_packet_awaited_by_peer, | 308 packet_creator_.SetCurrentPath(path_id, least_packet_awaited_by_peer, |
| 348 max_packets_in_flight); | 309 max_packets_in_flight); |
| 349 } | 310 } |
| 350 | 311 |
| 351 void QuicPacketGenerator::set_rtt_multiplier_for_fec_timeout( | |
| 352 float rtt_multiplier_for_fec_timeout) { | |
| 353 packet_creator_.set_rtt_multiplier_for_fec_timeout( | |
| 354 rtt_multiplier_for_fec_timeout); | |
| 355 } | |
| 356 | |
| 357 FecSendPolicy QuicPacketGenerator::fec_send_policy() { | |
| 358 return packet_creator_.fec_send_policy(); | |
| 359 } | |
| 360 | |
| 361 void QuicPacketGenerator::set_fec_send_policy(FecSendPolicy fec_send_policy) { | |
| 362 packet_creator_.set_fec_send_policy(fec_send_policy); | |
| 363 } | |
| 364 | |
| 365 } // namespace net | 312 } // namespace net |
| OLD | NEW |