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 |