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
;
16 class QuicAckNotifier
;
18 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id
,
20 QuicRandom
* random_generator
,
21 DelegateInterface
* delegate
)
22 : delegate_(delegate
),
23 debug_delegate_(NULL
),
24 packet_creator_(connection_id
, framer
, random_generator
),
26 should_fec_protect_(false),
27 should_send_ack_(false),
28 should_send_feedback_(false),
29 should_send_stop_waiting_(false) {
32 QuicPacketGenerator::~QuicPacketGenerator() {
33 for (QuicFrames::iterator it
= queued_control_frames_
.begin();
34 it
!= queued_control_frames_
.end(); ++it
) {
37 delete it
->padding_frame
;
40 delete it
->stream_frame
;
45 case CONGESTION_FEEDBACK_FRAME
:
46 delete it
->congestion_feedback_frame
;
48 case RST_STREAM_FRAME
:
49 delete it
->rst_stream_frame
;
51 case CONNECTION_CLOSE_FRAME
:
52 delete it
->connection_close_frame
;
55 delete it
->goaway_frame
;
57 case WINDOW_UPDATE_FRAME
:
58 delete it
->window_update_frame
;
61 delete it
->blocked_frame
;
63 case STOP_WAITING_FRAME
:
64 delete it
->stop_waiting_frame
;
67 delete it
->ping_frame
;
70 DCHECK(false) << "Cannot delete type: " << it
->type
;
75 void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback
,
76 bool also_send_stop_waiting
) {
77 should_send_ack_
= true;
78 should_send_feedback_
= also_send_feedback
;
79 should_send_stop_waiting_
= also_send_stop_waiting
;
80 SendQueuedFrames(false);
83 void QuicPacketGenerator::SetShouldSendStopWaiting() {
84 should_send_stop_waiting_
= true;
85 SendQueuedFrames(false);
88 void QuicPacketGenerator::AddControlFrame(const QuicFrame
& frame
) {
89 queued_control_frames_
.push_back(frame
);
90 SendQueuedFrames(false);
93 QuicConsumedData
QuicPacketGenerator::ConsumeData(QuicStreamId id
,
94 const IOVector
& data_to_write
,
95 QuicStreamOffset offset
,
97 FecProtection fec_protection
,
98 QuicAckNotifier
* notifier
) {
99 IsHandshake handshake
= id
== kCryptoStreamId
? IS_HANDSHAKE
: NOT_HANDSHAKE
;
100 // To make reasoning about crypto frames easier, we don't combine them with
101 // other retransmittable frames in a single packet.
102 const bool flush
= handshake
== IS_HANDSHAKE
&&
103 packet_creator_
.HasPendingRetransmittableFrames();
104 SendQueuedFrames(flush
);
106 size_t total_bytes_consumed
= 0;
107 bool fin_consumed
= false;
109 if (!packet_creator_
.HasRoomForStreamFrame(id
, offset
)) {
110 SerializeAndSendPacket();
113 if (fec_protection
== MUST_FEC_PROTECT
) {
114 MaybeStartFecProtection();
117 IOVector data
= data_to_write
;
118 size_t data_size
= data
.TotalBufferSize();
119 while (delegate_
->ShouldGeneratePacket(NOT_RETRANSMISSION
,
120 HAS_RETRANSMITTABLE_DATA
, handshake
)) {
122 size_t bytes_consumed
;
123 if (notifier
!= NULL
) {
124 // We want to track which packet this stream frame ends up in.
125 bytes_consumed
= packet_creator_
.CreateStreamFrameWithNotifier(
126 id
, data
, offset
+ total_bytes_consumed
, fin
, notifier
, &frame
);
128 bytes_consumed
= packet_creator_
.CreateStreamFrame(
129 id
, data
, offset
+ total_bytes_consumed
, fin
, &frame
);
131 if (!AddFrame(frame
)) {
132 LOG(DFATAL
) << "Failed to add stream frame.";
133 // Inability to add a STREAM frame creates an unrecoverable hole in a
134 // the stream, so it's best to close the connection.
135 delegate_
->CloseConnection(QUIC_INTERNAL_ERROR
, false);
136 return QuicConsumedData(0, false);
139 total_bytes_consumed
+= bytes_consumed
;
140 fin_consumed
= fin
&& total_bytes_consumed
== data_size
;
141 data
.Consume(bytes_consumed
);
142 DCHECK(data
.Empty() || packet_creator_
.BytesFree() == 0u);
144 // TODO(ianswett): Restore packet reordering.
145 if (!InBatchMode() || !packet_creator_
.HasRoomForStreamFrame(id
, offset
)) {
146 SerializeAndSendPacket();
150 // We're done writing the data. Exit the loop.
151 // We don't make this a precondition because we could have 0 bytes of data
152 // if we're simply writing a fin.
153 if (fec_protection
== MUST_FEC_PROTECT
) {
154 // Turn off FEC protection when we're done writing protected data.
155 DVLOG(1) << "Turning FEC protection OFF";
156 should_fec_protect_
= false;
162 // Don't allow the handshake to be bundled with other retransmittable frames.
163 if (handshake
== IS_HANDSHAKE
) {
164 SendQueuedFrames(true);
167 // Try to close FEC group since we've either run out of data to send or we're
168 // blocked. If not in batch mode, force close the group.
169 MaybeSendFecPacketAndCloseGroup(!InBatchMode());
171 DCHECK(InBatchMode() || !packet_creator_
.HasPendingFrames());
172 return QuicConsumedData(total_bytes_consumed
, fin_consumed
);
175 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
176 DCHECK(HasPendingFrames());
177 HasRetransmittableData retransmittable
=
178 (should_send_ack_
|| should_send_feedback_
|| should_send_stop_waiting_
)
179 ? NO_RETRANSMITTABLE_DATA
: HAS_RETRANSMITTABLE_DATA
;
180 if (retransmittable
== HAS_RETRANSMITTABLE_DATA
) {
181 DCHECK(!queued_control_frames_
.empty()); // These are retransmittable.
183 return delegate_
->ShouldGeneratePacket(NOT_RETRANSMISSION
, retransmittable
,
187 void QuicPacketGenerator::SendQueuedFrames(bool flush
) {
188 // Only add pending frames if we are SURE we can then send the whole packet.
189 while (HasPendingFrames() &&
190 (flush
|| CanSendWithNextPendingFrameAddition())) {
191 if (!AddNextPendingFrame()) {
192 // Packet was full, so serialize and send it.
193 SerializeAndSendPacket();
197 if (!InBatchMode() || flush
) {
198 if (packet_creator_
.HasPendingFrames()) {
199 SerializeAndSendPacket();
201 // Ensure the FEC group is closed at the end of this method unless other
202 // writes are pending.
203 MaybeSendFecPacketAndCloseGroup(true);
207 void QuicPacketGenerator::MaybeStartFecProtection() {
208 if (!packet_creator_
.IsFecEnabled()) {
211 DVLOG(1) << "Turning FEC protection ON";
212 should_fec_protect_
= true;
213 if (packet_creator_
.IsFecProtected()) {
214 // Only start creator's FEC protection if not already on.
217 if (HasQueuedFrames()) {
218 // TODO(jri): This currently requires that the generator flush out any
219 // pending frames when FEC protection is turned on. If current packet can be
220 // converted to an FEC protected packet, do it. This will require the
221 // generator to check if the resulting expansion still allows the incoming
222 // frame to be added to the packet.
223 SendQueuedFrames(true);
225 packet_creator_
.StartFecProtectingPackets();
226 DCHECK(packet_creator_
.IsFecProtected());
229 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force
) {
230 if (!packet_creator_
.IsFecProtected() ||
231 packet_creator_
.HasPendingFrames()) {
235 if (packet_creator_
.ShouldSendFec(force
)) {
236 // TODO(jri): SerializeFec can return a NULL packet, and this should
237 // cause an early return, with a call to
238 // delegate_->OnPacketGenerationError.
239 SerializedPacket serialized_fec
= packet_creator_
.SerializeFec();
240 DCHECK(serialized_fec
.packet
);
241 delegate_
->OnSerializedPacket(serialized_fec
);
244 // Turn FEC protection off if the creator does not have an FEC group open.
245 // Note: We only wait until the frames queued in the creator are flushed;
246 // pending frames in the generator will not keep us from turning FEC off.
247 if (!should_fec_protect_
&& !packet_creator_
.IsFecGroupOpen()) {
248 packet_creator_
.StopFecProtectingPackets();
249 DCHECK(!packet_creator_
.IsFecProtected());
253 bool QuicPacketGenerator::InBatchMode() {
257 void QuicPacketGenerator::StartBatchOperations() {
261 void QuicPacketGenerator::FinishBatchOperations() {
263 SendQueuedFrames(false);
266 void QuicPacketGenerator::FlushAllQueuedFrames() {
267 SendQueuedFrames(true);
270 bool QuicPacketGenerator::HasQueuedFrames() const {
271 return packet_creator_
.HasPendingFrames() || HasPendingFrames();
274 bool QuicPacketGenerator::HasPendingFrames() const {
275 return should_send_ack_
|| should_send_feedback_
||
276 should_send_stop_waiting_
|| !queued_control_frames_
.empty();
279 bool QuicPacketGenerator::AddNextPendingFrame() {
280 if (should_send_ack_
) {
281 pending_ack_frame_
.reset(delegate_
->CreateAckFrame());
282 // If we can't this add the frame now, then we still need to do so later.
283 should_send_ack_
= !AddFrame(QuicFrame(pending_ack_frame_
.get()));
284 // Return success if we have cleared out this flag (i.e., added the frame).
285 // If we still need to send, then the frame is full, and we have failed.
286 return !should_send_ack_
;
289 if (should_send_feedback_
) {
290 pending_feedback_frame_
.reset(delegate_
->CreateFeedbackFrame());
291 // If we can't this add the frame now, then we still need to do so later.
292 should_send_feedback_
= !AddFrame(QuicFrame(pending_feedback_frame_
.get()));
293 // Return success if we have cleared out this flag (i.e., added the frame).
294 // If we still need to send, then the frame is full, and we have failed.
295 return !should_send_feedback_
;
298 if (should_send_stop_waiting_
) {
299 pending_stop_waiting_frame_
.reset(delegate_
->CreateStopWaitingFrame());
300 // If we can't this add the frame now, then we still need to do so later.
301 should_send_stop_waiting_
=
302 !AddFrame(QuicFrame(pending_stop_waiting_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_stop_waiting_
;
308 LOG_IF(DFATAL
, queued_control_frames_
.empty())
309 << "AddNextPendingFrame called with no queued control frames.";
310 if (!AddFrame(queued_control_frames_
.back())) {
314 queued_control_frames_
.pop_back();
318 bool QuicPacketGenerator::AddFrame(const QuicFrame
& frame
) {
319 bool success
= packet_creator_
.AddSavedFrame(frame
);
320 if (success
&& debug_delegate_
) {
321 debug_delegate_
->OnFrameAddedToPacket(frame
);
326 void QuicPacketGenerator::SerializeAndSendPacket() {
327 SerializedPacket serialized_packet
= packet_creator_
.SerializePacket();
328 DCHECK(serialized_packet
.packet
);
329 delegate_
->OnSerializedPacket(serialized_packet
);
330 MaybeSendFecPacketAndCloseGroup(false);
333 void QuicPacketGenerator::StopSendingVersion() {
334 packet_creator_
.StopSendingVersion();
337 QuicPacketSequenceNumber
QuicPacketGenerator::sequence_number() const {
338 return packet_creator_
.sequence_number();
341 size_t QuicPacketGenerator::max_packet_length() const {
342 return packet_creator_
.max_packet_length();
345 void QuicPacketGenerator::set_max_packet_length(size_t length
) {
346 packet_creator_
.set_max_packet_length(length
);
349 QuicEncryptedPacket
* QuicPacketGenerator::SerializeVersionNegotiationPacket(
350 const QuicVersionVector
& supported_versions
) {
351 return packet_creator_
.SerializeVersionNegotiationPacket(supported_versions
);
354 SerializedPacket
QuicPacketGenerator::ReserializeAllFrames(
355 const QuicFrames
& frames
,
356 QuicSequenceNumberLength original_length
) {
357 return packet_creator_
.ReserializeAllFrames(frames
, original_length
);
360 void QuicPacketGenerator::UpdateSequenceNumberLength(
361 QuicPacketSequenceNumber least_packet_awaited_by_peer
,
362 QuicByteCount congestion_window
) {
363 return packet_creator_
.UpdateSequenceNumberLength(
364 least_packet_awaited_by_peer
, congestion_window
);
367 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level
) {
368 packet_creator_
.set_encryption_level(level
);