| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 FecProtection fec_protection) { | 259 FecProtection fec_protection) { |
| 260 if (!HasRoomForStreamFrame(id, offset)) { | 260 if (!HasRoomForStreamFrame(id, offset)) { |
| 261 Flush(); | 261 Flush(); |
| 262 return false; | 262 return false; |
| 263 } | 263 } |
| 264 if (fec_protection == MUST_FEC_PROTECT) { | 264 if (fec_protection == MUST_FEC_PROTECT) { |
| 265 should_fec_protect_next_packet_ = true; | 265 should_fec_protect_next_packet_ = true; |
| 266 MaybeStartFecProtection(); | 266 MaybeStartFecProtection(); |
| 267 } | 267 } |
| 268 CreateStreamFrame(id, iov, iov_offset, offset, fin, frame); | 268 CreateStreamFrame(id, iov, iov_offset, offset, fin, frame); |
| 269 bool success = AddFrame(*frame, | 269 bool success = AddFrame(*frame, /*save_retransmittable_frames=*/true); |
| 270 /*save_retransmittable_frames=*/true, needs_padding); | 270 if (needs_padding) { |
| 271 needs_padding_ = true; |
| 272 } |
| 271 DCHECK(success); | 273 DCHECK(success); |
| 272 return true; | 274 return true; |
| 273 } | 275 } |
| 274 | 276 |
| 275 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, | 277 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, |
| 276 QuicStreamOffset offset) const { | 278 QuicStreamOffset offset) const { |
| 277 // TODO(jri): This is a simple safe decision for now, but make | 279 // TODO(jri): This is a simple safe decision for now, but make |
| 278 // is_in_fec_group a parameter. Same as with all public methods in | 280 // is_in_fec_group a parameter. Same as with all public methods in |
| 279 // QuicPacketCreator. | 281 // QuicPacketCreator. |
| 280 return BytesFree() > | 282 return BytesFree() > |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 return serialized_packet; | 428 return serialized_packet; |
| 427 } | 429 } |
| 428 | 430 |
| 429 SerializedPacket QuicPacketCreator::SerializeAllFrames(const QuicFrames& frames, | 431 SerializedPacket QuicPacketCreator::SerializeAllFrames(const QuicFrames& frames, |
| 430 char* buffer, | 432 char* buffer, |
| 431 size_t buffer_len) { | 433 size_t buffer_len) { |
| 432 LOG_IF(DFATAL, !queued_frames_.empty()) << "Frames already queued."; | 434 LOG_IF(DFATAL, !queued_frames_.empty()) << "Frames already queued."; |
| 433 LOG_IF(DFATAL, frames.empty()) | 435 LOG_IF(DFATAL, frames.empty()) |
| 434 << "Attempt to serialize empty packet"; | 436 << "Attempt to serialize empty packet"; |
| 435 for (const QuicFrame& frame : frames) { | 437 for (const QuicFrame& frame : frames) { |
| 436 bool success = AddFrame(frame, false, false); | 438 bool success = AddFrame(frame, false); |
| 437 DCHECK(success); | 439 DCHECK(success); |
| 438 } | 440 } |
| 439 SerializedPacket packet = SerializePacket(buffer, buffer_len); | 441 SerializedPacket packet = SerializePacket(buffer, buffer_len); |
| 440 DCHECK(packet.retransmittable_frames == nullptr); | 442 DCHECK(packet.retransmittable_frames == nullptr); |
| 441 return packet; | 443 return packet; |
| 442 } | 444 } |
| 443 | 445 |
| 444 void QuicPacketCreator::Flush() { | 446 void QuicPacketCreator::Flush() { |
| 445 if (!HasPendingFrames()) { | 447 if (!HasPendingFrames()) { |
| 446 return; | 448 return; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 // Update packet number length on packet and FEC boundary. | 491 // Update packet number length on packet and FEC boundary. |
| 490 packet_number_length_ = next_packet_number_length_; | 492 packet_number_length_ = next_packet_number_length_; |
| 491 } | 493 } |
| 492 packet_size_ = GetPacketHeaderSize( | 494 packet_size_ = GetPacketHeaderSize( |
| 493 connection_id_length_, send_version_in_packet_, /*include_path_id=*/false, | 495 connection_id_length_, send_version_in_packet_, /*include_path_id=*/false, |
| 494 packet_number_length_, fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); | 496 packet_number_length_, fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); |
| 495 return packet_size_; | 497 return packet_size_; |
| 496 } | 498 } |
| 497 | 499 |
| 498 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { | 500 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { |
| 499 return AddFrame(frame, | 501 return AddFrame(frame, /*save_retransmittable_frames=*/true); |
| 500 /*save_retransmittable_frames=*/true, | |
| 501 /*needs_padding=*/false); | |
| 502 } | 502 } |
| 503 | 503 |
| 504 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame) { | 504 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame) { |
| 505 return AddFrame(frame, | 505 if (AddFrame(frame, /*save_retransmittable_frames=*/true)) { |
| 506 /*save_retransmittable_frames=*/true, | 506 needs_padding_ = true; |
| 507 /*needs_padding=*/true); | 507 return true; |
| 508 } |
| 509 return false; |
| 508 } | 510 } |
| 509 | 511 |
| 510 SerializedPacket QuicPacketCreator::SerializePacket( | 512 SerializedPacket QuicPacketCreator::SerializePacket( |
| 511 char* encrypted_buffer, | 513 char* encrypted_buffer, |
| 512 size_t encrypted_buffer_len) { | 514 size_t encrypted_buffer_len) { |
| 513 DCHECK_LT(0u, encrypted_buffer_len); | 515 DCHECK_LT(0u, encrypted_buffer_len); |
| 514 LOG_IF(DFATAL, queued_frames_.empty()) | 516 LOG_IF(DFATAL, queued_frames_.empty()) |
| 515 << "Attempt to serialize empty packet"; | 517 << "Attempt to serialize empty packet"; |
| 516 if (fec_group_.get() != nullptr) { | 518 if (fec_group_.get() != nullptr) { |
| 517 DCHECK_GE(packet_number_ + 1, fec_group_->FecGroupNumber()); | 519 DCHECK_GE(packet_number_ + 1, fec_group_->FecGroupNumber()); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 case PADDING_FRAME: | 667 case PADDING_FRAME: |
| 666 case STOP_WAITING_FRAME: | 668 case STOP_WAITING_FRAME: |
| 667 case MTU_DISCOVERY_FRAME: | 669 case MTU_DISCOVERY_FRAME: |
| 668 return false; | 670 return false; |
| 669 default: | 671 default: |
| 670 return true; | 672 return true; |
| 671 } | 673 } |
| 672 } | 674 } |
| 673 | 675 |
| 674 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, | 676 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, |
| 675 bool save_retransmittable_frames, | 677 bool save_retransmittable_frames) { |
| 676 bool needs_padding) { | |
| 677 DVLOG(1) << "Adding frame: " << frame; | 678 DVLOG(1) << "Adding frame: " << frame; |
| 678 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); | 679 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
| 679 | 680 |
| 680 size_t frame_len = framer_->GetSerializedFrameLength( | 681 size_t frame_len = framer_->GetSerializedFrameLength( |
| 681 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 682 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, |
| 682 packet_number_length_); | 683 packet_number_length_); |
| 683 if (frame_len == 0) { | 684 if (frame_len == 0) { |
| 684 // Current open packet is full. | 685 // Current open packet is full. |
| 685 Flush(); | 686 Flush(); |
| 686 return false; | 687 return false; |
| 687 } | 688 } |
| 688 DCHECK_LT(0u, packet_size_); | 689 DCHECK_LT(0u, packet_size_); |
| 689 packet_size_ += ExpansionOnNewFrame() + frame_len; | 690 packet_size_ += ExpansionOnNewFrame() + frame_len; |
| 690 | 691 |
| 691 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | 692 if (save_retransmittable_frames && ShouldRetransmit(frame)) { |
| 692 if (queued_retransmittable_frames_.get() == nullptr) { | 693 if (queued_retransmittable_frames_.get() == nullptr) { |
| 693 queued_retransmittable_frames_.reset(new RetransmittableFrames()); | 694 queued_retransmittable_frames_.reset(new RetransmittableFrames()); |
| 694 } | 695 } |
| 695 queued_frames_.push_back(queued_retransmittable_frames_->AddFrame(frame)); | 696 queued_frames_.push_back(queued_retransmittable_frames_->AddFrame(frame)); |
| 696 } else { | 697 } else { |
| 697 queued_frames_.push_back(frame); | 698 queued_frames_.push_back(frame); |
| 698 } | 699 } |
| 699 | 700 |
| 700 if (frame.type == ACK_FRAME) { | 701 if (frame.type == ACK_FRAME) { |
| 701 has_ack_ = true; | 702 has_ack_ = true; |
| 702 } | 703 } |
| 703 if (frame.type == STOP_WAITING_FRAME) { | 704 if (frame.type == STOP_WAITING_FRAME) { |
| 704 has_stop_waiting_ = true; | 705 has_stop_waiting_ = true; |
| 705 } | 706 } |
| 706 if (needs_padding) { | |
| 707 needs_padding_ = true; | |
| 708 } | |
| 709 if (debug_delegate_ != nullptr) { | 707 if (debug_delegate_ != nullptr) { |
| 710 debug_delegate_->OnFrameAddedToPacket(frame); | 708 debug_delegate_->OnFrameAddedToPacket(frame); |
| 711 } | 709 } |
| 712 | 710 |
| 713 return true; | 711 return true; |
| 714 } | 712 } |
| 715 | 713 |
| 716 void QuicPacketCreator::MaybeAddPadding() { | 714 void QuicPacketCreator::MaybeAddPadding() { |
| 717 if (!needs_padding_) { | 715 if (!needs_padding_) { |
| 718 return; | 716 return; |
| 719 } | 717 } |
| 720 | 718 |
| 721 if (BytesFree() == 0) { | 719 if (BytesFree() == 0) { |
| 722 // Don't pad full packets. | 720 // Don't pad full packets. |
| 723 return; | 721 return; |
| 724 } | 722 } |
| 725 | 723 |
| 726 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false, false); | 724 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false); |
| 727 DCHECK(success); | 725 DCHECK(success); |
| 728 } | 726 } |
| 729 | 727 |
| 730 void QuicPacketCreator::MaybeStartFecProtection() { | 728 void QuicPacketCreator::MaybeStartFecProtection() { |
| 731 if (max_packets_per_fec_group_ == 0 || fec_protect_) { | 729 if (max_packets_per_fec_group_ == 0 || fec_protect_) { |
| 732 // Do not start FEC protection when FEC protection is not enabled or FEC | 730 // Do not start FEC protection when FEC protection is not enabled or FEC |
| 733 // protection is already on. | 731 // protection is already on. |
| 734 return; | 732 return; |
| 735 } | 733 } |
| 736 DVLOG(1) << "Turning FEC protection ON"; | 734 DVLOG(1) << "Turning FEC protection ON"; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 hash_map<QuicPathId, QuicPacketNumber>::iterator it = | 804 hash_map<QuicPathId, QuicPacketNumber>::iterator it = |
| 807 multipath_packet_number_.find(path_id); | 805 multipath_packet_number_.find(path_id); |
| 808 // If path_id is not in the map, it's a new path. Set packet_number to 0. | 806 // If path_id is not in the map, it's a new path. Set packet_number to 0. |
| 809 packet_number_ = it == multipath_packet_number_.end() ? 0 : it->second; | 807 packet_number_ = it == multipath_packet_number_.end() ? 0 : it->second; |
| 810 current_path_ = path_id; | 808 current_path_ = path_id; |
| 811 // Switching path needs to update packet number length. | 809 // Switching path needs to update packet number length. |
| 812 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); | 810 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); |
| 813 } | 811 } |
| 814 | 812 |
| 815 } // namespace net | 813 } // namespace net |
| OLD | NEW |