Home | History | Annotate | Download | only in quic
      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 
     12 using base::StringPiece;
     13 
     14 namespace net {
     15 
     16 namespace {
     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.
     25 const float kCongestionWindowMultiplierForFecGroupSize = 0.5;
     26 
     27 }  // namespace
     28 
     29 class QuicAckNotifier;
     30 
     31 QuicPacketGenerator::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 
     45 QuicPacketGenerator::~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.
     89 void 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 
     96 void 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 
    104 void QuicPacketGenerator::SetShouldSendStopWaiting() {
    105   should_send_stop_waiting_ = true;
    106   SendQueuedFrames(false);
    107 }
    108 
    109 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
    110   queued_control_frames_.push_back(frame);
    111   SendQueuedFrames(false);
    112 }
    113 
    114 QuicConsumedData 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 
    199 bool 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 
    211 void 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 
    231 void 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 
    253 void 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 
    274 bool QuicPacketGenerator::InBatchMode() {
    275   return batch_mode_;
    276 }
    277 
    278 void QuicPacketGenerator::StartBatchOperations() {
    279   batch_mode_ = true;
    280 }
    281 
    282 void QuicPacketGenerator::FinishBatchOperations() {
    283   batch_mode_ = false;
    284   SendQueuedFrames(false);
    285 }
    286 
    287 void QuicPacketGenerator::FlushAllQueuedFrames() {
    288   SendQueuedFrames(true);
    289 }
    290 
    291 bool QuicPacketGenerator::HasQueuedFrames() const {
    292   return packet_creator_.HasPendingFrames() || HasPendingFrames();
    293 }
    294 
    295 bool QuicPacketGenerator::HasPendingFrames() const {
    296   return should_send_ack_ || should_send_feedback_ ||
    297       should_send_stop_waiting_ || !queued_control_frames_.empty();
    298 }
    299 
    300 bool 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 
    339 bool 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 
    347 void QuicPacketGenerator::SerializeAndSendPacket() {
    348   SerializedPacket serialized_packet = packet_creator_.SerializePacket();
    349   DCHECK(serialized_packet.packet);
    350   delegate_->OnSerializedPacket(serialized_packet);
    351   MaybeSendFecPacketAndCloseGroup(false);
    352 }
    353 
    354 void QuicPacketGenerator::StopSendingVersion() {
    355   packet_creator_.StopSendingVersion();
    356 }
    357 
    358 QuicPacketSequenceNumber QuicPacketGenerator::sequence_number() const {
    359   return packet_creator_.sequence_number();
    360 }
    361 
    362 size_t QuicPacketGenerator::max_packet_length() const {
    363   return packet_creator_.max_packet_length();
    364 }
    365 
    366 void QuicPacketGenerator::set_max_packet_length(size_t length) {
    367   packet_creator_.set_max_packet_length(length);
    368 }
    369 
    370 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket(
    371     const QuicVersionVector& supported_versions) {
    372   return packet_creator_.SerializeVersionNegotiationPacket(supported_versions);
    373 }
    374 
    375 SerializedPacket QuicPacketGenerator::ReserializeAllFrames(
    376     const QuicFrames& frames,
    377     QuicSequenceNumberLength original_length) {
    378   return packet_creator_.ReserializeAllFrames(frames, original_length);
    379 }
    380 
    381 void 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 
    388 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
    389   packet_creator_.set_encryption_level(level);
    390 }
    391 
    392 }  // namespace net
    393