OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/quic/quic_packet_generator.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/logging.h" | |
9 #include "net/quic/quic_ack_notifier.h" | |
10 #include "net/quic/quic_fec_group.h" | |
11 #include "net/quic/quic_flags.h" | |
12 #include "net/quic/quic_utils.h" | |
13 | |
14 using base::StringPiece; | |
15 | |
16 namespace net { | |
17 | |
18 namespace { | |
19 | |
20 // We want to put some space between a protected packet and the FEC packet to | |
21 // avoid losing them both within the same loss episode. On the other hand, we | |
22 // expect to be able to recover from any loss in about an RTT. We resolve this | |
23 // tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half | |
24 // the max number of in-flight packets, the first protected packet. Since we | |
25 // don't want to delay an FEC packet past half an RTT, we set the max FEC group | |
26 // size to be half the current congestion window. | |
27 const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5; | |
28 const float kRttMultiplierForFecTimeout = 0.5; | |
29 | |
30 // Minimum timeout for FEC alarm, set to half the minimum Tail Loss Probe | |
31 // timeout of 10ms. | |
32 const int64 kMinFecTimeoutMs = 5u; | |
33 | |
34 } // namespace | |
35 | |
36 class QuicAckNotifier; | |
37 | |
38 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, | |
39 QuicFramer* framer, | |
40 QuicRandom* random_generator, | |
41 DelegateInterface* delegate) | |
42 : delegate_(delegate), | |
43 debug_delegate_(nullptr), | |
44 packet_creator_(connection_id, framer, random_generator), | |
45 batch_mode_(false), | |
46 fec_timeout_(QuicTime::Delta::Zero()), | |
47 should_fec_protect_(false), | |
48 should_send_ack_(false), | |
49 should_send_stop_waiting_(false), | |
50 ack_queued_(false), | |
51 stop_waiting_queued_(false) { | |
52 } | |
53 | |
54 QuicPacketGenerator::~QuicPacketGenerator() { | |
55 for (QuicFrames::iterator it = queued_control_frames_.begin(); | |
56 it != queued_control_frames_.end(); ++it) { | |
57 switch (it->type) { | |
58 case PADDING_FRAME: | |
59 delete it->padding_frame; | |
60 break; | |
61 case STREAM_FRAME: | |
62 delete it->stream_frame; | |
63 break; | |
64 case ACK_FRAME: | |
65 delete it->ack_frame; | |
66 break; | |
67 case RST_STREAM_FRAME: | |
68 delete it->rst_stream_frame; | |
69 break; | |
70 case CONNECTION_CLOSE_FRAME: | |
71 delete it->connection_close_frame; | |
72 break; | |
73 case GOAWAY_FRAME: | |
74 delete it->goaway_frame; | |
75 break; | |
76 case WINDOW_UPDATE_FRAME: | |
77 delete it->window_update_frame; | |
78 break; | |
79 case BLOCKED_FRAME: | |
80 delete it->blocked_frame; | |
81 break; | |
82 case STOP_WAITING_FRAME: | |
83 delete it->stop_waiting_frame; | |
84 break; | |
85 case PING_FRAME: | |
86 delete it->ping_frame; | |
87 break; | |
88 case NUM_FRAME_TYPES: | |
89 DCHECK(false) << "Cannot delete type: " << it->type; | |
90 } | |
91 } | |
92 } | |
93 | |
94 void QuicPacketGenerator::OnCongestionWindowChange( | |
95 QuicPacketCount max_packets_in_flight) { | |
96 packet_creator_.set_max_packets_per_fec_group( | |
97 static_cast<size_t>(kMaxPacketsInFlightMultiplierForFecGroupSize * | |
98 max_packets_in_flight)); | |
99 } | |
100 | |
101 void QuicPacketGenerator::OnRttChange(QuicTime::Delta rtt) { | |
102 fec_timeout_ = rtt.Multiply(kRttMultiplierForFecTimeout); | |
103 } | |
104 | |
105 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { | |
106 if (ack_queued_) { | |
107 // Ack already queued, nothing to do. | |
108 return; | |
109 } | |
110 | |
111 if (also_send_stop_waiting && stop_waiting_queued_) { | |
112 LOG(DFATAL) << "Should only ever be one pending stop waiting frame."; | |
113 return; | |
114 } | |
115 | |
116 should_send_ack_ = true; | |
117 should_send_stop_waiting_ = also_send_stop_waiting; | |
118 SendQueuedFrames(false); | |
119 } | |
120 | |
121 void QuicPacketGenerator::SetShouldSendStopWaiting() { | |
122 should_send_stop_waiting_ = true; | |
123 SendQueuedFrames(false); | |
124 } | |
125 | |
126 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { | |
127 queued_control_frames_.push_back(frame); | |
128 SendQueuedFrames(false); | |
129 } | |
130 | |
131 QuicConsumedData QuicPacketGenerator::ConsumeData( | |
132 QuicStreamId id, | |
133 const IOVector& data_to_write, | |
134 QuicStreamOffset offset, | |
135 bool fin, | |
136 FecProtection fec_protection, | |
137 QuicAckNotifier::DelegateInterface* delegate) { | |
138 bool has_handshake = id == kCryptoStreamId; | |
139 // To make reasoning about crypto frames easier, we don't combine them with | |
140 // other retransmittable frames in a single packet. | |
141 const bool flush = | |
142 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); | |
143 SendQueuedFrames(flush); | |
144 | |
145 size_t total_bytes_consumed = 0; | |
146 bool fin_consumed = false; | |
147 | |
148 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { | |
149 SerializeAndSendPacket(); | |
150 } | |
151 | |
152 if (fec_protection == MUST_FEC_PROTECT) { | |
153 MaybeStartFecProtection(); | |
154 } | |
155 | |
156 // This notifier will be owned by the AckNotifierManager (or deleted below) if | |
157 // not attached to a packet. | |
158 QuicAckNotifier* notifier = nullptr; | |
159 if (delegate != nullptr) { | |
160 notifier = new QuicAckNotifier(delegate); | |
161 } | |
162 | |
163 IOVector data = data_to_write; | |
164 size_t data_size = data.TotalBufferSize(); | |
165 if (!fin && (data_size == 0)) { | |
166 LOG(DFATAL) << "Attempt to consume empty data without FIN."; | |
167 return QuicConsumedData(0, false); | |
168 } | |
169 | |
170 int frames_created = 0; | |
171 while (delegate_->ShouldGeneratePacket( | |
172 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, | |
173 has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { | |
174 QuicFrame frame; | |
175 size_t bytes_consumed = packet_creator_.CreateStreamFrame( | |
176 id, data, offset + total_bytes_consumed, fin, &frame); | |
177 ++frames_created; | |
178 | |
179 // We want to track which packet this stream frame ends up in. | |
180 if (FLAGS_quic_attach_ack_notifiers_to_packets) { | |
181 if (notifier != nullptr) { | |
182 ack_notifiers_.push_back(notifier); | |
183 } | |
184 } else { | |
185 frame.stream_frame->notifier = notifier; | |
186 } | |
187 | |
188 if (!AddFrame(frame)) { | |
189 LOG(DFATAL) << "Failed to add stream frame."; | |
190 // Inability to add a STREAM frame creates an unrecoverable hole in a | |
191 // the stream, so it's best to close the connection. | |
192 delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false); | |
193 delete notifier; | |
194 return QuicConsumedData(0, false); | |
195 } | |
196 | |
197 total_bytes_consumed += bytes_consumed; | |
198 fin_consumed = fin && total_bytes_consumed == data_size; | |
199 data.Consume(bytes_consumed); | |
200 DCHECK(data.Empty() || packet_creator_.BytesFree() == 0u); | |
201 | |
202 // TODO(ianswett): Restore packet reordering. | |
203 if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) { | |
204 SerializeAndSendPacket(); | |
205 } | |
206 | |
207 if (data.Empty()) { | |
208 // We're done writing the data. Exit the loop. | |
209 // We don't make this a precondition because we could have 0 bytes of data | |
210 // if we're simply writing a fin. | |
211 if (fec_protection == MUST_FEC_PROTECT) { | |
212 // Turn off FEC protection when we're done writing protected data. | |
213 DVLOG(1) << "Turning FEC protection OFF"; | |
214 should_fec_protect_ = false; | |
215 } | |
216 break; | |
217 } | |
218 } | |
219 | |
220 if (notifier != nullptr && frames_created == 0) { | |
221 // Safe to delete the AckNotifer as it was never attached to a packet. | |
222 delete notifier; | |
223 } | |
224 | |
225 // Don't allow the handshake to be bundled with other retransmittable frames. | |
226 if (has_handshake) { | |
227 SendQueuedFrames(true); | |
228 } | |
229 | |
230 // Try to close FEC group since we've either run out of data to send or we're | |
231 // blocked. If not in batch mode, force close the group. | |
232 MaybeSendFecPacketAndCloseGroup(/*force=*/false); | |
233 | |
234 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); | |
235 return QuicConsumedData(total_bytes_consumed, fin_consumed); | |
236 } | |
237 | |
238 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { | |
239 DCHECK(HasPendingFrames()); | |
240 HasRetransmittableData retransmittable = | |
241 (should_send_ack_ || should_send_stop_waiting_) | |
242 ? NO_RETRANSMITTABLE_DATA | |
243 : HAS_RETRANSMITTABLE_DATA; | |
244 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | |
245 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | |
246 } | |
247 return delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, retransmittable, | |
248 NOT_HANDSHAKE); | |
249 } | |
250 | |
251 void QuicPacketGenerator::SendQueuedFrames(bool flush) { | |
252 // Only add pending frames if we are SURE we can then send the whole packet. | |
253 while (HasPendingFrames() && | |
254 (flush || CanSendWithNextPendingFrameAddition())) { | |
255 if (!AddNextPendingFrame()) { | |
256 // Packet was full, so serialize and send it. | |
257 SerializeAndSendPacket(); | |
258 } | |
259 } | |
260 if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) { | |
261 SerializeAndSendPacket(); | |
262 } | |
263 MaybeSendFecPacketAndCloseGroup(flush); | |
264 } | |
265 | |
266 void QuicPacketGenerator::MaybeStartFecProtection() { | |
267 if (!packet_creator_.IsFecEnabled()) { | |
268 return; | |
269 } | |
270 DVLOG(1) << "Turning FEC protection ON"; | |
271 should_fec_protect_ = true; | |
272 if (packet_creator_.IsFecProtected()) { | |
273 // Only start creator's FEC protection if not already on. | |
274 return; | |
275 } | |
276 if (HasQueuedFrames()) { | |
277 // TODO(jri): This currently requires that the generator flush out any | |
278 // pending frames when FEC protection is turned on. If current packet can be | |
279 // converted to an FEC protected packet, do it. This will require the | |
280 // generator to check if the resulting expansion still allows the incoming | |
281 // frame to be added to the packet. | |
282 SendQueuedFrames(true); | |
283 } | |
284 packet_creator_.StartFecProtectingPackets(); | |
285 DCHECK(packet_creator_.IsFecProtected()); | |
286 } | |
287 | |
288 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) { | |
289 if (!ShouldSendFecPacket(force)) { | |
290 return; | |
291 } | |
292 // TODO(jri): SerializeFec can return a NULL packet, and this should | |
293 // cause an early return, with a call to delegate_->OnPacketGenerationError. | |
294 SerializedPacket serialized_fec = packet_creator_.SerializeFec(); | |
295 DCHECK(serialized_fec.packet); | |
296 delegate_->OnSerializedPacket(serialized_fec); | |
297 // Turn FEC protection off if creator's protection is on and the creator | |
298 // does not have an open FEC group. | |
299 // Note: We only wait until the frames queued in the creator are flushed; | |
300 // pending frames in the generator will not keep us from turning FEC off. | |
301 if (!should_fec_protect_ && !packet_creator_.IsFecGroupOpen()) { | |
302 packet_creator_.StopFecProtectingPackets(); | |
303 DCHECK(!packet_creator_.IsFecProtected()); | |
304 } | |
305 } | |
306 | |
307 bool QuicPacketGenerator::ShouldSendFecPacket(bool force) { | |
308 return packet_creator_.IsFecProtected() && | |
309 !packet_creator_.HasPendingFrames() && | |
310 packet_creator_.ShouldSendFec(force); | |
311 } | |
312 | |
313 void QuicPacketGenerator::OnFecTimeout() { | |
314 DCHECK(!InBatchMode()); | |
315 if (!ShouldSendFecPacket(true)) { | |
316 LOG(DFATAL) << "No FEC packet to send on FEC timeout."; | |
317 return; | |
318 } | |
319 // Flush out any pending frames in the generator and the creator, and then | |
320 // send out FEC packet. | |
321 SendQueuedFrames(true); | |
322 MaybeSendFecPacketAndCloseGroup(/*force=*/true); | |
323 } | |
324 | |
325 QuicTime::Delta QuicPacketGenerator::GetFecTimeout( | |
326 QuicPacketSequenceNumber sequence_number) { | |
327 // Do not set up FEC alarm for |sequence_number| it is not the first packet in | |
328 // the current group. | |
329 if (packet_creator_.IsFecGroupOpen() && | |
330 (sequence_number == packet_creator_.fec_group_number())) { | |
331 return QuicTime::Delta::Max( | |
332 fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs)); | |
333 } | |
334 return QuicTime::Delta::Infinite(); | |
335 } | |
336 | |
337 bool QuicPacketGenerator::InBatchMode() { | |
338 return batch_mode_; | |
339 } | |
340 | |
341 void QuicPacketGenerator::StartBatchOperations() { | |
342 batch_mode_ = true; | |
343 } | |
344 | |
345 void QuicPacketGenerator::FinishBatchOperations() { | |
346 batch_mode_ = false; | |
347 SendQueuedFrames(false); | |
348 } | |
349 | |
350 void QuicPacketGenerator::FlushAllQueuedFrames() { | |
351 SendQueuedFrames(true); | |
352 } | |
353 | |
354 bool QuicPacketGenerator::HasQueuedFrames() const { | |
355 return packet_creator_.HasPendingFrames() || HasPendingFrames(); | |
356 } | |
357 | |
358 bool QuicPacketGenerator::HasPendingFrames() const { | |
359 return should_send_ack_ || should_send_stop_waiting_ || | |
360 !queued_control_frames_.empty(); | |
361 } | |
362 | |
363 bool QuicPacketGenerator::AddNextPendingFrame() { | |
364 if (should_send_ack_) { | |
365 delegate_->PopulateAckFrame(&pending_ack_frame_); | |
366 ack_queued_ = true; | |
367 // If we can't this add the frame now, then we still need to do so later. | |
368 should_send_ack_ = !AddFrame(QuicFrame(&pending_ack_frame_)); | |
369 // Return success if we have cleared out this flag (i.e., added the frame). | |
370 // If we still need to send, then the frame is full, and we have failed. | |
371 return !should_send_ack_; | |
372 } | |
373 | |
374 if (should_send_stop_waiting_) { | |
375 delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_); | |
376 stop_waiting_queued_ = true; | |
377 // If we can't this add the frame now, then we still need to do so later. | |
378 should_send_stop_waiting_ = | |
379 !AddFrame(QuicFrame(&pending_stop_waiting_frame_)); | |
380 // Return success if we have cleared out this flag (i.e., added the frame). | |
381 // If we still need to send, then the frame is full, and we have failed. | |
382 return !should_send_stop_waiting_; | |
383 } | |
384 | |
385 LOG_IF(DFATAL, queued_control_frames_.empty()) | |
386 << "AddNextPendingFrame called with no queued control frames."; | |
387 if (!AddFrame(queued_control_frames_.back())) { | |
388 // Packet was full. | |
389 return false; | |
390 } | |
391 queued_control_frames_.pop_back(); | |
392 return true; | |
393 } | |
394 | |
395 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) { | |
396 bool success = packet_creator_.AddSavedFrame(frame); | |
397 if (success && debug_delegate_) { | |
398 debug_delegate_->OnFrameAddedToPacket(frame); | |
399 } | |
400 return success; | |
401 } | |
402 | |
403 void QuicPacketGenerator::SerializeAndSendPacket() { | |
404 SerializedPacket serialized_packet = packet_creator_.SerializePacket(); | |
405 DCHECK(serialized_packet.packet); | |
406 | |
407 // There may be AckNotifiers interested in this packet. | |
408 if (FLAGS_quic_attach_ack_notifiers_to_packets) { | |
409 serialized_packet.notifiers.swap(ack_notifiers_); | |
410 ack_notifiers_.clear(); | |
411 } | |
412 | |
413 delegate_->OnSerializedPacket(serialized_packet); | |
414 MaybeSendFecPacketAndCloseGroup(/*force=*/false); | |
415 | |
416 // The packet has now been serialized, so the frames are no longer queued. | |
417 ack_queued_ = false; | |
418 stop_waiting_queued_ = false; | |
419 } | |
420 | |
421 void QuicPacketGenerator::StopSendingVersion() { | |
422 packet_creator_.StopSendingVersion(); | |
423 } | |
424 | |
425 QuicPacketSequenceNumber QuicPacketGenerator::sequence_number() const { | |
426 return packet_creator_.sequence_number(); | |
427 } | |
428 | |
429 QuicByteCount QuicPacketGenerator::max_packet_length() const { | |
430 return packet_creator_.max_packet_length(); | |
431 } | |
432 | |
433 void QuicPacketGenerator::set_max_packet_length(QuicByteCount length) { | |
434 packet_creator_.set_max_packet_length(length); | |
435 } | |
436 | |
437 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket( | |
438 const QuicVersionVector& supported_versions) { | |
439 return packet_creator_.SerializeVersionNegotiationPacket(supported_versions); | |
440 } | |
441 | |
442 SerializedPacket QuicPacketGenerator::ReserializeAllFrames( | |
443 const RetransmittableFrames& frames, | |
444 QuicSequenceNumberLength original_length) { | |
445 return packet_creator_.ReserializeAllFrames(frames, original_length); | |
446 } | |
447 | |
448 void QuicPacketGenerator::UpdateSequenceNumberLength( | |
449 QuicPacketSequenceNumber least_packet_awaited_by_peer, | |
450 QuicPacketCount max_packets_in_flight) { | |
451 return packet_creator_.UpdateSequenceNumberLength( | |
452 least_packet_awaited_by_peer, max_packets_in_flight); | |
453 } | |
454 | |
455 void QuicPacketGenerator::SetConnectionIdLength(uint32 length) { | |
456 if (length == 0) { | |
457 packet_creator_.set_connection_id_length(PACKET_0BYTE_CONNECTION_ID); | |
458 } else if (length == 1) { | |
459 packet_creator_.set_connection_id_length(PACKET_1BYTE_CONNECTION_ID); | |
460 } else if (length <= 4) { | |
461 packet_creator_.set_connection_id_length(PACKET_4BYTE_CONNECTION_ID); | |
462 } else { | |
463 packet_creator_.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID); | |
464 } | |
465 } | |
466 | |
467 | |
468 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { | |
469 packet_creator_.set_encryption_level(level); | |
470 } | |
471 | |
472 } // namespace net | |
OLD | NEW |