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_connection.h" | 5 #include "net/quic/quic_connection.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <iterator> | 10 #include <iterator> |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 helper_(helper), | 160 helper_(helper), |
161 writer_(writer), | 161 writer_(writer), |
162 encryption_level_(ENCRYPTION_NONE), | 162 encryption_level_(ENCRYPTION_NONE), |
163 clock_(helper->GetClock()), | 163 clock_(helper->GetClock()), |
164 random_generator_(helper->GetRandomGenerator()), | 164 random_generator_(helper->GetRandomGenerator()), |
165 guid_(guid), | 165 guid_(guid), |
166 peer_address_(address), | 166 peer_address_(address), |
167 largest_seen_packet_with_ack_(0), | 167 largest_seen_packet_with_ack_(0), |
168 pending_version_negotiation_packet_(false), | 168 pending_version_negotiation_packet_(false), |
169 received_packet_manager_(kTCP), | 169 received_packet_manager_(kTCP), |
| 170 ack_queued_(false), |
170 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), | 171 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), |
171 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), | 172 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), |
172 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 173 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
173 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 174 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
174 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), | 175 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), |
175 debug_visitor_(NULL), | 176 debug_visitor_(NULL), |
176 packet_creator_(guid_, &framer_, random_generator_, is_server), | 177 packet_creator_(guid_, &framer_, random_generator_, is_server), |
177 packet_generator_(this, NULL, &packet_creator_), | 178 packet_generator_(this, NULL, &packet_creator_), |
178 idle_network_timeout_( | 179 idle_network_timeout_( |
179 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), | 180 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 DVLOG(1) << ENDPOINT << (last_packet_revived_ ? "Revived" : "Got") | 630 DVLOG(1) << ENDPOINT << (last_packet_revived_ ? "Revived" : "Got") |
630 << " packet " << last_header_.packet_sequence_number | 631 << " packet " << last_header_.packet_sequence_number |
631 << " with " << last_ack_frames_.size() << " acks, " | 632 << " with " << last_ack_frames_.size() << " acks, " |
632 << last_congestion_frames_.size() << " congestions, " | 633 << last_congestion_frames_.size() << " congestions, " |
633 << last_goaway_frames_.size() << " goaways, " | 634 << last_goaway_frames_.size() << " goaways, " |
634 << last_rst_frames_.size() << " rsts, " | 635 << last_rst_frames_.size() << " rsts, " |
635 << last_close_frames_.size() << " closes, " | 636 << last_close_frames_.size() << " closes, " |
636 << last_stream_frames_.size() | 637 << last_stream_frames_.size() |
637 << " stream frames for " << last_header_.public_header.guid; | 638 << " stream frames for " << last_header_.public_header.guid; |
638 | 639 |
639 // Must called before ack processing, because processing acks removes entries | 640 MaybeQueueAck(); |
640 // from unacket_packets_, increasing the least_unacked. | |
641 const bool last_packet_should_instigate_ack = ShouldLastPacketInstigateAck(); | |
642 | |
643 // If the incoming packet was missing, send an ack immediately. | |
644 bool send_ack_immediately = received_packet_manager_.IsMissing( | |
645 last_header_.packet_sequence_number); | |
646 | 641 |
647 // Discard the packet if the visitor fails to process the stream frames. | 642 // Discard the packet if the visitor fails to process the stream frames. |
648 if (!last_stream_frames_.empty() && | 643 if (!last_stream_frames_.empty() && |
649 !visitor_->OnStreamFrames(last_stream_frames_)) { | 644 !visitor_->OnStreamFrames(last_stream_frames_)) { |
650 return; | 645 return; |
651 } | 646 } |
652 | 647 |
653 received_packet_manager_.RecordPacketReceived(last_size_, | 648 received_packet_manager_.RecordPacketReceived(last_size_, |
654 last_header_, | 649 last_header_, |
655 time_of_last_received_packet_, | 650 time_of_last_received_packet_, |
(...skipping 17 matching lines...) Expand all Loading... |
673 sent_packet_manager_.OnIncomingQuicCongestionFeedbackFrame( | 668 sent_packet_manager_.OnIncomingQuicCongestionFeedbackFrame( |
674 last_congestion_frames_[i], time_of_last_received_packet_); | 669 last_congestion_frames_[i], time_of_last_received_packet_); |
675 } | 670 } |
676 if (!last_close_frames_.empty()) { | 671 if (!last_close_frames_.empty()) { |
677 CloseConnection(last_close_frames_[0].error_code, true); | 672 CloseConnection(last_close_frames_[0].error_code, true); |
678 DCHECK(!connected_); | 673 DCHECK(!connected_); |
679 } | 674 } |
680 | 675 |
681 // If there are new missing packets to report, send an ack immediately. | 676 // If there are new missing packets to report, send an ack immediately. |
682 if (received_packet_manager_.HasNewMissingPackets()) { | 677 if (received_packet_manager_.HasNewMissingPackets()) { |
683 send_ack_immediately = true; | 678 ack_queued_ = true; |
| 679 ack_alarm_->Cancel(); |
684 } | 680 } |
685 | 681 |
686 MaybeSendInResponseToPacket(send_ack_immediately, | 682 ClearLastFrames(); |
687 last_packet_should_instigate_ack); | 683 } |
688 | 684 |
689 ClearLastFrames(); | 685 void QuicConnection::MaybeQueueAck() { |
| 686 // If the incoming packet was missing, send an ack immediately. |
| 687 ack_queued_ = received_packet_manager_.IsMissing( |
| 688 last_header_.packet_sequence_number); |
| 689 |
| 690 // ShouldLastPacketInstigateAck must called before ack processing, because |
| 691 // processing acks removes entries from unacket_packets_, increasing the |
| 692 // least_unacked. |
| 693 if (!ack_queued_ && ShouldLastPacketInstigateAck()) { |
| 694 if (ack_alarm_->IsSet()) { |
| 695 ack_queued_ = true; |
| 696 } else { |
| 697 ack_alarm_->Set(clock_->ApproximateNow().Add( |
| 698 sent_packet_manager_.DelayedAckTime())); |
| 699 DVLOG(1) << "Ack timer set; next packet or timer will trigger ACK."; |
| 700 } |
| 701 } |
| 702 |
| 703 if (ack_queued_) { |
| 704 ack_alarm_->Cancel(); |
| 705 } |
690 } | 706 } |
691 | 707 |
692 void QuicConnection::ClearLastFrames() { | 708 void QuicConnection::ClearLastFrames() { |
693 last_stream_frames_.clear(); | 709 last_stream_frames_.clear(); |
694 last_goaway_frames_.clear(); | 710 last_goaway_frames_.clear(); |
695 last_rst_frames_.clear(); | 711 last_rst_frames_.clear(); |
696 last_ack_frames_.clear(); | 712 last_ack_frames_.clear(); |
697 last_congestion_frames_.clear(); | 713 last_congestion_frames_.clear(); |
698 } | 714 } |
699 | 715 |
(...skipping 10 matching lines...) Expand all Loading... |
710 return new QuicCongestionFeedbackFrame(outgoing_congestion_feedback_); | 726 return new QuicCongestionFeedbackFrame(outgoing_congestion_feedback_); |
711 } | 727 } |
712 | 728 |
713 bool QuicConnection::ShouldLastPacketInstigateAck() { | 729 bool QuicConnection::ShouldLastPacketInstigateAck() { |
714 if (!last_stream_frames_.empty() || | 730 if (!last_stream_frames_.empty() || |
715 !last_goaway_frames_.empty() || | 731 !last_goaway_frames_.empty() || |
716 !last_rst_frames_.empty()) { | 732 !last_rst_frames_.empty()) { |
717 return true; | 733 return true; |
718 } | 734 } |
719 | 735 |
720 // If the peer is still waiting for a packet that we are no | 736 // If the peer is still waiting for a packet that we are no longer planning to |
721 // longer planning to send, we should send an ack to raise | 737 // send, send an ack to raise the high water mark. |
722 // the high water mark. | |
723 if (!last_ack_frames_.empty() && | 738 if (!last_ack_frames_.empty() && |
724 !last_ack_frames_.back().received_info.missing_packets.empty()) { | 739 !last_ack_frames_.back().received_info.missing_packets.empty()) { |
725 return sent_packet_manager_.GetLeastUnackedSentPacket() > | 740 return sent_packet_manager_.GetLeastUnackedSentPacket() > |
726 *last_ack_frames_.back().received_info.missing_packets.begin(); | 741 *last_ack_frames_.back().received_info.missing_packets.begin(); |
727 } | 742 } |
728 return false; | 743 return false; |
729 } | 744 } |
730 | 745 |
731 void QuicConnection::MaybeSendInResponseToPacket( | 746 void QuicConnection::MaybeSendInResponseToPacket() { |
732 bool send_ack_immediately, | 747 if (!connected_) { |
733 bool last_packet_should_instigate_ack) { | 748 return; |
734 // |include_ack| is false since we decide about ack bundling below. | 749 } |
735 ScopedPacketBundler bundler(this, false); | 750 ScopedPacketBundler bundler(this, false); |
736 | 751 if (ack_queued_) { |
737 if (last_packet_should_instigate_ack) { | 752 SendAck(); |
738 // In general, we ack every second packet. When we don't ack the first | |
739 // packet, we set the delayed ack alarm. Thus, if the ack alarm is set | |
740 // then we know this is the second packet, and we should send an ack. | |
741 if (send_ack_immediately || ack_alarm_->IsSet()) { | |
742 SendAck(); | |
743 DCHECK(!ack_alarm_->IsSet()); | |
744 } else { | |
745 ack_alarm_->Set(clock_->ApproximateNow().Add( | |
746 sent_packet_manager_.DelayedAckTime())); | |
747 DVLOG(1) << "Ack timer set; next packet or timer will trigger ACK."; | |
748 } | |
749 } | 753 } |
750 | 754 |
751 if (!last_ack_frames_.empty()) { | 755 // Now that we have received an ack, we might be able to send packets which |
752 // Now the we have received an ack, we might be able to send packets which | 756 // are queued locally, or drain streams which are blocked. |
753 // are queued locally, or drain streams which are blocked. | 757 QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend( |
754 QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend( | 758 time_of_last_received_packet_, NOT_RETRANSMISSION, |
755 time_of_last_received_packet_, NOT_RETRANSMISSION, | 759 HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); |
756 HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); | 760 if (delay.IsZero()) { |
757 if (delay.IsZero()) { | 761 send_alarm_->Cancel(); |
758 send_alarm_->Cancel(); | 762 WriteIfNotBlocked(); |
759 WriteIfNotBlocked(); | 763 } else if (!delay.IsInfinite()) { |
760 } else if (!delay.IsInfinite()) { | 764 send_alarm_->Cancel(); |
761 send_alarm_->Cancel(); | 765 send_alarm_->Set(time_of_last_received_packet_.Add(delay)); |
762 send_alarm_->Set(time_of_last_received_packet_.Add(delay)); | |
763 } | |
764 } | 766 } |
765 } | 767 } |
766 | 768 |
767 void QuicConnection::SendVersionNegotiationPacket() { | 769 void QuicConnection::SendVersionNegotiationPacket() { |
768 scoped_ptr<QuicEncryptedPacket> version_packet( | 770 scoped_ptr<QuicEncryptedPacket> version_packet( |
769 packet_creator_.SerializeVersionNegotiationPacket( | 771 packet_creator_.SerializeVersionNegotiationPacket( |
770 framer_.supported_versions())); | 772 framer_.supported_versions())); |
771 // TODO(satyamshekhar): implement zero server state negotiation. | 773 // TODO(satyamshekhar): implement zero server state negotiation. |
772 WriteResult result = | 774 WriteResult result = |
773 writer_->WritePacket(version_packet->data(), version_packet->length(), | 775 writer_->WritePacket(version_packet->data(), version_packet->length(), |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 // because the CHLO or SHLO packet was lost. | 868 // because the CHLO or SHLO packet was lost. |
867 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && | 869 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && |
868 framer_.error() == QUIC_DECRYPTION_FAILURE && | 870 framer_.error() == QUIC_DECRYPTION_FAILURE && |
869 undecryptable_packets_.size() < kMaxUndecryptablePackets) { | 871 undecryptable_packets_.size() < kMaxUndecryptablePackets) { |
870 QueueUndecryptablePacket(packet); | 872 QueueUndecryptablePacket(packet); |
871 } | 873 } |
872 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " | 874 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " |
873 << last_header_.packet_sequence_number; | 875 << last_header_.packet_sequence_number; |
874 return; | 876 return; |
875 } | 877 } |
| 878 |
876 MaybeProcessUndecryptablePackets(); | 879 MaybeProcessUndecryptablePackets(); |
877 MaybeProcessRevivedPacket(); | 880 MaybeProcessRevivedPacket(); |
| 881 MaybeSendInResponseToPacket(); |
878 } | 882 } |
879 | 883 |
880 bool QuicConnection::OnCanWrite() { | 884 bool QuicConnection::OnCanWrite() { |
881 DCHECK(!writer_->IsWriteBlocked()); | 885 DCHECK(!writer_->IsWriteBlocked()); |
882 | 886 |
883 WriteQueuedPackets(); | 887 WriteQueuedPackets(); |
884 WritePendingRetransmissions(); | 888 WritePendingRetransmissions(); |
885 | 889 |
886 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? | 890 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? |
887 IS_HANDSHAKE : NOT_HANDSHAKE; | 891 IS_HANDSHAKE : NOT_HANDSHAKE; |
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 // If we changed the generator's batch state, restore original batch state. | 1665 // If we changed the generator's batch state, restore original batch state. |
1662 if (!already_in_batch_mode_) { | 1666 if (!already_in_batch_mode_) { |
1663 DVLOG(1) << "Leaving Batch Mode."; | 1667 DVLOG(1) << "Leaving Batch Mode."; |
1664 connection_->packet_generator_.FinishBatchOperations(); | 1668 connection_->packet_generator_.FinishBatchOperations(); |
1665 } | 1669 } |
1666 DCHECK_EQ(already_in_batch_mode_, | 1670 DCHECK_EQ(already_in_batch_mode_, |
1667 connection_->packet_generator_.InBatchMode()); | 1671 connection_->packet_generator_.InBatchMode()); |
1668 } | 1672 } |
1669 | 1673 |
1670 } // namespace net | 1674 } // namespace net |
OLD | NEW |