Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / net / quic / quic_packet_generator.cc
blob21ab10c9e716bd2d12edff464bdb38a8c63320ff
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;
14 namespace net {
16 namespace {
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;
27 } // namespace
29 class QuicAckNotifier;
31 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
32 QuicFramer* framer,
33 QuicRandom* random_generator,
34 DelegateInterface* delegate)
35 : delegate_(delegate),
36 debug_delegate_(nullptr),
37 packet_creator_(connection_id, framer, random_generator),
38 batch_mode_(false),
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) {
47 switch (it->type) {
48 case PADDING_FRAME:
49 delete it->padding_frame;
50 break;
51 case STREAM_FRAME:
52 delete it->stream_frame;
53 break;
54 case ACK_FRAME:
55 delete it->ack_frame;
56 break;
57 case CONGESTION_FEEDBACK_FRAME:
58 delete it->congestion_feedback_frame;
59 break;
60 case RST_STREAM_FRAME:
61 delete it->rst_stream_frame;
62 break;
63 case CONNECTION_CLOSE_FRAME:
64 delete it->connection_close_frame;
65 break;
66 case GOAWAY_FRAME:
67 delete it->goaway_frame;
68 break;
69 case WINDOW_UPDATE_FRAME:
70 delete it->window_update_frame;
71 break;
72 case BLOCKED_FRAME:
73 delete it->blocked_frame;
74 break;
75 case STOP_WAITING_FRAME:
76 delete it->stop_waiting_frame;
77 break;
78 case PING_FRAME:
79 delete it->ping_frame;
80 break;
81 case NUM_FRAME_TYPES:
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,
115 bool fin,
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)) {
140 QuicFrame frame;
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);
146 } else {
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();
168 if (data.Empty()) {
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;
177 break;
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,
206 NOT_HANDSHAKE);
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()) {
231 return;
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.
237 return;
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)) {
255 return;
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() {
273 return batch_mode_;
276 void QuicPacketGenerator::StartBatchOperations() {
277 batch_mode_ = true;
280 void QuicPacketGenerator::FinishBatchOperations() {
281 batch_mode_ = false;
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())) {
330 // Packet was full.
331 return false;
333 queued_control_frames_.pop_back();
334 return true;
337 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) {
338 bool success = packet_creator_.AddSavedFrame(frame);
339 if (success && debug_delegate_) {
340 debug_delegate_->OnFrameAddedToPacket(frame);
342 return success;
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) {
387 if (length == 0) {
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);
393 } else {
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);
403 } // namespace net