OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_packet_creator.h" | 5 #include "net/quic/quic_packet_creator.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "net/quic/crypto/quic_random.h" | 9 #include "net/quic/crypto/quic_random.h" |
10 #include "net/quic/quic_ack_notifier.h" | 10 #include "net/quic/quic_ack_notifier.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 | 97 |
98 void QuicPacketCreator::set_max_packets_per_fec_group( | 98 void QuicPacketCreator::set_max_packets_per_fec_group( |
99 size_t max_packets_per_fec_group) { | 99 size_t max_packets_per_fec_group) { |
100 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, | 100 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, |
101 max_packets_per_fec_group); | 101 max_packets_per_fec_group); |
102 DCHECK_LT(0u, max_packets_per_fec_group_); | 102 DCHECK_LT(0u, max_packets_per_fec_group_); |
103 } | 103 } |
104 | 104 |
105 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { | 105 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { |
106 DCHECK(!HasPendingFrames()); | 106 DCHECK(!HasPendingFrames()); |
107 return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 && | 107 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 && |
108 (force_close || fec_group_->NumReceivedPackets() >= | 108 (force_close || |
109 max_packets_per_fec_group_); | 109 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); |
110 } | 110 } |
111 | 111 |
112 bool QuicPacketCreator::IsFecGroupOpen() const { | 112 bool QuicPacketCreator::IsFecGroupOpen() const { |
113 return fec_group_.get() != NULL; | 113 return fec_group_.get() != nullptr; |
114 } | 114 } |
115 | 115 |
116 void QuicPacketCreator::StartFecProtectingPackets() { | 116 void QuicPacketCreator::StartFecProtectingPackets() { |
117 if (!IsFecEnabled()) { | 117 if (!IsFecEnabled()) { |
118 LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled."; | 118 LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled."; |
119 return; | 119 return; |
120 } | 120 } |
121 // TODO(jri): This currently requires that the generator flush out any | 121 // TODO(jri): This currently requires that the generator flush out any |
122 // pending frames when FEC protection is turned on. If current packet can be | 122 // pending frames when FEC protection is turned on. If current packet can be |
123 // converted to an FEC protected packet, do it. This will require the | 123 // converted to an FEC protected packet, do it. This will require the |
124 // generator to check if the resulting expansion still allows the incoming | 124 // generator to check if the resulting expansion still allows the incoming |
125 // frame to be added to the packet. | 125 // frame to be added to the packet. |
126 if (HasPendingFrames()) { | 126 if (HasPendingFrames()) { |
127 LOG(DFATAL) << "Cannot start FEC protection with pending frames."; | 127 LOG(DFATAL) << "Cannot start FEC protection with pending frames."; |
128 return; | 128 return; |
129 } | 129 } |
130 DCHECK(!should_fec_protect_); | 130 DCHECK(!should_fec_protect_); |
131 should_fec_protect_ = true; | 131 should_fec_protect_ = true; |
132 } | 132 } |
133 | 133 |
134 void QuicPacketCreator::StopFecProtectingPackets() { | 134 void QuicPacketCreator::StopFecProtectingPackets() { |
135 if (fec_group_.get() != NULL) { | 135 if (fec_group_.get() != nullptr) { |
136 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; | 136 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; |
137 return; | 137 return; |
138 } | 138 } |
139 DCHECK(should_fec_protect_); | 139 DCHECK(should_fec_protect_); |
140 should_fec_protect_ = false; | 140 should_fec_protect_ = false; |
141 fec_group_number_ = 0; | 141 fec_group_number_ = 0; |
142 } | 142 } |
143 | 143 |
144 bool QuicPacketCreator::IsFecProtected() const { | 144 bool QuicPacketCreator::IsFecProtected() const { |
145 return should_fec_protect_; | 145 return should_fec_protect_; |
146 } | 146 } |
147 | 147 |
148 bool QuicPacketCreator::IsFecEnabled() const { | 148 bool QuicPacketCreator::IsFecEnabled() const { |
149 return max_packets_per_fec_group_ > 0; | 149 return max_packets_per_fec_group_ > 0; |
150 } | 150 } |
151 | 151 |
152 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { | 152 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { |
153 if (fec_group_.get() != NULL) { | 153 if (fec_group_.get() != nullptr) { |
154 // Don't update any lengths when an FEC group is open, to ensure same | 154 // Don't update any lengths when an FEC group is open, to ensure same |
155 // packet header size in all packets within a group. | 155 // packet header size in all packets within a group. |
156 return IN_FEC_GROUP; | 156 return IN_FEC_GROUP; |
157 } | 157 } |
158 if (!queued_frames_.empty()) { | 158 if (!queued_frames_.empty()) { |
159 // Don't change creator state if there are frames queued. | 159 // Don't change creator state if there are frames queued. |
160 return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; | 160 return fec_group_.get() == nullptr ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; |
161 } | 161 } |
162 | 162 |
163 // Update sequence number length only on packet and FEC group boundaries. | 163 // Update sequence number length only on packet and FEC group boundaries. |
164 sequence_number_length_ = next_sequence_number_length_; | 164 sequence_number_length_ = next_sequence_number_length_; |
165 | 165 |
166 if (!should_fec_protect_) { | 166 if (!should_fec_protect_) { |
167 return NOT_IN_FEC_GROUP; | 167 return NOT_IN_FEC_GROUP; |
168 } | 168 } |
169 // Start a new FEC group since protection is on. Set the fec group number to | 169 // Start a new FEC group since protection is on. Set the fec group number to |
170 // the sequence number of the next packet. | 170 // the sequence number of the next packet. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 // a packet. At that point the notifier is informed of the sequence number | 276 // a packet. At that point the notifier is informed of the sequence number |
277 // of the packet that this frame was eventually sent in. | 277 // of the packet that this frame was eventually sent in. |
278 frame->stream_frame->notifier = notifier; | 278 frame->stream_frame->notifier = notifier; |
279 | 279 |
280 return bytes_consumed; | 280 return bytes_consumed; |
281 } | 281 } |
282 | 282 |
283 SerializedPacket QuicPacketCreator::ReserializeAllFrames( | 283 SerializedPacket QuicPacketCreator::ReserializeAllFrames( |
284 const QuicFrames& frames, | 284 const QuicFrames& frames, |
285 QuicSequenceNumberLength original_length) { | 285 QuicSequenceNumberLength original_length) { |
286 DCHECK(fec_group_.get() == NULL); | 286 DCHECK(fec_group_.get() == nullptr); |
287 const QuicSequenceNumberLength saved_length = sequence_number_length_; | 287 const QuicSequenceNumberLength saved_length = sequence_number_length_; |
288 const QuicSequenceNumberLength saved_next_length = | 288 const QuicSequenceNumberLength saved_next_length = |
289 next_sequence_number_length_; | 289 next_sequence_number_length_; |
290 const bool saved_should_fec_protect = should_fec_protect_; | 290 const bool saved_should_fec_protect = should_fec_protect_; |
291 | 291 |
292 // Temporarily set the sequence number length and stop FEC protection. | 292 // Temporarily set the sequence number length and stop FEC protection. |
293 sequence_number_length_ = original_length; | 293 sequence_number_length_ = original_length; |
294 next_sequence_number_length_ = original_length; | 294 next_sequence_number_length_ = original_length; |
295 should_fec_protect_ = false; | 295 should_fec_protect_ = false; |
296 | 296 |
(...skipping 12 matching lines...) Expand all Loading... |
309 // frames from SendStreamData()[send_stream_should_flush_ == false && | 309 // frames from SendStreamData()[send_stream_should_flush_ == false && |
310 // data.empty() == true] and retransmit due to RTO. | 310 // data.empty() == true] and retransmit due to RTO. |
311 DCHECK_EQ(0u, queued_frames_.size()); | 311 DCHECK_EQ(0u, queued_frames_.size()); |
312 LOG_IF(DFATAL, frames.empty()) | 312 LOG_IF(DFATAL, frames.empty()) |
313 << "Attempt to serialize empty packet"; | 313 << "Attempt to serialize empty packet"; |
314 for (size_t i = 0; i < frames.size(); ++i) { | 314 for (size_t i = 0; i < frames.size(); ++i) { |
315 bool success = AddFrame(frames[i], false); | 315 bool success = AddFrame(frames[i], false); |
316 DCHECK(success); | 316 DCHECK(success); |
317 } | 317 } |
318 SerializedPacket packet = SerializePacket(); | 318 SerializedPacket packet = SerializePacket(); |
319 DCHECK(packet.retransmittable_frames == NULL); | 319 DCHECK(packet.retransmittable_frames == nullptr); |
320 return packet; | 320 return packet; |
321 } | 321 } |
322 | 322 |
323 bool QuicPacketCreator::HasPendingFrames() const { | 323 bool QuicPacketCreator::HasPendingFrames() const { |
324 return !queued_frames_.empty(); | 324 return !queued_frames_.empty(); |
325 } | 325 } |
326 | 326 |
327 bool QuicPacketCreator::HasPendingRetransmittableFrames() const { | 327 bool QuicPacketCreator::HasPendingRetransmittableFrames() const { |
328 return queued_retransmittable_frames_.get() != NULL && | 328 return queued_retransmittable_frames_.get() != nullptr && |
329 !queued_retransmittable_frames_->frames().empty(); | 329 !queued_retransmittable_frames_->frames().empty(); |
330 } | 330 } |
331 | 331 |
332 size_t QuicPacketCreator::ExpansionOnNewFrame() const { | 332 size_t QuicPacketCreator::ExpansionOnNewFrame() const { |
333 // If packet is FEC protected, there's no expansion. | 333 // If packet is FEC protected, there's no expansion. |
334 if (should_fec_protect_) { | 334 if (should_fec_protect_) { |
335 return 0; | 335 return 0; |
336 } | 336 } |
337 // If the last frame in the packet is a stream frame, then it will expand to | 337 // If the last frame in the packet is a stream frame, then it will expand to |
338 // include the stream_length field when a new frame is added. | 338 // include the stream_length field when a new frame is added. |
339 bool has_trailing_stream_frame = | 339 bool has_trailing_stream_frame = |
340 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; | 340 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; |
341 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; | 341 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; |
342 } | 342 } |
343 | 343 |
344 size_t QuicPacketCreator::BytesFree() const { | 344 size_t QuicPacketCreator::BytesFree() const { |
345 const size_t max_plaintext_size = | 345 const size_t max_plaintext_size = |
346 framer_->GetMaxPlaintextSize(max_packet_length_); | 346 framer_->GetMaxPlaintextSize(max_packet_length_); |
347 DCHECK_GE(max_plaintext_size, PacketSize()); | 347 DCHECK_GE(max_plaintext_size, PacketSize()); |
348 return max_plaintext_size - min(max_plaintext_size, PacketSize() | 348 return max_plaintext_size - min(max_plaintext_size, PacketSize() |
349 + ExpansionOnNewFrame()); | 349 + ExpansionOnNewFrame()); |
350 } | 350 } |
351 | 351 |
352 size_t QuicPacketCreator::PacketSize() const { | 352 size_t QuicPacketCreator::PacketSize() const { |
353 if (!queued_frames_.empty()) { | 353 if (!queued_frames_.empty()) { |
354 return packet_size_; | 354 return packet_size_; |
355 } | 355 } |
356 if (fec_group_.get() == NULL) { | 356 if (fec_group_.get() == nullptr) { |
357 // Update sequence number length on packet and FEC boundary. | 357 // Update sequence number length on packet and FEC boundary. |
358 sequence_number_length_ = next_sequence_number_length_; | 358 sequence_number_length_ = next_sequence_number_length_; |
359 } | 359 } |
360 packet_size_ = GetPacketHeaderSize( | 360 packet_size_ = GetPacketHeaderSize( |
361 connection_id_length_, send_version_in_packet_, sequence_number_length_, | 361 connection_id_length_, send_version_in_packet_, sequence_number_length_, |
362 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); | 362 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); |
363 return packet_size_; | 363 return packet_size_; |
364 } | 364 } |
365 | 365 |
366 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { | 366 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { |
(...skipping 28 matching lines...) Expand all Loading... |
395 if (!possibly_truncated_by_length) { | 395 if (!possibly_truncated_by_length) { |
396 DCHECK_EQ(packet_size_, serialized.packet->length()); | 396 DCHECK_EQ(packet_size_, serialized.packet->length()); |
397 } | 397 } |
398 packet_size_ = 0; | 398 packet_size_ = 0; |
399 queued_frames_.clear(); | 399 queued_frames_.clear(); |
400 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); | 400 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); |
401 return serialized; | 401 return serialized; |
402 } | 402 } |
403 | 403 |
404 SerializedPacket QuicPacketCreator::SerializeFec() { | 404 SerializedPacket QuicPacketCreator::SerializeFec() { |
405 if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() <= 0) { | 405 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { |
406 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; | 406 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; |
407 // TODO(jri): Make this a public method of framer? | 407 // TODO(jri): Make this a public method of framer? |
408 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL); | 408 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, |
| 409 nullptr); |
409 return kNoPacket; | 410 return kNoPacket; |
410 } | 411 } |
411 DCHECK_EQ(0u, queued_frames_.size()); | 412 DCHECK_EQ(0u, queued_frames_.size()); |
412 QuicPacketHeader header; | 413 QuicPacketHeader header; |
413 FillPacketHeader(fec_group_number_, true, &header); | 414 FillPacketHeader(fec_group_number_, true, &header); |
414 QuicFecData fec_data; | 415 QuicFecData fec_data; |
415 fec_data.fec_group = fec_group_->min_protected_packet(); | 416 fec_data.fec_group = fec_group_->min_protected_packet(); |
416 fec_data.redundancy = fec_group_->payload_parity(); | 417 fec_data.redundancy = fec_group_->payload_parity(); |
417 SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data); | 418 SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data); |
418 fec_group_.reset(NULL); | 419 fec_group_.reset(nullptr); |
419 packet_size_ = 0; | 420 packet_size_ = 0; |
420 LOG_IF(DFATAL, !serialized.packet) | 421 LOG_IF(DFATAL, !serialized.packet) |
421 << "Failed to serialize fec packet for group:" << fec_data.fec_group; | 422 << "Failed to serialize fec packet for group:" << fec_data.fec_group; |
422 DCHECK_GE(max_packet_length_, serialized.packet->length()); | 423 DCHECK_GE(max_packet_length_, serialized.packet->length()); |
423 return serialized; | 424 return serialized; |
424 } | 425 } |
425 | 426 |
426 SerializedPacket QuicPacketCreator::SerializeConnectionClose( | 427 SerializedPacket QuicPacketCreator::SerializeConnectionClose( |
427 QuicConnectionCloseFrame* close_frame) { | 428 QuicConnectionCloseFrame* close_frame) { |
428 QuicFrames frames; | 429 QuicFrames frames; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 size_t frame_len = framer_->GetSerializedFrameLength( | 480 size_t frame_len = framer_->GetSerializedFrameLength( |
480 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 481 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, |
481 sequence_number_length_); | 482 sequence_number_length_); |
482 if (frame_len == 0) { | 483 if (frame_len == 0) { |
483 return false; | 484 return false; |
484 } | 485 } |
485 DCHECK_LT(0u, packet_size_); | 486 DCHECK_LT(0u, packet_size_); |
486 packet_size_ += ExpansionOnNewFrame() + frame_len; | 487 packet_size_ += ExpansionOnNewFrame() + frame_len; |
487 | 488 |
488 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | 489 if (save_retransmittable_frames && ShouldRetransmit(frame)) { |
489 if (queued_retransmittable_frames_.get() == NULL) { | 490 if (queued_retransmittable_frames_.get() == nullptr) { |
490 queued_retransmittable_frames_.reset(new RetransmittableFrames()); | 491 queued_retransmittable_frames_.reset(new RetransmittableFrames()); |
491 } | 492 } |
492 if (frame.type == STREAM_FRAME) { | 493 if (frame.type == STREAM_FRAME) { |
493 queued_frames_.push_back( | 494 queued_frames_.push_back( |
494 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame)); | 495 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame)); |
495 } else { | 496 } else { |
496 queued_frames_.push_back( | 497 queued_frames_.push_back( |
497 queued_retransmittable_frames_->AddNonStreamFrame(frame)); | 498 queued_retransmittable_frames_->AddNonStreamFrame(frame)); |
498 } | 499 } |
499 } else { | 500 } else { |
500 queued_frames_.push_back(frame); | 501 queued_frames_.push_back(frame); |
501 } | 502 } |
502 return true; | 503 return true; |
503 } | 504 } |
504 | 505 |
505 void QuicPacketCreator::MaybeAddPadding() { | 506 void QuicPacketCreator::MaybeAddPadding() { |
506 if (queued_retransmittable_frames_.get() == NULL) { | 507 if (queued_retransmittable_frames_.get() == nullptr) { |
507 return; | 508 return; |
508 } | 509 } |
509 if (!queued_retransmittable_frames_->HasCryptoHandshake()) { | 510 if (!queued_retransmittable_frames_->HasCryptoHandshake()) { |
510 return; | 511 return; |
511 } | 512 } |
512 if (BytesFree() == 0) { | 513 if (BytesFree() == 0) { |
513 // Don't pad full packets. | 514 // Don't pad full packets. |
514 return; | 515 return; |
515 } | 516 } |
516 QuicPaddingFrame padding; | 517 QuicPaddingFrame padding; |
517 bool success = AddFrame(QuicFrame(&padding), false); | 518 bool success = AddFrame(QuicFrame(&padding), false); |
518 DCHECK(success); | 519 DCHECK(success); |
519 } | 520 } |
520 | 521 |
521 } // namespace net | 522 } // namespace net |
OLD | NEW |