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_fec_group.h"
10#include "net/quic/quic_utils.h"
11
12using base::StringPiece;
13
14namespace net {
15
16namespace {
17
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 a cwnd, after the first protected packet. Since we
23// don't want to delay an FEC packet past half an RTT, we set the max FEC
24// group size to be half the current congestion window.
25const float kCongestionWindowMultiplierForFecGroupSize = 0.5;
26
27}  // namespace
28
29class QuicAckNotifier;
30
31QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
32                                         QuicFramer* framer,
33                                         QuicRandom* random_generator,
34                                         DelegateInterface* delegate)
35    : delegate_(delegate),
36      debug_delegate_(NULL),
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) {
43}
44
45QuicPacketGenerator::~QuicPacketGenerator() {
46  for (QuicFrames::iterator it = queued_control_frames_.begin();
47       it != queued_control_frames_.end(); ++it) {
48    switch (it->type) {
49      case PADDING_FRAME:
50        delete it->padding_frame;
51        break;
52      case STREAM_FRAME:
53        delete it->stream_frame;
54        break;
55      case ACK_FRAME:
56        delete it->ack_frame;
57        break;
58      case CONGESTION_FEEDBACK_FRAME:
59        delete it->congestion_feedback_frame;
60        break;
61      case RST_STREAM_FRAME:
62        delete it->rst_stream_frame;
63        break;
64      case CONNECTION_CLOSE_FRAME:
65        delete it->connection_close_frame;
66        break;
67      case GOAWAY_FRAME:
68        delete it->goaway_frame;
69        break;
70      case WINDOW_UPDATE_FRAME:
71        delete it->window_update_frame;
72        break;
73      case BLOCKED_FRAME:
74        delete it->blocked_frame;
75        break;
76      case STOP_WAITING_FRAME:
77        delete it->stop_waiting_frame;
78        break;
79      case PING_FRAME:
80        delete it->ping_frame;
81        break;
82      case NUM_FRAME_TYPES:
83        DCHECK(false) << "Cannot delete type: " << it->type;
84    }
85  }
86}
87
88// NetworkChangeVisitor method.
89void QuicPacketGenerator::OnCongestionWindowChange(
90    QuicByteCount congestion_window) {
91  packet_creator_.set_max_packets_per_fec_group(
92      static_cast<size_t>(kCongestionWindowMultiplierForFecGroupSize *
93                          congestion_window / kDefaultTCPMSS));
94}
95
96void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback,
97                                           bool also_send_stop_waiting) {
98  should_send_ack_ = true;
99  should_send_feedback_ = also_send_feedback;
100  should_send_stop_waiting_ = also_send_stop_waiting;
101  SendQueuedFrames(false);
102}
103
104void QuicPacketGenerator::SetShouldSendStopWaiting() {
105  should_send_stop_waiting_ = true;
106  SendQueuedFrames(false);
107}
108
109void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
110  queued_control_frames_.push_back(frame);
111  SendQueuedFrames(false);
112}
113
114QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
115                                                  const IOVector& data_to_write,
116                                                  QuicStreamOffset offset,
117                                                  bool fin,
118                                                  FecProtection fec_protection,
119                                                  QuicAckNotifier* notifier) {
120  IsHandshake handshake = id == kCryptoStreamId ? IS_HANDSHAKE : NOT_HANDSHAKE;
121  // To make reasoning about crypto frames easier, we don't combine them with
122  // other retransmittable frames in a single packet.
123  const bool flush = handshake == IS_HANDSHAKE &&
124      packet_creator_.HasPendingRetransmittableFrames();
125  SendQueuedFrames(flush);
126
127  size_t total_bytes_consumed = 0;
128  bool fin_consumed = false;
129
130  if (!packet_creator_.HasRoomForStreamFrame(id, offset)) {
131    SerializeAndSendPacket();
132  }
133
134  if (fec_protection == MUST_FEC_PROTECT) {
135    MaybeStartFecProtection();
136  }
137
138  IOVector data = data_to_write;
139  size_t data_size = data.TotalBufferSize();
140  while (delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION,
141                                         HAS_RETRANSMITTABLE_DATA, handshake)) {
142    QuicFrame frame;
143    size_t bytes_consumed;
144    if (notifier != NULL) {
145      // We want to track which packet this stream frame ends up in.
146      bytes_consumed = packet_creator_.CreateStreamFrameWithNotifier(
147          id, data, offset + total_bytes_consumed, fin, notifier, &frame);
148    } else {
149      bytes_consumed = packet_creator_.CreateStreamFrame(
150          id, data, offset + total_bytes_consumed, fin, &frame);
151    }
152    if (!AddFrame(frame)) {
153      LOG(DFATAL) << "Failed to add stream frame.";
154      // Inability to add a STREAM frame creates an unrecoverable hole in a
155      // the stream, so it's best to close the connection.
156      delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false);
157      return QuicConsumedData(0, false);
158    }
159
160    total_bytes_consumed += bytes_consumed;
161    fin_consumed = fin && total_bytes_consumed == data_size;
162    data.Consume(bytes_consumed);
163    DCHECK(data.Empty() || packet_creator_.BytesFree() == 0u);
164
165    // TODO(ianswett): Restore packet reordering.
166    if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) {
167      SerializeAndSendPacket();
168    }
169
170    if (data.Empty()) {
171      // We're done writing the data. Exit the loop.
172      // We don't make this a precondition because we could have 0 bytes of data
173      // if we're simply writing a fin.
174      if (fec_protection == MUST_FEC_PROTECT) {
175        // Turn off FEC protection when we're done writing protected data.
176        DVLOG(1) << "Turning FEC protection OFF";
177        should_fec_protect_ = false;
178      }
179      break;
180    }
181  }
182
183  // Don't allow the handshake to be bundled with other retransmittable frames.
184  if (handshake == IS_HANDSHAKE) {
185    SendQueuedFrames(true);
186  }
187
188  // Try to close FEC group since we've either run out of data to send or we're
189  // blocked. If not in batch mode, force close the group.
190  // TODO(jri): This method should be called with flush=false here
191  // once the timer-based FEC sending is done, to separate FEC sending from
192  // the end of batch operations.
193  MaybeSendFecPacketAndCloseGroup(!InBatchMode());
194
195  DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames());
196  return QuicConsumedData(total_bytes_consumed, fin_consumed);
197}
198
199bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
200  DCHECK(HasPendingFrames());
201  HasRetransmittableData retransmittable =
202      (should_send_ack_ || should_send_feedback_ || should_send_stop_waiting_)
203      ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA;
204  if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
205      DCHECK(!queued_control_frames_.empty());  // These are retransmittable.
206  }
207  return delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, retransmittable,
208                                         NOT_HANDSHAKE);
209}
210
211void QuicPacketGenerator::SendQueuedFrames(bool flush) {
212  // Only add pending frames if we are SURE we can then send the whole packet.
213  while (HasPendingFrames() &&
214         (flush || CanSendWithNextPendingFrameAddition())) {
215    if (!AddNextPendingFrame()) {
216      // Packet was full, so serialize and send it.
217      SerializeAndSendPacket();
218    }
219  }
220
221  if (!InBatchMode() || flush) {
222    if (packet_creator_.HasPendingFrames()) {
223      SerializeAndSendPacket();
224    }
225    // Ensure the FEC group is closed at the end of this method unless other
226    // writes are pending.
227    MaybeSendFecPacketAndCloseGroup(true);
228  }
229}
230
231void QuicPacketGenerator::MaybeStartFecProtection() {
232  if (!packet_creator_.IsFecEnabled()) {
233    return;
234  }
235  DVLOG(1) << "Turning FEC protection ON";
236  should_fec_protect_ = true;
237  if (packet_creator_.IsFecProtected()) {
238    // Only start creator's FEC protection if not already on.
239    return;
240  }
241  if (HasQueuedFrames()) {
242    // TODO(jri): This currently requires that the generator flush out any
243    // pending frames when FEC protection is turned on. If current packet can be
244    // converted to an FEC protected packet, do it. This will require the
245    // generator to check if the resulting expansion still allows the incoming
246    // frame to be added to the packet.
247    SendQueuedFrames(true);
248  }
249  packet_creator_.StartFecProtectingPackets();
250  DCHECK(packet_creator_.IsFecProtected());
251}
252
253void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) {
254  if (!packet_creator_.IsFecProtected() ||
255      packet_creator_.HasPendingFrames() ||
256      !packet_creator_.ShouldSendFec(force)) {
257    return;
258  }
259  // TODO(jri): SerializeFec can return a NULL packet, and this should
260  // cause an early return, with a call to delegate_->OnPacketGenerationError.
261  SerializedPacket serialized_fec = packet_creator_.SerializeFec();
262  DCHECK(serialized_fec.packet);
263  delegate_->OnSerializedPacket(serialized_fec);
264  // Turn FEC protection off if creator's protection is on and the creator
265  // does not have an open FEC group.
266  // Note: We only wait until the frames queued in the creator are flushed;
267  // pending frames in the generator will not keep us from turning FEC off.
268  if (!should_fec_protect_ && !packet_creator_.IsFecGroupOpen()) {
269    packet_creator_.StopFecProtectingPackets();
270    DCHECK(!packet_creator_.IsFecProtected());
271  }
272}
273
274bool QuicPacketGenerator::InBatchMode() {
275  return batch_mode_;
276}
277
278void QuicPacketGenerator::StartBatchOperations() {
279  batch_mode_ = true;
280}
281
282void QuicPacketGenerator::FinishBatchOperations() {
283  batch_mode_ = false;
284  SendQueuedFrames(false);
285}
286
287void QuicPacketGenerator::FlushAllQueuedFrames() {
288  SendQueuedFrames(true);
289}
290
291bool QuicPacketGenerator::HasQueuedFrames() const {
292  return packet_creator_.HasPendingFrames() || HasPendingFrames();
293}
294
295bool QuicPacketGenerator::HasPendingFrames() const {
296  return should_send_ack_ || should_send_feedback_ ||
297      should_send_stop_waiting_ || !queued_control_frames_.empty();
298}
299
300bool QuicPacketGenerator::AddNextPendingFrame() {
301  if (should_send_ack_) {
302    pending_ack_frame_.reset(delegate_->CreateAckFrame());
303    // If we can't this add the frame now, then we still need to do so later.
304    should_send_ack_ = !AddFrame(QuicFrame(pending_ack_frame_.get()));
305    // Return success if we have cleared out this flag (i.e., added the frame).
306    // If we still need to send, then the frame is full, and we have failed.
307    return !should_send_ack_;
308  }
309
310  if (should_send_feedback_) {
311    pending_feedback_frame_.reset(delegate_->CreateFeedbackFrame());
312    // If we can't this add the frame now, then we still need to do so later.
313    should_send_feedback_ = !AddFrame(QuicFrame(pending_feedback_frame_.get()));
314    // Return success if we have cleared out this flag (i.e., added the frame).
315    // If we still need to send, then the frame is full, and we have failed.
316    return !should_send_feedback_;
317  }
318
319  if (should_send_stop_waiting_) {
320    pending_stop_waiting_frame_.reset(delegate_->CreateStopWaitingFrame());
321    // If we can't this add the frame now, then we still need to do so later.
322    should_send_stop_waiting_ =
323        !AddFrame(QuicFrame(pending_stop_waiting_frame_.get()));
324    // Return success if we have cleared out this flag (i.e., added the frame).
325    // If we still need to send, then the frame is full, and we have failed.
326    return !should_send_stop_waiting_;
327  }
328
329  LOG_IF(DFATAL, queued_control_frames_.empty())
330      << "AddNextPendingFrame called with no queued control frames.";
331  if (!AddFrame(queued_control_frames_.back())) {
332    // Packet was full.
333    return false;
334  }
335  queued_control_frames_.pop_back();
336  return true;
337}
338
339bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) {
340  bool success = packet_creator_.AddSavedFrame(frame);
341  if (success && debug_delegate_) {
342    debug_delegate_->OnFrameAddedToPacket(frame);
343  }
344  return success;
345}
346
347void QuicPacketGenerator::SerializeAndSendPacket() {
348  SerializedPacket serialized_packet = packet_creator_.SerializePacket();
349  DCHECK(serialized_packet.packet);
350  delegate_->OnSerializedPacket(serialized_packet);
351  MaybeSendFecPacketAndCloseGroup(false);
352}
353
354void QuicPacketGenerator::StopSendingVersion() {
355  packet_creator_.StopSendingVersion();
356}
357
358QuicPacketSequenceNumber QuicPacketGenerator::sequence_number() const {
359  return packet_creator_.sequence_number();
360}
361
362size_t QuicPacketGenerator::max_packet_length() const {
363  return packet_creator_.max_packet_length();
364}
365
366void QuicPacketGenerator::set_max_packet_length(size_t length) {
367  packet_creator_.set_max_packet_length(length);
368}
369
370QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket(
371    const QuicVersionVector& supported_versions) {
372  return packet_creator_.SerializeVersionNegotiationPacket(supported_versions);
373}
374
375SerializedPacket QuicPacketGenerator::ReserializeAllFrames(
376    const QuicFrames& frames,
377    QuicSequenceNumberLength original_length) {
378  return packet_creator_.ReserializeAllFrames(frames, original_length);
379}
380
381void QuicPacketGenerator::UpdateSequenceNumberLength(
382      QuicPacketSequenceNumber least_packet_awaited_by_peer,
383      QuicByteCount congestion_window) {
384  return packet_creator_.UpdateSequenceNumberLength(
385      least_packet_awaited_by_peer, congestion_window);
386}
387
388void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
389  packet_creator_.set_encryption_level(level);
390}
391
392}  // namespace net
393