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/logging.h" 8 #include "net/quic/quic_fec_group.h" 9 #include "net/quic/quic_utils.h" 10 11 using base::StringPiece; 12 13 namespace net { 14 15 QuicPacketGenerator::QuicPacketGenerator(DelegateInterface* delegate, 16 DebugDelegateInterface* debug_delegate, 17 QuicPacketCreator* creator) 18 : delegate_(delegate), 19 debug_delegate_(debug_delegate), 20 packet_creator_(creator), 21 should_flush_(true), 22 should_send_ack_(false), 23 should_send_feedback_(false) { 24 } 25 26 QuicPacketGenerator::~QuicPacketGenerator() { 27 for (QuicFrames::iterator it = queued_control_frames_.begin(); 28 it != queued_control_frames_.end(); ++it) { 29 switch (it->type) { 30 case PADDING_FRAME: 31 delete it->padding_frame; 32 break; 33 case STREAM_FRAME: 34 delete it->stream_frame; 35 break; 36 case ACK_FRAME: 37 delete it->ack_frame; 38 break; 39 case CONGESTION_FEEDBACK_FRAME: 40 delete it->congestion_feedback_frame; 41 break; 42 case RST_STREAM_FRAME: 43 delete it->rst_stream_frame; 44 break; 45 case CONNECTION_CLOSE_FRAME: 46 delete it->connection_close_frame; 47 break; 48 case GOAWAY_FRAME: 49 delete it->goaway_frame; 50 break; 51 case NUM_FRAME_TYPES: 52 DCHECK(false) << "Cannot delete type: " << it->type; 53 } 54 } 55 } 56 57 void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback) { 58 should_send_ack_ = true; 59 should_send_feedback_ = also_send_feedback; 60 SendQueuedFrames(); 61 } 62 63 64 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { 65 queued_control_frames_.push_back(frame); 66 SendQueuedFrames(); 67 } 68 69 QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id, 70 StringPiece data, 71 QuicStreamOffset offset, 72 bool fin) { 73 SendQueuedFrames(); 74 75 size_t total_bytes_consumed = 0; 76 bool fin_consumed = false; 77 78 while (delegate_->CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, 79 NOT_HANDSHAKE)) { 80 QuicFrame frame; 81 size_t bytes_consumed = packet_creator_->CreateStreamFrame( 82 id, data, offset + total_bytes_consumed, fin, &frame); 83 bool success = AddFrame(frame); 84 DCHECK(success); 85 86 total_bytes_consumed += bytes_consumed; 87 fin_consumed = fin && bytes_consumed == data.size(); 88 data.remove_prefix(bytes_consumed); 89 DCHECK(data.empty() || packet_creator_->BytesFree() == 0u); 90 91 // TODO(ianswett): Restore packet reordering. 92 if (should_flush_ || !packet_creator_->HasRoomForStreamFrame(id, offset)) { 93 SerializeAndSendPacket(); 94 } 95 96 if (data.empty()) { 97 // We're done writing the data. Exit the loop. 98 // We don't make this a precondition because we could have 0 bytes of data 99 // if we're simply writing a fin. 100 break; 101 } 102 } 103 104 // Ensure the FEC group is closed at the end of this method unless other 105 // writes are pending. 106 if (should_flush_ && packet_creator_->ShouldSendFec(true)) { 107 SerializedPacket serialized_fec = packet_creator_->SerializeFec(); 108 DCHECK(serialized_fec.packet); 109 delegate_->OnSerializedPacket(serialized_fec); 110 } 111 112 DCHECK(!should_flush_ || !packet_creator_->HasPendingFrames()); 113 return QuicConsumedData(total_bytes_consumed, fin_consumed); 114 } 115 116 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { 117 DCHECK(HasPendingFrames()); 118 HasRetransmittableData retransmittable = 119 (should_send_ack_ || should_send_feedback_) ? NO_RETRANSMITTABLE_DATA 120 : HAS_RETRANSMITTABLE_DATA; 121 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { 122 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. 123 } 124 return delegate_->CanWrite(NOT_RETRANSMISSION, retransmittable, 125 NOT_HANDSHAKE); 126 } 127 128 void QuicPacketGenerator::SendQueuedFrames() { 129 packet_creator_->MaybeStartFEC(); 130 // Only add pending frames if we are SURE we can then send the whole packet. 131 while (HasPendingFrames() && CanSendWithNextPendingFrameAddition()) { 132 if (!AddNextPendingFrame()) { 133 // Packet was full, so serialize and send it. 134 SerializeAndSendPacket(); 135 } 136 } 137 138 if (should_flush_) { 139 if (packet_creator_->HasPendingFrames()) { 140 SerializeAndSendPacket(); 141 } 142 143 // Ensure the FEC group is closed at the end of this method unless other 144 // writes are pending. 145 if (packet_creator_->ShouldSendFec(true)) { 146 SerializedPacket serialized_fec = packet_creator_->SerializeFec(); 147 DCHECK(serialized_fec.packet); 148 delegate_->OnSerializedPacket(serialized_fec); 149 packet_creator_->MaybeStartFEC(); 150 } 151 } 152 } 153 154 void QuicPacketGenerator::StartBatchOperations() { 155 should_flush_ = false; 156 } 157 158 void QuicPacketGenerator::FinishBatchOperations() { 159 should_flush_ = true; 160 SendQueuedFrames(); 161 } 162 163 bool QuicPacketGenerator::HasQueuedFrames() const { 164 return packet_creator_->HasPendingFrames() || HasPendingFrames(); 165 } 166 167 bool QuicPacketGenerator::HasPendingFrames() const { 168 return should_send_ack_ || should_send_feedback_ || 169 !queued_control_frames_.empty(); 170 } 171 172 bool QuicPacketGenerator::AddNextPendingFrame() { 173 if (should_send_ack_) { 174 pending_ack_frame_.reset((delegate_->CreateAckFrame())); 175 // If we can't this add the frame now, then we still need to do so later. 176 should_send_ack_ = !AddFrame(QuicFrame(pending_ack_frame_.get())); 177 // Return success if we have cleared out this flag (i.e., added the frame). 178 // If we still need to send, then the frame is full, and we have failed. 179 return !should_send_ack_; 180 } 181 182 if (should_send_feedback_) { 183 pending_feedback_frame_.reset((delegate_->CreateFeedbackFrame())); 184 // If we can't this add the frame now, then we still need to do so later. 185 should_send_feedback_ = !AddFrame(QuicFrame(pending_feedback_frame_.get())); 186 // Return success if we have cleared out this flag (i.e., added the frame). 187 // If we still need to send, then the frame is full, and we have failed. 188 return !should_send_feedback_; 189 } 190 191 DCHECK(!queued_control_frames_.empty()); 192 if (!AddFrame(queued_control_frames_.back())) { 193 // Packet was full. 194 return false; 195 } 196 queued_control_frames_.pop_back(); 197 return true; 198 } 199 200 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) { 201 bool success = packet_creator_->AddSavedFrame(frame); 202 if (success && debug_delegate_) { 203 debug_delegate_->OnFrameAddedToPacket(frame); 204 } 205 return success; 206 } 207 208 void QuicPacketGenerator::SerializeAndSendPacket() { 209 SerializedPacket serialized_packet = packet_creator_->SerializePacket(); 210 DCHECK(serialized_packet.packet); 211 delegate_->OnSerializedPacket(serialized_packet); 212 213 if (packet_creator_->ShouldSendFec(false)) { 214 SerializedPacket serialized_fec = packet_creator_->SerializeFec(); 215 DCHECK(serialized_fec.packet); 216 delegate_->OnSerializedPacket(serialized_fec); 217 packet_creator_->MaybeStartFEC(); 218 } 219 } 220 221 } // namespace net 222