| 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/core/quic_packet_generator.h" | 5 #include "net/quic/core/quic_packet_generator.h" |
| 6 | 6 |
| 7 #include <cstdint> | 7 #include <cstdint> |
| 8 | 8 |
| 9 #include "net/quic/core/crypto/quic_random.h" |
| 9 #include "net/quic/core/quic_utils.h" | 10 #include "net/quic/core/quic_utils.h" |
| 10 #include "net/quic/platform/api/quic_bug_tracker.h" | 11 #include "net/quic/platform/api/quic_bug_tracker.h" |
| 11 #include "net/quic/platform/api/quic_logging.h" | 12 #include "net/quic/platform/api/quic_logging.h" |
| 12 | 13 |
| 13 namespace net { | 14 namespace net { |
| 14 | 15 |
| 15 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, | 16 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, |
| 16 QuicFramer* framer, | 17 QuicFramer* framer, |
| 18 QuicRandom* random_generator, |
| 17 QuicBufferAllocator* buffer_allocator, | 19 QuicBufferAllocator* buffer_allocator, |
| 18 DelegateInterface* delegate) | 20 DelegateInterface* delegate) |
| 19 : delegate_(delegate), | 21 : delegate_(delegate), |
| 20 packet_creator_(connection_id, framer, buffer_allocator, delegate), | 22 packet_creator_(connection_id, framer, buffer_allocator, delegate), |
| 21 batch_mode_(false), | 23 batch_mode_(false), |
| 22 should_send_ack_(false), | 24 should_send_ack_(false), |
| 23 should_send_stop_waiting_(false) {} | 25 should_send_stop_waiting_(false), |
| 26 random_generator_(random_generator) {} |
| 24 | 27 |
| 25 QuicPacketGenerator::~QuicPacketGenerator() { | 28 QuicPacketGenerator::~QuicPacketGenerator() { |
| 26 DeleteFrames(&queued_control_frames_); | 29 DeleteFrames(&queued_control_frames_); |
| 27 } | 30 } |
| 28 | 31 |
| 29 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { | 32 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { |
| 30 if (packet_creator_.has_ack()) { | 33 if (packet_creator_.has_ack()) { |
| 31 // Ack already queued, nothing to do. | 34 // Ack already queued, nothing to do. |
| 32 return; | 35 return; |
| 33 } | 36 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 44 | 47 |
| 45 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { | 48 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { |
| 46 queued_control_frames_.push_back(frame); | 49 queued_control_frames_.push_back(frame); |
| 47 SendQueuedFrames(/*flush=*/false); | 50 SendQueuedFrames(/*flush=*/false); |
| 48 } | 51 } |
| 49 | 52 |
| 50 QuicConsumedData QuicPacketGenerator::ConsumeData( | 53 QuicConsumedData QuicPacketGenerator::ConsumeData( |
| 51 QuicStreamId id, | 54 QuicStreamId id, |
| 52 QuicIOVector iov, | 55 QuicIOVector iov, |
| 53 QuicStreamOffset offset, | 56 QuicStreamOffset offset, |
| 54 bool fin, | 57 StreamSendingState state, |
| 55 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 58 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
| 56 bool has_handshake = (id == kCryptoStreamId); | 59 bool has_handshake = (id == kCryptoStreamId); |
| 60 bool fin = state != NO_FIN; |
| 57 QUIC_BUG_IF(has_handshake && fin) | 61 QUIC_BUG_IF(has_handshake && fin) |
| 58 << "Handshake packets should never send a fin"; | 62 << "Handshake packets should never send a fin"; |
| 59 // To make reasoning about crypto frames easier, we don't combine them with | 63 // To make reasoning about crypto frames easier, we don't combine them with |
| 60 // other retransmittable frames in a single packet. | 64 // other retransmittable frames in a single packet. |
| 61 const bool flush = | 65 const bool flush = |
| 62 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); | 66 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); |
| 63 SendQueuedFrames(flush); | 67 SendQueuedFrames(flush); |
| 64 | 68 |
| 65 size_t total_bytes_consumed = 0; | 69 size_t total_bytes_consumed = 0; |
| 66 bool fin_consumed = false; | 70 bool fin_consumed = false; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 86 return QuicConsumedData(0, false); | 90 return QuicConsumedData(0, false); |
| 87 } | 91 } |
| 88 | 92 |
| 89 // A stream frame is created and added. | 93 // A stream frame is created and added. |
| 90 size_t bytes_consumed = frame.stream_frame->data_length; | 94 size_t bytes_consumed = frame.stream_frame->data_length; |
| 91 if (ack_listener != nullptr) { | 95 if (ack_listener != nullptr) { |
| 92 packet_creator_.AddAckListener(ack_listener, bytes_consumed); | 96 packet_creator_.AddAckListener(ack_listener, bytes_consumed); |
| 93 } | 97 } |
| 94 total_bytes_consumed += bytes_consumed; | 98 total_bytes_consumed += bytes_consumed; |
| 95 fin_consumed = fin && total_bytes_consumed == iov.total_length; | 99 fin_consumed = fin && total_bytes_consumed == iov.total_length; |
| 100 if (fin_consumed && state == FIN_AND_PADDING) { |
| 101 AddRandomPadding(); |
| 102 } |
| 96 DCHECK(total_bytes_consumed == iov.total_length || | 103 DCHECK(total_bytes_consumed == iov.total_length || |
| 97 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); | 104 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); |
| 98 | 105 |
| 99 if (!InBatchMode()) { | 106 if (!InBatchMode()) { |
| 100 packet_creator_.Flush(); | 107 packet_creator_.Flush(); |
| 101 } | 108 } |
| 102 | 109 |
| 103 if (total_bytes_consumed == iov.total_length) { | 110 if (total_bytes_consumed == iov.total_length) { |
| 104 // We're done writing the data. Exit the loop. | 111 // We're done writing the data. Exit the loop. |
| 105 // We don't make this a precondition because we could have 0 bytes of data | 112 // We don't make this a precondition because we could have 0 bytes of data |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 packet_creator_.Flush(); | 174 packet_creator_.Flush(); |
| 168 // The only reason AddFrame can fail is that the packet is too full to fit in | 175 // The only reason AddFrame can fail is that the packet is too full to fit in |
| 169 // a ping. This is not possible for any sane MTU. | 176 // a ping. This is not possible for any sane MTU. |
| 170 DCHECK(success); | 177 DCHECK(success); |
| 171 | 178 |
| 172 // Reset the packet length back. | 179 // Reset the packet length back. |
| 173 SetMaxPacketLength(current_mtu); | 180 SetMaxPacketLength(current_mtu); |
| 174 } | 181 } |
| 175 | 182 |
| 176 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { | 183 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { |
| 177 DCHECK(HasPendingFrames()); | 184 DCHECK(HasPendingFrames() || packet_creator_.pending_padding_bytes() > 0); |
| 178 HasRetransmittableData retransmittable = | 185 HasRetransmittableData retransmittable = |
| 179 (should_send_ack_ || should_send_stop_waiting_) | 186 (should_send_ack_ || should_send_stop_waiting_ || |
| 187 packet_creator_.pending_padding_bytes() > 0) |
| 180 ? NO_RETRANSMITTABLE_DATA | 188 ? NO_RETRANSMITTABLE_DATA |
| 181 : HAS_RETRANSMITTABLE_DATA; | 189 : HAS_RETRANSMITTABLE_DATA; |
| 182 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | 190 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { |
| 183 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | 191 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. |
| 184 } | 192 } |
| 185 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); | 193 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); |
| 186 } | 194 } |
| 187 | 195 |
| 188 void QuicPacketGenerator::SendQueuedFrames(bool flush) { | 196 void QuicPacketGenerator::SendQueuedFrames(bool flush) { |
| 189 // Only add pending frames if we are SURE we can then send the whole packet. | 197 // Only add pending frames if we are SURE we can then send the whole packet. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 215 return batch_mode_; | 223 return batch_mode_; |
| 216 } | 224 } |
| 217 | 225 |
| 218 void QuicPacketGenerator::StartBatchOperations() { | 226 void QuicPacketGenerator::StartBatchOperations() { |
| 219 batch_mode_ = true; | 227 batch_mode_ = true; |
| 220 } | 228 } |
| 221 | 229 |
| 222 void QuicPacketGenerator::FinishBatchOperations() { | 230 void QuicPacketGenerator::FinishBatchOperations() { |
| 223 batch_mode_ = false; | 231 batch_mode_ = false; |
| 224 SendQueuedFrames(/*flush=*/false); | 232 SendQueuedFrames(/*flush=*/false); |
| 233 SendRemainingPendingPadding(); |
| 225 } | 234 } |
| 226 | 235 |
| 227 void QuicPacketGenerator::FlushAllQueuedFrames() { | 236 void QuicPacketGenerator::FlushAllQueuedFrames() { |
| 228 SendQueuedFrames(/*flush=*/true); | 237 SendQueuedFrames(/*flush=*/true); |
| 229 } | 238 } |
| 230 | 239 |
| 231 bool QuicPacketGenerator::HasQueuedFrames() const { | 240 bool QuicPacketGenerator::HasQueuedFrames() const { |
| 232 return packet_creator_.HasPendingFrames() || HasPendingFrames(); | 241 return packet_creator_.HasPendingFrames() || HasPendingFrames(); |
| 233 } | 242 } |
| 234 | 243 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 | 329 |
| 321 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { | 330 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { |
| 322 packet_creator_.set_encryption_level(level); | 331 packet_creator_.set_encryption_level(level); |
| 323 } | 332 } |
| 324 | 333 |
| 325 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, | 334 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, |
| 326 QuicEncrypter* encrypter) { | 335 QuicEncrypter* encrypter) { |
| 327 packet_creator_.SetEncrypter(level, encrypter); | 336 packet_creator_.SetEncrypter(level, encrypter); |
| 328 } | 337 } |
| 329 | 338 |
| 339 void QuicPacketGenerator::AddRandomPadding() { |
| 340 packet_creator_.AddPendingPadding( |
| 341 random_generator_->RandUint64() % kMaxNumRandomPaddingBytes + 1); |
| 342 } |
| 343 |
| 344 void QuicPacketGenerator::SendRemainingPendingPadding() { |
| 345 while (packet_creator_.pending_padding_bytes() > 0 && !HasQueuedFrames() && |
| 346 CanSendWithNextPendingFrameAddition()) { |
| 347 packet_creator_.Flush(); |
| 348 } |
| 349 } |
| 350 |
| 330 } // namespace net | 351 } // namespace net |
| OLD | NEW |