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 |