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.
5 #include "net/quic/quic_packet_generator.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "net/quic/quic_fec_group.h"
10 #include "net/quic/quic_utils.h"
12 using base::StringPiece
;
18 // We want to put some space between a protected packet and the FEC packet to
19 // avoid losing them both within the same loss episode. On the other hand,
20 // we expect to be able to recover from any loss in about an RTT.
21 // We resolve this tradeoff by sending an FEC packet atmost half an RTT,
22 // or equivalently, half the max number of in-flight packets, the first
23 // protected packet. Since we don't want to delay an FEC packet past half an
24 // RTT, we set the max FEC group size to be half the current congestion window.
25 const float kMaxPacketsInFlightMultiplierForFecGroupSize
= 0.5;
29 class QuicAckNotifier
;
31 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id
,
33 QuicRandom
* random_generator
,
34 DelegateInterface
* delegate
)
35 : delegate_(delegate
),
36 debug_delegate_(nullptr),
37 packet_creator_(connection_id
, framer
, random_generator
),
39 should_fec_protect_(false),
40 should_send_ack_(false),
41 should_send_feedback_(false),
42 should_send_stop_waiting_(false) {}
44 QuicPacketGenerator::~QuicPacketGenerator() {
45 for (QuicFrames::iterator it
= queued_control_frames_
.begin();
46 it
!= queued_control_frames_
.end(); ++it
) {
49 delete it
->padding_frame
;
52 delete it
->stream_frame
;
57 case CONGESTION_FEEDBACK_FRAME
:
58 delete it
->congestion_feedback_frame
;
60 case RST_STREAM_FRAME
:
61 delete it
->rst_stream_frame
;
63 case CONNECTION_CLOSE_FRAME
:
64 delete it
->connection_close_frame
;
67 delete it
->goaway_frame
;
69 case WINDOW_UPDATE_FRAME
:
70 delete it
->window_update_frame
;
73 delete it
->blocked_frame
;
75 case STOP_WAITING_FRAME
:
76 delete it
->stop_waiting_frame
;
79 delete it
->ping_frame
;
82 DCHECK(false) << "Cannot delete type: " << it
->type
;
87 void QuicPacketGenerator::OnCongestionWindowChange(
88 QuicPacketCount max_packets_in_flight
) {
89 packet_creator_
.set_max_packets_per_fec_group(
90 static_cast<size_t>(kMaxPacketsInFlightMultiplierForFecGroupSize
*
91 max_packets_in_flight
));
94 void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback
,
95 bool also_send_stop_waiting
) {
96 should_send_ack_
= true;
97 should_send_feedback_
= also_send_feedback
;
98 should_send_stop_waiting_
= also_send_stop_waiting
;
99 SendQueuedFrames(false);
102 void QuicPacketGenerator::SetShouldSendStopWaiting() {
103 should_send_stop_waiting_
= true;
104 SendQueuedFrames(false);
107 void QuicPacketGenerator::AddControlFrame(const QuicFrame
& frame
) {
108 queued_control_frames_
.push_back(frame
);
109 SendQueuedFrames(false);
112 QuicConsumedData
QuicPacketGenerator::ConsumeData(QuicStreamId id
,
113 const IOVector
& data_to_write
,
114 QuicStreamOffset offset
,
116 FecProtection fec_protection
,
117 QuicAckNotifier
* notifier
) {
118 IsHandshake handshake
= id
== kCryptoStreamId
? IS_HANDSHAKE
: NOT_HANDSHAKE
;
119 // To make reasoning about crypto frames easier, we don't combine them with
120 // other retransmittable frames in a single packet.
121 const bool flush
= handshake
== IS_HANDSHAKE
&&
122 packet_creator_
.HasPendingRetransmittableFrames();
123 SendQueuedFrames(flush
);
125 size_t total_bytes_consumed
= 0;
126 bool fin_consumed
= false;
128 if (!packet_creator_
.HasRoomForStreamFrame(id
, offset
)) {
129 SerializeAndSendPacket();
132 if (fec_protection
== MUST_FEC_PROTECT
) {
133 MaybeStartFecProtection();
136 IOVector data
= data_to_write
;
137 size_t data_size
= data
.TotalBufferSize();
138 while (delegate_
->ShouldGeneratePacket(NOT_RETRANSMISSION
,
139 HAS_RETRANSMITTABLE_DATA
, handshake
)) {
141 size_t bytes_consumed
;
142 if (notifier
!= nullptr) {
143 // We want to track which packet this stream frame ends up in.
144 bytes_consumed
= packet_creator_
.CreateStreamFrameWithNotifier(
145 id
, data
, offset
+ total_bytes_consumed
, fin
, notifier
, &frame
);
147 bytes_consumed
= packet_creator_
.CreateStreamFrame(
148 id
, data
, offset
+ total_bytes_consumed
, fin
, &frame
);
150 if (!AddFrame(frame
)) {
151 LOG(DFATAL
) << "Failed to add stream frame.";
152 // Inability to add a STREAM frame creates an unrecoverable hole in a
153 // the stream, so it's best to close the connection.
154 delegate_
->CloseConnection(QUIC_INTERNAL_ERROR
, false);
155 return QuicConsumedData(0, false);
158 total_bytes_consumed
+= bytes_consumed
;
159 fin_consumed
= fin
&& total_bytes_consumed
== data_size
;
160 data
.Consume(bytes_consumed
);
161 DCHECK(data
.Empty() || packet_creator_
.BytesFree() == 0u);
163 // TODO(ianswett): Restore packet reordering.
164 if (!InBatchMode() || !packet_creator_
.HasRoomForStreamFrame(id
, offset
)) {
165 SerializeAndSendPacket();
169 // We're done writing the data. Exit the loop.
170 // We don't make this a precondition because we could have 0 bytes of data
171 // if we're simply writing a fin.
172 if (fec_protection
== MUST_FEC_PROTECT
) {
173 // Turn off FEC protection when we're done writing protected data.
174 DVLOG(1) << "Turning FEC protection OFF";
175 should_fec_protect_
= false;
181 // Don't allow the handshake to be bundled with other retransmittable frames.
182 if (handshake
== IS_HANDSHAKE
) {
183 SendQueuedFrames(true);
186 // Try to close FEC group since we've either run out of data to send or we're
187 // blocked. If not in batch mode, force close the group.
188 // TODO(jri): This method should be called with flush=false here
189 // once the timer-based FEC sending is done, to separate FEC sending from
190 // the end of batch operations.
191 MaybeSendFecPacketAndCloseGroup(!InBatchMode());
193 DCHECK(InBatchMode() || !packet_creator_
.HasPendingFrames());
194 return QuicConsumedData(total_bytes_consumed
, fin_consumed
);
197 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
198 DCHECK(HasPendingFrames());
199 HasRetransmittableData retransmittable
=
200 (should_send_ack_
|| should_send_feedback_
|| should_send_stop_waiting_
)
201 ? NO_RETRANSMITTABLE_DATA
: HAS_RETRANSMITTABLE_DATA
;
202 if (retransmittable
== HAS_RETRANSMITTABLE_DATA
) {
203 DCHECK(!queued_control_frames_
.empty()); // These are retransmittable.
205 return delegate_
->ShouldGeneratePacket(NOT_RETRANSMISSION
, retransmittable
,
209 void QuicPacketGenerator::SendQueuedFrames(bool flush
) {
210 // Only add pending frames if we are SURE we can then send the whole packet.
211 while (HasPendingFrames() &&
212 (flush
|| CanSendWithNextPendingFrameAddition())) {
213 if (!AddNextPendingFrame()) {
214 // Packet was full, so serialize and send it.
215 SerializeAndSendPacket();
219 if (!InBatchMode() || flush
) {
220 if (packet_creator_
.HasPendingFrames()) {
221 SerializeAndSendPacket();
223 // Ensure the FEC group is closed at the end of this method unless other
224 // writes are pending.
225 MaybeSendFecPacketAndCloseGroup(true);
229 void QuicPacketGenerator::MaybeStartFecProtection() {
230 if (!packet_creator_
.IsFecEnabled()) {
233 DVLOG(1) << "Turning FEC protection ON";
234 should_fec_protect_
= true;
235 if (packet_creator_
.IsFecProtected()) {
236 // Only start creator's FEC protection if not already on.
239 if (HasQueuedFrames()) {
240 // TODO(jri): This currently requires that the generator flush out any
241 // pending frames when FEC protection is turned on. If current packet can be
242 // converted to an FEC protected packet, do it. This will require the
243 // generator to check if the resulting expansion still allows the incoming
244 // frame to be added to the packet.
245 SendQueuedFrames(true);
247 packet_creator_
.StartFecProtectingPackets();
248 DCHECK(packet_creator_
.IsFecProtected());
251 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force
) {
252 if (!packet_creator_
.IsFecProtected() ||
253 packet_creator_
.HasPendingFrames() ||
254 !packet_creator_
.ShouldSendFec(force
)) {
257 // TODO(jri): SerializeFec can return a NULL packet, and this should
258 // cause an early return, with a call to delegate_->OnPacketGenerationError.
259 SerializedPacket serialized_fec
= packet_creator_
.SerializeFec();
260 DCHECK(serialized_fec
.packet
);
261 delegate_
->OnSerializedPacket(serialized_fec
);
262 // Turn FEC protection off if creator's protection is on and the creator
263 // does not have an open FEC group.
264 // Note: We only wait until the frames queued in the creator are flushed;
265 // pending frames in the generator will not keep us from turning FEC off.
266 if (!should_fec_protect_
&& !packet_creator_
.IsFecGroupOpen()) {
267 packet_creator_
.StopFecProtectingPackets();
268 DCHECK(!packet_creator_
.IsFecProtected());
272 bool QuicPacketGenerator::InBatchMode() {
276 void QuicPacketGenerator::StartBatchOperations() {
280 void QuicPacketGenerator::FinishBatchOperations() {
282 SendQueuedFrames(false);
285 void QuicPacketGenerator::FlushAllQueuedFrames() {
286 SendQueuedFrames(true);
289 bool QuicPacketGenerator::HasQueuedFrames() const {
290 return packet_creator_
.HasPendingFrames() || HasPendingFrames();
293 bool QuicPacketGenerator::HasPendingFrames() const {
294 return should_send_ack_
|| should_send_feedback_
||
295 should_send_stop_waiting_
|| !queued_control_frames_
.empty();
298 bool QuicPacketGenerator::AddNextPendingFrame() {
299 if (should_send_ack_
) {
300 pending_ack_frame_
.reset(delegate_
->CreateAckFrame());
301 // If we can't this add the frame now, then we still need to do so later.
302 should_send_ack_
= !AddFrame(QuicFrame(pending_ack_frame_
.get()));
303 // Return success if we have cleared out this flag (i.e., added the frame).
304 // If we still need to send, then the frame is full, and we have failed.
305 return !should_send_ack_
;
308 if (should_send_feedback_
) {
309 pending_feedback_frame_
.reset(delegate_
->CreateFeedbackFrame());
310 // If we can't this add the frame now, then we still need to do so later.
311 should_send_feedback_
= !AddFrame(QuicFrame(pending_feedback_frame_
.get()));
312 // Return success if we have cleared out this flag (i.e., added the frame).
313 // If we still need to send, then the frame is full, and we have failed.
314 return !should_send_feedback_
;
317 if (should_send_stop_waiting_
) {
318 pending_stop_waiting_frame_
.reset(delegate_
->CreateStopWaitingFrame());
319 // If we can't this add the frame now, then we still need to do so later.
320 should_send_stop_waiting_
=
321 !AddFrame(QuicFrame(pending_stop_waiting_frame_
.get()));
322 // Return success if we have cleared out this flag (i.e., added the frame).
323 // If we still need to send, then the frame is full, and we have failed.
324 return !should_send_stop_waiting_
;
327 LOG_IF(DFATAL
, queued_control_frames_
.empty())
328 << "AddNextPendingFrame called with no queued control frames.";
329 if (!AddFrame(queued_control_frames_
.back())) {
333 queued_control_frames_
.pop_back();
337 bool QuicPacketGenerator::AddFrame(const QuicFrame
& frame
) {
338 bool success
= packet_creator_
.AddSavedFrame(frame
);
339 if (success
&& debug_delegate_
) {
340 debug_delegate_
->OnFrameAddedToPacket(frame
);
345 void QuicPacketGenerator::SerializeAndSendPacket() {
346 SerializedPacket serialized_packet
= packet_creator_
.SerializePacket();
347 DCHECK(serialized_packet
.packet
);
348 delegate_
->OnSerializedPacket(serialized_packet
);
349 MaybeSendFecPacketAndCloseGroup(false);
352 void QuicPacketGenerator::StopSendingVersion() {
353 packet_creator_
.StopSendingVersion();
356 QuicPacketSequenceNumber
QuicPacketGenerator::sequence_number() const {
357 return packet_creator_
.sequence_number();
360 QuicByteCount
QuicPacketGenerator::max_packet_length() const {
361 return packet_creator_
.max_packet_length();
364 void QuicPacketGenerator::set_max_packet_length(QuicByteCount length
) {
365 packet_creator_
.set_max_packet_length(length
);
368 QuicEncryptedPacket
* QuicPacketGenerator::SerializeVersionNegotiationPacket(
369 const QuicVersionVector
& supported_versions
) {
370 return packet_creator_
.SerializeVersionNegotiationPacket(supported_versions
);
373 SerializedPacket
QuicPacketGenerator::ReserializeAllFrames(
374 const QuicFrames
& frames
,
375 QuicSequenceNumberLength original_length
) {
376 return packet_creator_
.ReserializeAllFrames(frames
, original_length
);
379 void QuicPacketGenerator::UpdateSequenceNumberLength(
380 QuicPacketSequenceNumber least_packet_awaited_by_peer
,
381 QuicPacketCount max_packets_in_flight
) {
382 return packet_creator_
.UpdateSequenceNumberLength(
383 least_packet_awaited_by_peer
, max_packets_in_flight
);
386 void QuicPacketGenerator::SetConnectionIdLength(uint32 length
) {
388 packet_creator_
.set_connection_id_length(PACKET_0BYTE_CONNECTION_ID
);
389 } else if (length
== 1) {
390 packet_creator_
.set_connection_id_length(PACKET_1BYTE_CONNECTION_ID
);
391 } else if (length
<= 4) {
392 packet_creator_
.set_connection_id_length(PACKET_4BYTE_CONNECTION_ID
);
394 packet_creator_
.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID
);
399 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level
) {
400 packet_creator_
.set_encryption_level(level
);