| OLD | NEW |
| (Empty) |
| 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_bug_tracker.h" | |
| 9 #include "net/quic/quic_flags.h" | |
| 10 #include "net/quic/quic_utils.h" | |
| 11 | |
| 12 using base::StringPiece; | |
| 13 | |
| 14 namespace net { | |
| 15 | |
| 16 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, | |
| 17 QuicFramer* framer, | |
| 18 QuicRandom* random_generator, | |
| 19 QuicBufferAllocator* buffer_allocator, | |
| 20 DelegateInterface* delegate) | |
| 21 : delegate_(delegate), | |
| 22 packet_creator_(connection_id, | |
| 23 framer, | |
| 24 random_generator, | |
| 25 buffer_allocator, | |
| 26 delegate), | |
| 27 batch_mode_(false), | |
| 28 should_send_ack_(false), | |
| 29 should_send_stop_waiting_(false) {} | |
| 30 | |
| 31 QuicPacketGenerator::~QuicPacketGenerator() { | |
| 32 QuicUtils::DeleteFrames(&queued_control_frames_); | |
| 33 } | |
| 34 | |
| 35 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { | |
| 36 if (packet_creator_.has_ack()) { | |
| 37 // Ack already queued, nothing to do. | |
| 38 return; | |
| 39 } | |
| 40 | |
| 41 if (also_send_stop_waiting && packet_creator_.has_stop_waiting()) { | |
| 42 QUIC_BUG << "Should only ever be one pending stop waiting frame."; | |
| 43 return; | |
| 44 } | |
| 45 | |
| 46 should_send_ack_ = true; | |
| 47 should_send_stop_waiting_ = also_send_stop_waiting; | |
| 48 SendQueuedFrames(/*flush=*/false); | |
| 49 } | |
| 50 | |
| 51 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { | |
| 52 queued_control_frames_.push_back(frame); | |
| 53 SendQueuedFrames(/*flush=*/false); | |
| 54 } | |
| 55 | |
| 56 QuicConsumedData QuicPacketGenerator::ConsumeData( | |
| 57 QuicStreamId id, | |
| 58 QuicIOVector iov, | |
| 59 QuicStreamOffset offset, | |
| 60 bool fin, | |
| 61 QuicAckListenerInterface* listener) { | |
| 62 bool has_handshake = (id == kCryptoStreamId); | |
| 63 QUIC_BUG_IF(has_handshake && fin) | |
| 64 << "Handshake packets should never send a fin"; | |
| 65 // To make reasoning about crypto frames easier, we don't combine them with | |
| 66 // other retransmittable frames in a single packet. | |
| 67 const bool flush = | |
| 68 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); | |
| 69 SendQueuedFrames(flush); | |
| 70 | |
| 71 size_t total_bytes_consumed = 0; | |
| 72 bool fin_consumed = false; | |
| 73 | |
| 74 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { | |
| 75 packet_creator_.Flush(); | |
| 76 } | |
| 77 | |
| 78 if (!fin && (iov.total_length == 0)) { | |
| 79 QUIC_BUG << "Attempt to consume empty data without FIN."; | |
| 80 return QuicConsumedData(0, false); | |
| 81 } | |
| 82 | |
| 83 while (delegate_->ShouldGeneratePacket( | |
| 84 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { | |
| 85 QuicFrame frame; | |
| 86 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, | |
| 87 offset + total_bytes_consumed, fin, | |
| 88 has_handshake, &frame)) { | |
| 89 // The creator is always flushed if there's not enough room for a new | |
| 90 // stream frame before ConsumeData, so ConsumeData should always succeed. | |
| 91 QUIC_BUG << "Failed to ConsumeData, stream:" << id; | |
| 92 return QuicConsumedData(0, false); | |
| 93 } | |
| 94 | |
| 95 // A stream frame is created and added. | |
| 96 size_t bytes_consumed = frame.stream_frame->data_length; | |
| 97 if (listener != nullptr) { | |
| 98 packet_creator_.AddAckListener(listener, bytes_consumed); | |
| 99 } | |
| 100 total_bytes_consumed += bytes_consumed; | |
| 101 fin_consumed = fin && total_bytes_consumed == iov.total_length; | |
| 102 DCHECK(total_bytes_consumed == iov.total_length || | |
| 103 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); | |
| 104 | |
| 105 if (!InBatchMode()) { | |
| 106 packet_creator_.Flush(); | |
| 107 } | |
| 108 | |
| 109 if (total_bytes_consumed == iov.total_length) { | |
| 110 // We're done writing the data. Exit the loop. | |
| 111 // We don't make this a precondition because we could have 0 bytes of data | |
| 112 // if we're simply writing a fin. | |
| 113 break; | |
| 114 } | |
| 115 // TODO(ianswett): Move to having the creator flush itself when it's full. | |
| 116 packet_creator_.Flush(); | |
| 117 } | |
| 118 | |
| 119 // Don't allow the handshake to be bundled with other retransmittable frames. | |
| 120 if (has_handshake) { | |
| 121 SendQueuedFrames(/*flush=*/true); | |
| 122 } | |
| 123 | |
| 124 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); | |
| 125 return QuicConsumedData(total_bytes_consumed, fin_consumed); | |
| 126 } | |
| 127 | |
| 128 QuicConsumedData QuicPacketGenerator::ConsumeDataFastPath( | |
| 129 QuicStreamId id, | |
| 130 const QuicIOVector& iov, | |
| 131 QuicStreamOffset offset, | |
| 132 bool fin, | |
| 133 QuicAckListenerInterface* listener) { | |
| 134 DCHECK_NE(id, kCryptoStreamId); | |
| 135 size_t total_bytes_consumed = 0; | |
| 136 while (total_bytes_consumed < iov.total_length && | |
| 137 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, | |
| 138 NOT_HANDSHAKE)) { | |
| 139 // Serialize and encrypt the packet. | |
| 140 ALIGNAS(64) char encrypted_buffer[kMaxPacketSize]; | |
| 141 size_t bytes_consumed = 0; | |
| 142 packet_creator_.CreateAndSerializeStreamFrame( | |
| 143 id, iov, total_bytes_consumed, offset + total_bytes_consumed, fin, | |
| 144 listener, encrypted_buffer, kMaxPacketSize, &bytes_consumed); | |
| 145 total_bytes_consumed += bytes_consumed; | |
| 146 } | |
| 147 | |
| 148 return QuicConsumedData(total_bytes_consumed, | |
| 149 fin && (total_bytes_consumed == iov.total_length)); | |
| 150 } | |
| 151 | |
| 152 void QuicPacketGenerator::GenerateMtuDiscoveryPacket( | |
| 153 QuicByteCount target_mtu, | |
| 154 QuicAckListenerInterface* listener) { | |
| 155 // MTU discovery frames must be sent by themselves. | |
| 156 if (!packet_creator_.CanSetMaxPacketLength()) { | |
| 157 QUIC_BUG << "MTU discovery packets should only be sent when no other " | |
| 158 << "frames needs to be sent."; | |
| 159 return; | |
| 160 } | |
| 161 const QuicByteCount current_mtu = GetCurrentMaxPacketLength(); | |
| 162 | |
| 163 // The MTU discovery frame is allocated on the stack, since it is going to be | |
| 164 // serialized within this function. | |
| 165 QuicMtuDiscoveryFrame mtu_discovery_frame; | |
| 166 QuicFrame frame(mtu_discovery_frame); | |
| 167 | |
| 168 // Send the probe packet with the new length. | |
| 169 SetMaxPacketLength(target_mtu); | |
| 170 const bool success = packet_creator_.AddPaddedSavedFrame(frame); | |
| 171 if (listener != nullptr) { | |
| 172 packet_creator_.AddAckListener(listener, 0); | |
| 173 } | |
| 174 packet_creator_.Flush(); | |
| 175 // The only reason AddFrame can fail is that the packet is too full to fit in | |
| 176 // a ping. This is not possible for any sane MTU. | |
| 177 DCHECK(success); | |
| 178 | |
| 179 // Reset the packet length back. | |
| 180 SetMaxPacketLength(current_mtu); | |
| 181 } | |
| 182 | |
| 183 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { | |
| 184 DCHECK(HasPendingFrames()); | |
| 185 HasRetransmittableData retransmittable = | |
| 186 (should_send_ack_ || should_send_stop_waiting_) | |
| 187 ? NO_RETRANSMITTABLE_DATA | |
| 188 : HAS_RETRANSMITTABLE_DATA; | |
| 189 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | |
| 190 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | |
| 191 } | |
| 192 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); | |
| 193 } | |
| 194 | |
| 195 void QuicPacketGenerator::SendQueuedFrames(bool flush) { | |
| 196 // Only add pending frames if we are SURE we can then send the whole packet. | |
| 197 while (HasPendingFrames() && | |
| 198 (flush || CanSendWithNextPendingFrameAddition())) { | |
| 199 AddNextPendingFrame(); | |
| 200 } | |
| 201 if (flush || !InBatchMode()) { | |
| 202 packet_creator_.Flush(); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 bool QuicPacketGenerator::InBatchMode() { | |
| 207 return batch_mode_; | |
| 208 } | |
| 209 | |
| 210 void QuicPacketGenerator::StartBatchOperations() { | |
| 211 batch_mode_ = true; | |
| 212 } | |
| 213 | |
| 214 void QuicPacketGenerator::FinishBatchOperations() { | |
| 215 batch_mode_ = false; | |
| 216 SendQueuedFrames(/*flush=*/false); | |
| 217 } | |
| 218 | |
| 219 void QuicPacketGenerator::FlushAllQueuedFrames() { | |
| 220 SendQueuedFrames(/*flush=*/true); | |
| 221 } | |
| 222 | |
| 223 bool QuicPacketGenerator::HasQueuedFrames() const { | |
| 224 return packet_creator_.HasPendingFrames() || HasPendingFrames(); | |
| 225 } | |
| 226 | |
| 227 bool QuicPacketGenerator::IsPendingPacketEmpty() const { | |
| 228 return !packet_creator_.HasPendingFrames(); | |
| 229 } | |
| 230 | |
| 231 bool QuicPacketGenerator::HasPendingFrames() const { | |
| 232 return should_send_ack_ || should_send_stop_waiting_ || | |
| 233 !queued_control_frames_.empty(); | |
| 234 } | |
| 235 | |
| 236 bool QuicPacketGenerator::AddNextPendingFrame() { | |
| 237 if (should_send_ack_) { | |
| 238 should_send_ack_ = | |
| 239 !packet_creator_.AddSavedFrame(delegate_->GetUpdatedAckFrame()); | |
| 240 return !should_send_ack_; | |
| 241 } | |
| 242 | |
| 243 if (should_send_stop_waiting_) { | |
| 244 delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_); | |
| 245 // If we can't this add the frame now, then we still need to do so later. | |
| 246 should_send_stop_waiting_ = | |
| 247 !packet_creator_.AddSavedFrame(QuicFrame(&pending_stop_waiting_frame_)); | |
| 248 // Return success if we have cleared out this flag (i.e., added the frame). | |
| 249 // If we still need to send, then the frame is full, and we have failed. | |
| 250 return !should_send_stop_waiting_; | |
| 251 } | |
| 252 | |
| 253 QUIC_BUG_IF(queued_control_frames_.empty()) | |
| 254 << "AddNextPendingFrame called with no queued control frames."; | |
| 255 if (!packet_creator_.AddSavedFrame(queued_control_frames_.back())) { | |
| 256 // Packet was full. | |
| 257 return false; | |
| 258 } | |
| 259 queued_control_frames_.pop_back(); | |
| 260 return true; | |
| 261 } | |
| 262 | |
| 263 void QuicPacketGenerator::StopSendingVersion() { | |
| 264 packet_creator_.StopSendingVersion(); | |
| 265 } | |
| 266 | |
| 267 void QuicPacketGenerator::SetDiversificationNonce( | |
| 268 const DiversificationNonce nonce) { | |
| 269 packet_creator_.SetDiversificationNonce(nonce); | |
| 270 } | |
| 271 | |
| 272 QuicPacketNumber QuicPacketGenerator::packet_number() const { | |
| 273 return packet_creator_.packet_number(); | |
| 274 } | |
| 275 | |
| 276 QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const { | |
| 277 return packet_creator_.max_packet_length(); | |
| 278 } | |
| 279 | |
| 280 void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) { | |
| 281 DCHECK(packet_creator_.CanSetMaxPacketLength()); | |
| 282 packet_creator_.SetMaxPacketLength(length); | |
| 283 } | |
| 284 | |
| 285 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket( | |
| 286 const QuicVersionVector& supported_versions) { | |
| 287 return packet_creator_.SerializeVersionNegotiationPacket(supported_versions); | |
| 288 } | |
| 289 | |
| 290 void QuicPacketGenerator::ReserializeAllFrames( | |
| 291 const PendingRetransmission& retransmission, | |
| 292 char* buffer, | |
| 293 size_t buffer_len) { | |
| 294 packet_creator_.ReserializeAllFrames(retransmission, buffer, buffer_len); | |
| 295 } | |
| 296 | |
| 297 void QuicPacketGenerator::UpdateSequenceNumberLength( | |
| 298 QuicPacketNumber least_packet_awaited_by_peer, | |
| 299 QuicPacketCount max_packets_in_flight) { | |
| 300 return packet_creator_.UpdatePacketNumberLength(least_packet_awaited_by_peer, | |
| 301 max_packets_in_flight); | |
| 302 } | |
| 303 | |
| 304 void QuicPacketGenerator::SetConnectionIdLength(uint32_t length) { | |
| 305 if (length == 0) { | |
| 306 packet_creator_.set_connection_id_length(PACKET_0BYTE_CONNECTION_ID); | |
| 307 } else { | |
| 308 packet_creator_.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID); | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { | |
| 313 packet_creator_.set_encryption_level(level); | |
| 314 } | |
| 315 | |
| 316 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, | |
| 317 QuicEncrypter* encrypter) { | |
| 318 packet_creator_.SetEncrypter(level, encrypter); | |
| 319 } | |
| 320 | |
| 321 void QuicPacketGenerator::SetCurrentPath( | |
| 322 QuicPathId path_id, | |
| 323 QuicPacketNumber least_packet_awaited_by_peer, | |
| 324 QuicPacketCount max_packets_in_flight) { | |
| 325 packet_creator_.SetCurrentPath(path_id, least_packet_awaited_by_peer, | |
| 326 max_packets_in_flight); | |
| 327 } | |
| 328 | |
| 329 } // namespace net | |
| OLD | NEW |