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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id, | 70 QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id, |
71 QuicFramer* framer, | 71 QuicFramer* framer, |
72 QuicRandom* random_generator) | 72 QuicRandom* random_generator) |
73 : connection_id_(connection_id), | 73 : connection_id_(connection_id), |
74 encryption_level_(ENCRYPTION_NONE), | 74 encryption_level_(ENCRYPTION_NONE), |
75 framer_(framer), | 75 framer_(framer), |
76 random_bool_source_(new QuicRandomBoolSource(random_generator)), | 76 random_bool_source_(new QuicRandomBoolSource(random_generator)), |
77 packet_number_(0), | 77 packet_number_(0), |
78 should_fec_protect_(false), | 78 should_fec_protect_(false), |
79 fec_group_number_(0), | |
80 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT), | 79 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT), |
81 max_packet_length_(0), | 80 max_packet_length_(0), |
82 max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup), | 81 max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup), |
83 connection_id_length_(PACKET_8BYTE_CONNECTION_ID), | 82 connection_id_length_(PACKET_8BYTE_CONNECTION_ID), |
84 next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER), | 83 next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER), |
85 packet_number_length_(next_packet_number_length_), | 84 packet_number_length_(next_packet_number_length_), |
86 packet_size_(0), | 85 packet_size_(0), |
87 needs_padding_(false) { | 86 needs_padding_(false) { |
88 SetMaxPacketLength(kDefaultMaxPacketSize); | 87 SetMaxPacketLength(kDefaultMaxPacketSize); |
89 } | 88 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); | 122 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); |
124 } | 123 } |
125 | 124 |
126 void QuicPacketCreator::set_max_packets_per_fec_group( | 125 void QuicPacketCreator::set_max_packets_per_fec_group( |
127 size_t max_packets_per_fec_group) { | 126 size_t max_packets_per_fec_group) { |
128 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, | 127 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup, |
129 max_packets_per_fec_group); | 128 max_packets_per_fec_group); |
130 DCHECK_LT(0u, max_packets_per_fec_group_); | 129 DCHECK_LT(0u, max_packets_per_fec_group_); |
131 } | 130 } |
132 | 131 |
| 132 QuicFecGroupNumber QuicPacketCreator::fec_group_number() { |
| 133 return fec_group_ != nullptr ? fec_group_->FecGroupNumber() : 0; |
| 134 } |
| 135 |
133 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { | 136 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { |
134 DCHECK(!HasPendingFrames()); | 137 DCHECK(!HasPendingFrames()); |
135 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 && | 138 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 && |
136 (force_close || | 139 (force_close || |
137 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); | 140 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); |
138 } | 141 } |
139 | 142 |
140 void QuicPacketCreator::ResetFecGroup() { | 143 void QuicPacketCreator::ResetFecGroup() { |
141 if (HasPendingFrames()) { | 144 if (HasPendingFrames()) { |
142 LOG_IF(DFATAL, packet_size_ != 0) | 145 LOG_IF(DFATAL, packet_size_ != 0) |
(...skipping 25 matching lines...) Expand all Loading... |
168 should_fec_protect_ = true; | 171 should_fec_protect_ = true; |
169 } | 172 } |
170 | 173 |
171 void QuicPacketCreator::StopFecProtectingPackets() { | 174 void QuicPacketCreator::StopFecProtectingPackets() { |
172 if (fec_group_.get() != nullptr) { | 175 if (fec_group_.get() != nullptr) { |
173 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; | 176 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; |
174 return; | 177 return; |
175 } | 178 } |
176 DCHECK(should_fec_protect_); | 179 DCHECK(should_fec_protect_); |
177 should_fec_protect_ = false; | 180 should_fec_protect_ = false; |
178 fec_group_number_ = 0; | |
179 } | 181 } |
180 | 182 |
181 bool QuicPacketCreator::IsFecProtected() const { | 183 bool QuicPacketCreator::IsFecProtected() const { |
182 return should_fec_protect_; | 184 return should_fec_protect_; |
183 } | 185 } |
184 | 186 |
185 bool QuicPacketCreator::IsFecEnabled() const { | 187 bool QuicPacketCreator::IsFecEnabled() const { |
186 return max_packets_per_fec_group_ > 0; | 188 return max_packets_per_fec_group_ > 0; |
187 } | 189 } |
188 | 190 |
189 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { | 191 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { |
190 if (fec_group_.get() != nullptr) { | 192 if (fec_group_.get() != nullptr) { |
191 // Don't update any lengths when an FEC group is open, to ensure same | 193 // Don't update any lengths when an FEC group is open, to ensure same |
192 // packet header size in all packets within a group. | 194 // packet header size in all packets within a group. |
193 return IN_FEC_GROUP; | 195 return IN_FEC_GROUP; |
194 } | 196 } |
195 if (!queued_frames_.empty()) { | 197 if (!queued_frames_.empty()) { |
196 // Don't change creator state if there are frames queued. | 198 // Don't change creator state if there are frames queued. |
197 return NOT_IN_FEC_GROUP; | 199 return NOT_IN_FEC_GROUP; |
198 } | 200 } |
199 | 201 |
200 // Update packet number length only on packet and FEC group boundaries. | 202 // Update packet number length only on packet and FEC group boundaries. |
201 packet_number_length_ = next_packet_number_length_; | 203 packet_number_length_ = next_packet_number_length_; |
202 | 204 |
203 if (!should_fec_protect_) { | 205 if (!should_fec_protect_) { |
204 return NOT_IN_FEC_GROUP; | 206 return NOT_IN_FEC_GROUP; |
205 } | 207 } |
206 // Start a new FEC group since protection is on. Set the fec group number to | 208 // Start a new FEC group since protection is on. Set the fec group number to |
207 // the packet number of the next packet. | 209 // the packet number of the next packet. |
208 fec_group_number_ = packet_number() + 1; | 210 fec_group_.reset(new QuicFecGroup(packet_number_ + 1)); |
209 fec_group_.reset(new QuicFecGroup(fec_group_number_)); | |
210 return IN_FEC_GROUP; | 211 return IN_FEC_GROUP; |
211 } | 212 } |
212 | 213 |
213 // Stops serializing version of the protocol in packets sent after this call. | 214 // Stops serializing version of the protocol in packets sent after this call. |
214 // A packet that is already open might send kQuicVersionSize bytes less than the | 215 // A packet that is already open might send kQuicVersionSize bytes less than the |
215 // maximum packet size if we stop sending version before it is serialized. | 216 // maximum packet size if we stop sending version before it is serialized. |
216 void QuicPacketCreator::StopSendingVersion() { | 217 void QuicPacketCreator::StopSendingVersion() { |
217 DCHECK(send_version_in_packet_); | 218 DCHECK(send_version_in_packet_); |
218 send_version_in_packet_ = false; | 219 send_version_in_packet_ = false; |
219 if (packet_size_ > 0) { | 220 if (packet_size_ > 0) { |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 /*save_retransmittable_frames=*/true, | 473 /*save_retransmittable_frames=*/true, |
473 /*needs_padding=*/true, buffer.Pass()); | 474 /*needs_padding=*/true, buffer.Pass()); |
474 } | 475 } |
475 | 476 |
476 SerializedPacket QuicPacketCreator::SerializePacket( | 477 SerializedPacket QuicPacketCreator::SerializePacket( |
477 char* encrypted_buffer, | 478 char* encrypted_buffer, |
478 size_t encrypted_buffer_len) { | 479 size_t encrypted_buffer_len) { |
479 DCHECK_LT(0u, encrypted_buffer_len); | 480 DCHECK_LT(0u, encrypted_buffer_len); |
480 LOG_IF(DFATAL, queued_frames_.empty()) | 481 LOG_IF(DFATAL, queued_frames_.empty()) |
481 << "Attempt to serialize empty packet"; | 482 << "Attempt to serialize empty packet"; |
482 DCHECK_GE(packet_number_ + 1, fec_group_number_); | 483 if (fec_group_.get() != nullptr) { |
| 484 DCHECK_GE(packet_number_ + 1, fec_group_->FecGroupNumber()); |
| 485 } |
483 QuicPacketHeader header; | 486 QuicPacketHeader header; |
484 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header); | 487 // FillPacketHeader increments packet_number_. |
| 488 FillPacketHeader(fec_group_number(), false, &header); |
485 | 489 |
486 MaybeAddPadding(); | 490 MaybeAddPadding(); |
487 | 491 |
488 DCHECK_GE(max_plaintext_size_, packet_size_); | 492 DCHECK_GE(max_plaintext_size_, packet_size_); |
489 // ACK Frames will be truncated due to length only if they're the only frame | 493 // ACK Frames will be truncated due to length only if they're the only frame |
490 // in the packet, and if packet_size_ was set to max_plaintext_size_. If | 494 // in the packet, and if packet_size_ was set to max_plaintext_size_. If |
491 // truncation due to length occurred, then GetSerializedFrameLength will have | 495 // truncation due to length occurred, then GetSerializedFrameLength will have |
492 // returned all bytes free. | 496 // returned all bytes free. |
493 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && | 497 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && |
494 queued_frames_.size() == 1 && | 498 queued_frames_.size() == 1 && |
495 queued_frames_.back().type == ACK_FRAME; | 499 queued_frames_.back().type == ACK_FRAME; |
496 // The optimized encryption algorithm implementations run faster when | 500 // The optimized encryption algorithm implementations run faster when |
497 // operating on aligned memory. | 501 // operating on aligned memory. |
498 // TODO(rtenneti): Change the default 64 alignas value (used the default | 502 // TODO(rtenneti): Change the default 64 alignas value (used the default |
499 // value from CACHELINE_SIZE). | 503 // value from CACHELINE_SIZE). |
500 ALIGNAS(64) char buffer[kMaxPacketSize]; | 504 ALIGNAS(64) char buffer[kMaxPacketSize]; |
501 // Use the packet_size_ instead of the buffer size to ensure smaller | 505 // Use the packet_size_ instead of the buffer size to ensure smaller |
502 // packet sizes are properly used. | 506 // packet sizes are properly used. |
503 scoped_ptr<char[]> large_buffer; | 507 size_t length = |
504 size_t length = 0; | 508 framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_); |
505 const bool use_stack_buffer = packet_size_ <= kMaxPacketSize; | |
506 if (use_stack_buffer) { | |
507 length = | |
508 framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_); | |
509 } else { | |
510 large_buffer.reset(new char[packet_size_]); | |
511 length = framer_->BuildDataPacket(header, queued_frames_, | |
512 large_buffer.get(), packet_size_); | |
513 } | |
514 if (length == 0) { | 509 if (length == 0) { |
515 LOG(DFATAL) << "Failed to serialize " << queued_frames_.size() | 510 LOG(DFATAL) << "Failed to serialize " << queued_frames_.size() |
516 << " frames."; | 511 << " frames."; |
517 return NoPacket(); | 512 return NoPacket(); |
518 } | 513 } |
519 | 514 |
520 // TODO(ianswett) Consider replacing QuicPacket with something else, | 515 // TODO(ianswett) Consider replacing QuicPacket with something else, |
521 // since it's only used to provide convenience methods to FEC and encryption. | 516 // since it's only used to provide convenience methods to FEC and encryption. |
522 QuicPacket packet(use_stack_buffer ? buffer : large_buffer.get(), length, | 517 QuicPacket packet(buffer, length, |
523 /* owns_buffer */ false, | 518 /* owns_buffer */ false, |
524 header.public_header.connection_id_length, | 519 header.public_header.connection_id_length, |
525 header.public_header.version_flag, | 520 header.public_header.version_flag, |
526 header.public_header.packet_number_length); | 521 header.public_header.packet_number_length); |
527 OnBuiltFecProtectedPayload(header, packet.FecProtectedData()); | 522 OnBuiltFecProtectedPayload(header, packet.FecProtectedData()); |
528 | 523 |
529 // Because of possible truncation, we can't be confident that our | 524 // Because of possible truncation, we can't be confident that our |
530 // packet size calculation worked correctly. | 525 // packet size calculation worked correctly. |
531 if (!possibly_truncated_by_length) { | 526 if (!possibly_truncated_by_length) { |
532 DCHECK_EQ(packet_size_, length); | 527 DCHECK_EQ(packet_size_, length); |
533 } | 528 } |
534 // Immediately encrypt the packet, to ensure we don't encrypt the same packet | 529 // Immediately encrypt the packet, to ensure we don't encrypt the same packet |
535 // packet number multiple times. | 530 // packet number multiple times. |
536 QuicEncryptedPacket* encrypted = | 531 size_t encrypted_length = |
537 framer_->EncryptPayload(encryption_level_, packet_number_, packet, | 532 framer_->EncryptPayload(encryption_level_, packet_number_, packet, |
538 encrypted_buffer, encrypted_buffer_len); | 533 encrypted_buffer, encrypted_buffer_len); |
539 if (encrypted == nullptr) { | 534 if (encrypted_length == 0) { |
540 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; | 535 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; |
541 return NoPacket(); | 536 return NoPacket(); |
542 } | 537 } |
543 | 538 |
544 // Update |needs_padding_| flag of |queued_retransmittable_frames_| here, and | 539 // Update |needs_padding_| flag of |queued_retransmittable_frames_| here, and |
545 // not in AddFrame, because when the first padded frame is added to the queue, | 540 // not in AddFrame, because when the first padded frame is added to the queue, |
546 // it might not be retransmittable, and hence the flag would end up being not | 541 // it might not be retransmittable, and hence the flag would end up being not |
547 // set. | 542 // set. |
548 if (queued_retransmittable_frames_.get() != nullptr) { | 543 if (queued_retransmittable_frames_.get() != nullptr) { |
549 queued_retransmittable_frames_->set_needs_padding(needs_padding_); | 544 queued_retransmittable_frames_->set_needs_padding(needs_padding_); |
550 } | 545 } |
551 | 546 |
552 bool has_ack = false; | 547 bool has_ack = false; |
553 bool has_stop_waiting = false; | 548 bool has_stop_waiting = false; |
554 for (const QuicFrame& frame : queued_frames_) { | 549 for (const QuicFrame& frame : queued_frames_) { |
555 has_ack |= frame.type == ACK_FRAME; | 550 has_ack |= frame.type == ACK_FRAME; |
556 has_stop_waiting |= frame.type == STOP_WAITING_FRAME; | 551 has_stop_waiting |= frame.type == STOP_WAITING_FRAME; |
557 } | 552 } |
558 | 553 |
559 packet_size_ = 0; | 554 packet_size_ = 0; |
560 queued_frames_.clear(); | 555 queued_frames_.clear(); |
561 needs_padding_ = false; | 556 needs_padding_ = false; |
562 return SerializedPacket( | 557 return SerializedPacket( |
563 header.packet_number, header.public_header.packet_number_length, | 558 header.packet_number, header.public_header.packet_number_length, |
564 encrypted, QuicFramer::GetPacketEntropyHash(header), | 559 encrypted_buffer, encrypted_length, /* owns_buffer*/ false, |
| 560 QuicFramer::GetPacketEntropyHash(header), |
565 queued_retransmittable_frames_.release(), has_ack, has_stop_waiting); | 561 queued_retransmittable_frames_.release(), has_ack, has_stop_waiting); |
566 } | 562 } |
567 | 563 |
568 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer, | 564 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer, |
569 size_t buffer_len) { | 565 size_t buffer_len) { |
570 DCHECK_LT(0u, buffer_len); | 566 DCHECK_LT(0u, buffer_len); |
571 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { | 567 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { |
572 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; | 568 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; |
573 // TODO(jri): Make this a public method of framer? | 569 // TODO(jri): Make this a public method of framer? |
574 return NoPacket(); | 570 return NoPacket(); |
575 } | 571 } |
576 DCHECK_EQ(0u, queued_frames_.size()); | 572 DCHECK_EQ(0u, queued_frames_.size()); |
577 QuicPacketHeader header; | 573 QuicPacketHeader header; |
578 FillPacketHeader(fec_group_number_, true, &header); | 574 FillPacketHeader(fec_group_->FecGroupNumber(), true, &header); |
579 scoped_ptr<QuicPacket> packet( | 575 scoped_ptr<QuicPacket> packet( |
580 framer_->BuildFecPacket(header, fec_group_->PayloadParity())); | 576 framer_->BuildFecPacket(header, fec_group_->PayloadParity())); |
581 fec_group_.reset(nullptr); | 577 fec_group_.reset(nullptr); |
582 packet_size_ = 0; | 578 packet_size_ = 0; |
583 LOG_IF(DFATAL, packet == nullptr) | 579 LOG_IF(DFATAL, packet == nullptr) |
584 << "Failed to serialize fec packet for group:" << fec_group_number_; | 580 << "Failed to serialize fec packet for group:" |
| 581 << fec_group_->FecGroupNumber(); |
585 DCHECK_GE(max_packet_length_, packet->length()); | 582 DCHECK_GE(max_packet_length_, packet->length()); |
586 // Immediately encrypt the packet, to ensure we don't encrypt the same packet | 583 // Immediately encrypt the packet, to ensure we don't encrypt the same packet |
587 // packet number multiple times. | 584 // packet number multiple times. |
588 QuicEncryptedPacket* encrypted = framer_->EncryptPayload( | 585 size_t encrypted_length = framer_->EncryptPayload( |
589 encryption_level_, packet_number_, *packet, buffer, buffer_len); | 586 encryption_level_, packet_number_, *packet, buffer, buffer_len); |
590 if (encrypted == nullptr) { | 587 if (encrypted_length == 0) { |
591 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; | 588 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; |
592 return NoPacket(); | 589 return NoPacket(); |
593 } | 590 } |
594 SerializedPacket serialized( | 591 SerializedPacket serialized( |
595 header.packet_number, header.public_header.packet_number_length, | 592 header.packet_number, header.public_header.packet_number_length, buffer, |
596 encrypted, QuicFramer::GetPacketEntropyHash(header), nullptr, false, | 593 encrypted_length, /* owns_buffer */ false, |
597 false); | 594 QuicFramer::GetPacketEntropyHash(header), nullptr, false, false); |
598 serialized.is_fec_packet = true; | 595 serialized.is_fec_packet = true; |
599 return serialized; | 596 return serialized; |
600 } | 597 } |
601 | 598 |
602 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( | 599 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( |
603 const QuicVersionVector& supported_versions) { | 600 const QuicVersionVector& supported_versions) { |
604 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); | 601 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); |
605 QuicPacketPublicHeader header; | 602 QuicPacketPublicHeader header; |
606 header.connection_id = connection_id_; | 603 header.connection_id = connection_id_; |
607 header.reset_flag = false; | 604 header.reset_flag = false; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 if (BytesFree() == 0) { | 685 if (BytesFree() == 0) { |
689 // Don't pad full packets. | 686 // Don't pad full packets. |
690 return; | 687 return; |
691 } | 688 } |
692 | 689 |
693 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false, false, nullptr); | 690 bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false, false, nullptr); |
694 DCHECK(success); | 691 DCHECK(success); |
695 } | 692 } |
696 | 693 |
697 } // namespace net | 694 } // namespace net |
OLD | NEW |