diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 21:23:52 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 21:23:52 +0000 |
commit | 5c34371f362562220c1fc0772e1d93a37bcff02d (patch) | |
tree | aec820c9efc863fea9758fa450797a16ff191b3e /net/quic | |
parent | 31b2ae370ffd2c5dca8a639dd1cf6bb73718a62b (diff) | |
download | chromium_src-5c34371f362562220c1fc0772e1d93a37bcff02d.zip chromium_src-5c34371f362562220c1fc0772e1d93a37bcff02d.tar.gz chromium_src-5c34371f362562220c1fc0772e1d93a37bcff02d.tar.bz2 |
Land Recent QUIC Changes
Add varz to track QUIC packets and bytes sent by transmission type.
Not flag protected.
Merge internal change: 63037893
+ Updated QuicConnectionLogger to log TransmissionType.
+ Used connection_id instead of GUID in the comments.
+ Moved QUIC_SESSION_PACKET_SENT and QUIC_SESSION_PACKET_RETRANSMITTED
to match the log messages description.
https://codereview.chromium.org/196053008/
Killing off QUIC v14, which was never actually used.
Merge internal change: 63025464
https://codereview.chromium.org/198523002/
Adds a varz variable to track the fraction of times we end up in cubic
mode during congestion control.
Merge internal change: 62977386
https://codereview.chromium.org/198303004/
Export QUIC response retransmit packet and byte counts via faster stats.
Computation is done on a stream basis and ignores retransmitted control
packets.
Merge internal change: 62911712
https://codereview.chromium.org/197473012/
Avoiding a double disconnect scenario, and DFATALs on server.
Merge internal change: 62767600
https://codereview.chromium.org/198263003/
Making GOAWAY advisory for SPDY-over-QUIC.
Sending GOAWAYs on new connections when the server enters lame duck.
Making sure we only send a GOAWAY once on a given connection.
Merge internal change: 62700562
https://codereview.chromium.org/196343008/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/198353003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@256932 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic')
24 files changed, 209 insertions, 133 deletions
diff --git a/net/quic/congestion_control/cubic.cc b/net/quic/congestion_control/cubic.cc index 301512c..f64e58b 100644 --- a/net/quic/congestion_control/cubic.cc +++ b/net/quic/congestion_control/cubic.cc @@ -73,20 +73,18 @@ void Cubic::Reset() { void Cubic::UpdateCongestionControlStats( QuicTcpCongestionWindow new_cubic_mode_cwnd, QuicTcpCongestionWindow new_reno_mode_cwnd) { - if (last_congestion_window_ < new_cubic_mode_cwnd) { - // Congestion window will increase in cubic mode. - stats_->cwnd_increase_cubic_mode += new_cubic_mode_cwnd - - last_congestion_window_; - if (new_cubic_mode_cwnd <= new_reno_mode_cwnd) { - // Congestion window increase in reno mode is higher or equal to cubic - // mode's increase. - stats_->cwnd_increase_reno_mode += new_reno_mode_cwnd - - last_congestion_window_; + + QuicTcpCongestionWindow highest_new_cwnd = std::max(new_cubic_mode_cwnd, + new_reno_mode_cwnd); + if (last_congestion_window_ < highest_new_cwnd) { + // cwnd will increase to highest_new_cwnd. + stats_->cwnd_increase_congestion_avoidance += + highest_new_cwnd - last_congestion_window_; + if (new_cubic_mode_cwnd > new_reno_mode_cwnd) { + // This cwnd increase is due to cubic mode. + stats_->cwnd_increase_cubic_mode += + new_cubic_mode_cwnd - last_congestion_window_; } - } else if (last_congestion_window_ < new_reno_mode_cwnd) { - // No cwnd increase in cubic mode, but cwnd will increase in reno mode. - stats_->cwnd_increase_reno_mode += new_reno_mode_cwnd - - last_congestion_window_; } } diff --git a/net/quic/congestion_control/cubic_test.cc b/net/quic/congestion_control/cubic_test.cc index 730c1cc..915274a 100644 --- a/net/quic/congestion_control/cubic_test.cc +++ b/net/quic/congestion_control/cubic_test.cc @@ -89,13 +89,14 @@ TEST_F(CubicTest, CwndIncreaseStatsDuringConvexRegion) { // Advance current time so that cwnd update is allowed to happen by Cubic. clock_.AdvanceTime(hundred_ms_); current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); - EXPECT_NEAR(expected_cwnd - 10, stats_.cwnd_increase_reno_mode, 1); + EXPECT_NEAR(expected_cwnd - 10, stats_.cwnd_increase_congestion_avoidance, + 1); EXPECT_NEAR(1u, stats_.cwnd_increase_cubic_mode, 1); expected_cwnd++; } uint32 old_cwnd = current_cwnd; stats_.cwnd_increase_cubic_mode = 0; - stats_.cwnd_increase_reno_mode = 0; + stats_.cwnd_increase_congestion_avoidance = 0; // Testing Cubic mode increase. for (int i = 0; i < 52; ++i) { @@ -112,7 +113,8 @@ TEST_F(CubicTest, CwndIncreaseStatsDuringConvexRegion) { expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024; EXPECT_EQ(expected_cwnd - old_cwnd, stats_.cwnd_increase_cubic_mode); - EXPECT_EQ(0u, stats_.cwnd_increase_reno_mode); + EXPECT_EQ(expected_cwnd - old_cwnd, + stats_.cwnd_increase_congestion_avoidance); } @@ -150,7 +152,7 @@ TEST_F(CubicTest, BelowOrigin) { uint32 old_cwnd = current_cwnd; // Cubic phase. stats_.cwnd_increase_cubic_mode = 0; - stats_.cwnd_increase_reno_mode = 0; + stats_.cwnd_increase_congestion_avoidance = 0; for (int i = 0; i < 40 ; ++i) { clock_.AdvanceTime(hundred_ms_); current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); @@ -158,7 +160,8 @@ TEST_F(CubicTest, BelowOrigin) { expected_cwnd = 422; EXPECT_EQ(expected_cwnd, current_cwnd); EXPECT_EQ(expected_cwnd - old_cwnd, stats_.cwnd_increase_cubic_mode); - EXPECT_EQ(0u, stats_.cwnd_increase_reno_mode); + EXPECT_EQ(expected_cwnd - old_cwnd, + stats_.cwnd_increase_congestion_avoidance); } } // namespace test diff --git a/net/quic/quic_ack_notifier.cc b/net/quic/quic_ack_notifier.cc index 3301baf..be9881d 100644 --- a/net/quic/quic_ack_notifier.cc +++ b/net/quic/quic_ack_notifier.cc @@ -9,14 +9,28 @@ #include "base/logging.h" #include "base/stl_util.h" +using base::hash_map; +using std::make_pair; + namespace net { +QuicAckNotifier::PacketInfo::PacketInfo() : packet_payload_size(0) { +} + +QuicAckNotifier::PacketInfo::PacketInfo(int payload_size) + : packet_payload_size(payload_size) { +} + QuicAckNotifier::DelegateInterface::DelegateInterface() {} QuicAckNotifier::DelegateInterface::~DelegateInterface() {} QuicAckNotifier::QuicAckNotifier(DelegateInterface* delegate) - : delegate_(delegate) { + : delegate_(delegate), + original_packet_count_(0), + original_byte_count_(0), + retransmitted_packet_count_(0), + retransmitted_byte_count_(0) { DCHECK(delegate); } @@ -24,16 +38,12 @@ QuicAckNotifier::~QuicAckNotifier() { } void QuicAckNotifier::AddSequenceNumber( - const QuicPacketSequenceNumber& sequence_number) { - sequence_numbers_.insert(sequence_number); -} - -void QuicAckNotifier::AddSequenceNumbers( - const SequenceNumberSet& sequence_numbers) { - for (SequenceNumberSet::const_iterator it = sequence_numbers.begin(); - it != sequence_numbers.end(); ++it) { - AddSequenceNumber(*it); - } + const QuicPacketSequenceNumber& sequence_number, + int packet_payload_size) { + sequence_numbers_.insert(make_pair(sequence_number, + PacketInfo(packet_payload_size))); + ++original_packet_count_; + original_byte_count_ += packet_payload_size; } bool QuicAckNotifier::OnAck(QuicPacketSequenceNumber sequence_number) { @@ -42,7 +52,9 @@ bool QuicAckNotifier::OnAck(QuicPacketSequenceNumber sequence_number) { if (IsEmpty()) { // We have seen all the sequence numbers we were waiting for, trigger // callback notification. - delegate_->OnAckNotification(); + delegate_->OnAckNotification( + original_packet_count_, original_byte_count_, + retransmitted_packet_count_, retransmitted_byte_count_); return true; } return false; @@ -51,8 +63,21 @@ bool QuicAckNotifier::OnAck(QuicPacketSequenceNumber sequence_number) { void QuicAckNotifier::UpdateSequenceNumber( QuicPacketSequenceNumber old_sequence_number, QuicPacketSequenceNumber new_sequence_number) { - sequence_numbers_.erase(old_sequence_number); - sequence_numbers_.insert(new_sequence_number); + DCHECK(!ContainsKey(sequence_numbers_, new_sequence_number)); + + PacketInfo packet_info; + hash_map<QuicPacketSequenceNumber, PacketInfo>::iterator it = + sequence_numbers_.find(old_sequence_number); + if (it != sequence_numbers_.end()) { + packet_info = it->second; + sequence_numbers_.erase(it); + } else { + DLOG(DFATAL) << "Old sequence number not found."; + } + + ++retransmitted_packet_count_; + retransmitted_byte_count_ += packet_info.packet_payload_size; + sequence_numbers_.insert(make_pair(new_sequence_number, packet_info)); } }; // namespace net diff --git a/net/quic/quic_ack_notifier.h b/net/quic/quic_ack_notifier.h index 48c8375..a771930 100644 --- a/net/quic/quic_ack_notifier.h +++ b/net/quic/quic_ack_notifier.h @@ -21,8 +21,16 @@ class NET_EXPORT_PRIVATE QuicAckNotifier { : public base::RefCounted<DelegateInterface> { public: DelegateInterface(); - virtual void OnAckNotification() = 0; - + // Args: + // num_original_packets - Number of packets in the original transmission. + // num_original_bytes - Number of packets in the original transmission. + // num_retransmitted_packets - Number of packets that had to be + // retransmitted. + // num_retransmitted_bytes - Number of bytes that had to be retransmitted. + virtual void OnAckNotification(int num_original_packets, + int num_original_bytes, + int num_retransmitted_packets, + int num_retransmitted_bytes) = 0; protected: friend class base::RefCounted<DelegateInterface>; @@ -35,11 +43,8 @@ class NET_EXPORT_PRIVATE QuicAckNotifier { virtual ~QuicAckNotifier(); // Register a sequence number that this AckNotifier should be interested in. - void AddSequenceNumber(const QuicPacketSequenceNumber& sequence_number); - - // Register a set of sequence numbers that this AckNotifier should be - // interested in. - void AddSequenceNumbers(const SequenceNumberSet& sequence_numbers); + void AddSequenceNumber(const QuicPacketSequenceNumber& sequence_number, + int packet_payload_size); // Called by the QuicConnection on receipt of new ACK frame, with the sequence // number referenced by the ACK frame. @@ -60,14 +65,31 @@ class NET_EXPORT_PRIVATE QuicAckNotifier { QuicPacketSequenceNumber new_sequence_number); private: + struct PacketInfo { + PacketInfo(); + explicit PacketInfo(int payload_size); + + int packet_payload_size; + }; + // The delegate's OnAckNotification() method will be called once we have been // notified of ACKs for all the sequence numbers we are tracking. // This is not owned by OnAckNotifier and must outlive it. scoped_refptr<DelegateInterface> delegate_; - // Set of sequence numbers this notifier is waiting to hear about. The - // delegate will not be called until this is an empty set. - SequenceNumberSet sequence_numbers_; + // Sequence numbers this notifier is waiting to hear about. The + // delegate will not be called until this is empty. + base::hash_map<QuicPacketSequenceNumber, PacketInfo> sequence_numbers_; + + // Transmission and retransmission stats. + // Number of packets in the original transmission. + int original_packet_count_; + // Number of packets in the original transmission. + int original_byte_count_; + // Number of packets that had to be retransmitted. + int retransmitted_packet_count_; + // Number of bytes that had to be retransmitted. + int retransmitted_byte_count_; }; }; // namespace net diff --git a/net/quic/quic_ack_notifier_manager.cc b/net/quic/quic_ack_notifier_manager.cc index 8676315..0dd8a76 100644 --- a/net/quic/quic_ack_notifier_manager.cc +++ b/net/quic/quic_ack_notifier_manager.cc @@ -90,7 +90,8 @@ void AckNotifierManager::OnSerializedPacket( // The AckNotifier needs to know it is tracking this packet's sequence // number. - notifier->AddSequenceNumber(serialized_packet.sequence_number); + notifier->AddSequenceNumber(serialized_packet.sequence_number, + serialized_packet.packet->length()); // Update the mapping in the other direction, from sequence // number to AckNotifier. diff --git a/net/quic/quic_ack_notifier_test.cc b/net/quic/quic_ack_notifier_test.cc index c846d39..c05e63e 100644 --- a/net/quic/quic_ack_notifier_test.cc +++ b/net/quic/quic_ack_notifier_test.cc @@ -8,6 +8,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::_; + namespace net { namespace test { namespace { @@ -18,20 +20,18 @@ class QuicAckNotifierTest : public ::testing::Test { delegate_ = new MockAckNotifierDelegate; notifier_.reset(new QuicAckNotifier(delegate_)); - sequence_numbers_.insert(26); - sequence_numbers_.insert(99); - sequence_numbers_.insert(1234); - notifier_->AddSequenceNumbers(sequence_numbers_); + notifier_->AddSequenceNumber(26, 100); + notifier_->AddSequenceNumber(99, 20); + notifier_->AddSequenceNumber(1234, 3); } - SequenceNumberSet sequence_numbers_; MockAckNotifierDelegate* delegate_; scoped_ptr<QuicAckNotifier> notifier_; }; // Should trigger callback when we receive acks for all the registered seqnums. TEST_F(QuicAckNotifierTest, TriggerCallback) { - EXPECT_CALL(*delegate_, OnAckNotification()).Times(1); + EXPECT_CALL(*delegate_, OnAckNotification(3, 123, 0, 0)).Times(1); EXPECT_FALSE(notifier_->OnAck(26)); EXPECT_FALSE(notifier_->OnAck(99)); EXPECT_TRUE(notifier_->OnAck(1234)); @@ -40,7 +40,7 @@ TEST_F(QuicAckNotifierTest, TriggerCallback) { // Should not trigger callback if we never provide all the seqnums. TEST_F(QuicAckNotifierTest, DoesNotTrigger) { // Should not trigger callback as not all packets have been seen. - EXPECT_CALL(*delegate_, OnAckNotification()).Times(0); + EXPECT_CALL(*delegate_, OnAckNotification(_, _, _, _)).Times(0); EXPECT_FALSE(notifier_->OnAck(26)); EXPECT_FALSE(notifier_->OnAck(99)); } @@ -52,7 +52,7 @@ TEST_F(QuicAckNotifierTest, UpdateSeqNums) { notifier_->UpdateSequenceNumber(99, 3000); notifier_->UpdateSequenceNumber(1234, 3001); - EXPECT_CALL(*delegate_, OnAckNotification()).Times(1); + EXPECT_CALL(*delegate_, OnAckNotification(3, 123, 2, 20 + 3)).Times(1); EXPECT_FALSE(notifier_->OnAck(26)); // original EXPECT_FALSE(notifier_->OnAck(3000)); // updated EXPECT_TRUE(notifier_->OnAck(3001)); // updated diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index 273f4f5..dce0ca1 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -389,8 +389,7 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { debug_visitor_->OnPacketHeader(header); } - if (header.fec_flag && framer_.version() <= QUIC_VERSION_14) { - DLOG(WARNING) << "Ignoring FEC packets for versions prior to 15."; + if (header.fec_flag && framer_.version() == QUIC_VERSION_13) { return false; } @@ -1301,8 +1300,11 @@ bool QuicConnection::WritePacket(QueuedPacket packet) { } if (debug_visitor_) { // Pass the write result to the visitor. - debug_visitor_->OnPacketSent( - sequence_number, packet.encryption_level, *encrypted, result); + debug_visitor_->OnPacketSent(sequence_number, + packet.encryption_level, + packet.transmission_type, + *encrypted, + result); } if (result.status == WRITE_STATUS_BLOCKED) { visitor_->OnWriteBlocked(); @@ -1618,7 +1620,12 @@ void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, // If we're write blocked, WritePacket() will not send, but will capture the // serialized packet. SendConnectionClosePacket(error, details); - CloseConnection(error, false); + if (connected_) { + // It's possible that while sending the connection close packet, we get a + // socket error and disconnect right then and there. Avoid a double + // disconnect in that case. + CloseConnection(error, false); + } } void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index 99cc591..f42b5a7 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h @@ -116,59 +116,60 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitorInterface // Called when a packet has been sent. virtual void OnPacketSent(QuicPacketSequenceNumber sequence_number, EncryptionLevel level, + TransmissionType transmission_type, const QuicEncryptedPacket& packet, - WriteResult result) = 0; + WriteResult result) {} // Called when the contents of a packet have been retransmitted as // a new packet. virtual void OnPacketRetransmitted( QuicPacketSequenceNumber old_sequence_number, - QuicPacketSequenceNumber new_sequence_number) = 0; + QuicPacketSequenceNumber new_sequence_number) {} // Called when a packet has been received, but before it is // validated or parsed. virtual void OnPacketReceived(const IPEndPoint& self_address, const IPEndPoint& peer_address, - const QuicEncryptedPacket& packet) = 0; + const QuicEncryptedPacket& packet) {} // Called when the protocol version on the received packet doensn't match // current protocol version of the connection. - virtual void OnProtocolVersionMismatch(QuicVersion version) = 0; + virtual void OnProtocolVersionMismatch(QuicVersion version) {} // Called when the complete header of a packet has been parsed. - virtual void OnPacketHeader(const QuicPacketHeader& header) = 0; + virtual void OnPacketHeader(const QuicPacketHeader& header) {} // Called when a StreamFrame has been parsed. - virtual void OnStreamFrame(const QuicStreamFrame& frame) = 0; + virtual void OnStreamFrame(const QuicStreamFrame& frame) {} // Called when a AckFrame has been parsed. - virtual void OnAckFrame(const QuicAckFrame& frame) = 0; + virtual void OnAckFrame(const QuicAckFrame& frame) {} // Called when a CongestionFeedbackFrame has been parsed. virtual void OnCongestionFeedbackFrame( - const QuicCongestionFeedbackFrame& frame) = 0; + const QuicCongestionFeedbackFrame& frame) {} // Called when a StopWaitingFrame has been parsed. - virtual void OnStopWaitingFrame(const QuicStopWaitingFrame& frame) = 0; + virtual void OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {} // Called when a RstStreamFrame has been parsed. - virtual void OnRstStreamFrame(const QuicRstStreamFrame& frame) = 0; + virtual void OnRstStreamFrame(const QuicRstStreamFrame& frame) {} // Called when a ConnectionCloseFrame has been parsed. virtual void OnConnectionCloseFrame( - const QuicConnectionCloseFrame& frame) = 0; + const QuicConnectionCloseFrame& frame) {} // Called when a public reset packet has been received. - virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) = 0; + virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) {} // Called when a version negotiation packet has been received. virtual void OnVersionNegotiationPacket( - const QuicVersionNegotiationPacket& packet) = 0; + const QuicVersionNegotiationPacket& packet) {} // Called after a packet has been successfully parsed which results // in the revival of a packet via FEC. virtual void OnRevivedPacket(const QuicPacketHeader& revived_header, - base::StringPiece payload) = 0; + base::StringPiece payload) {} }; class NET_EXPORT_PRIVATE QuicConnectionHelperInterface { diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc index 31fc4df..1ff5a8c 100644 --- a/net/quic/quic_connection_logger.cc +++ b/net/quic/quic_connection_logger.cc @@ -41,11 +41,13 @@ base::Value* NetLogQuicPacketCallback(const IPEndPoint* self_address, base::Value* NetLogQuicPacketSentCallback( QuicPacketSequenceNumber sequence_number, EncryptionLevel level, + TransmissionType transmission_type, size_t packet_size, WriteResult result, NetLog::LogLevel /* log_level */) { base::DictionaryValue* dict = new base::DictionaryValue(); dict->SetInteger("encryption_level", level); + dict->SetInteger("transmission_type", transmission_type); dict->SetString("packet_sequence_number", base::Uint64ToString(sequence_number)); dict->SetInteger("size", packet_size); @@ -378,12 +380,13 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) { void QuicConnectionLogger::OnPacketSent( QuicPacketSequenceNumber sequence_number, EncryptionLevel level, + TransmissionType transmission_type, const QuicEncryptedPacket& packet, WriteResult result) { net_log_.AddEvent( NetLog::TYPE_QUIC_SESSION_PACKET_SENT, base::Bind(&NetLogQuicPacketSentCallback, sequence_number, level, - packet.length(), result)); + transmission_type, packet.length(), result)); } void QuicConnectionLogger:: OnPacketRetransmitted( diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h index cd7f4dc..9fada58 100644 --- a/net/quic/quic_connection_logger.h +++ b/net/quic/quic_connection_logger.h @@ -31,6 +31,7 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger // QuicConnectionDebugVisitorInterface virtual void OnPacketSent(QuicPacketSequenceNumber sequence_number, EncryptionLevel level, + TransmissionType transmission_type, const QuicEncryptedPacket& packet, WriteResult result) OVERRIDE; virtual void OnPacketRetransmitted( diff --git a/net/quic/quic_connection_stats.cc b/net/quic/quic_connection_stats.cc index 324ea42..284ecce 100644 --- a/net/quic/quic_connection_stats.cc +++ b/net/quic/quic_connection_stats.cc @@ -27,8 +27,8 @@ QuicConnectionStats::QuicConnectionStats() rto_count(0), rtt(0), estimated_bandwidth(0), - cwnd_increase_cubic_mode(0), - cwnd_increase_reno_mode(0) { + cwnd_increase_congestion_avoidance(0), + cwnd_increase_cubic_mode(0) { } QuicConnectionStats::~QuicConnectionStats() {} @@ -52,10 +52,10 @@ ostream& operator<<(ostream& os, const QuicConnectionStats& s) { << ", tlp count: " << s.tlp_count << ", rtt(us): " << s.rtt << ", estimated_bandwidth: " << s.estimated_bandwidth + << ", total amount of cwnd increase in TCPCubic, in congestion avoidance: " + << s.cwnd_increase_congestion_avoidance << ", amount of cwnd increase in TCPCubic, in cubic mode: " << s.cwnd_increase_cubic_mode - << ", amount of cwnd increase in TCPCubic, matched by or in reno mode: " - << s.cwnd_increase_reno_mode << "}\n"; return os; } diff --git a/net/quic/quic_connection_stats.h b/net/quic/quic_connection_stats.h index d2ff52a..dffae31 100644 --- a/net/quic/quic_connection_stats.h +++ b/net/quic/quic_connection_stats.h @@ -55,12 +55,10 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats { uint64 estimated_bandwidth; // The following stats are used only in TcpCubicSender. + // Total amount of cwnd increase by TCPCubic in congestion avoidance. + uint32 cwnd_increase_congestion_avoidance; // Total amount of cwnd increase by TCPCubic in cubic mode. uint32 cwnd_increase_cubic_mode; - // Total amount of cwnd increase by TCPCubic in reno mode. This includes - // cwnd increases that actually happened in cubic mode, but where reno mode - // would have yielded the same increase. - uint32 cwnd_increase_reno_mode; // TODO(satyamshekhar): Add window_size, mss and mtu. }; diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index 19edfd0..01c4020 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -3011,7 +3011,7 @@ TEST_P(QuicConnectionTest, GoAway) { } TEST_P(QuicConnectionTest, WindowUpdate) { - if (version() < QUIC_VERSION_14) { + if (version() == QUIC_VERSION_13) { return; } EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); @@ -3024,7 +3024,7 @@ TEST_P(QuicConnectionTest, WindowUpdate) { } TEST_P(QuicConnectionTest, Blocked) { - if (version() < QUIC_VERSION_14) { + if (version() == QUIC_VERSION_13) { return; } EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); @@ -3599,7 +3599,7 @@ TEST_P(QuicConnectionTest, AckNotifierTriggerCallback) { // Create a delegate which we expect to be called. scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate); - EXPECT_CALL(*delegate, OnAckNotification()).Times(1); + EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _)).Times(1); // Send some data, which will register the delegate to be notified. connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get()); @@ -3616,7 +3616,7 @@ TEST_P(QuicConnectionTest, AckNotifierFailToTriggerCallback) { // Create a delegate which we don't expect to be called. scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate); - EXPECT_CALL(*delegate, OnAckNotification()).Times(0); + EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _)).Times(0); EXPECT_CALL(*send_algorithm_, UpdateRtt(_)); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(2); @@ -3647,7 +3647,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) { // Create a delegate which we expect to be called. scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate); - EXPECT_CALL(*delegate, OnAckNotification()).Times(1); + EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _)).Times(1); // Send four packets, and register to be notified on ACK of packet 2. connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); @@ -3690,7 +3690,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) { // Create a delegate which we expect to be called. scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate); - EXPECT_CALL(*delegate, OnAckNotification()).Times(1); + EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _)).Times(1); // Expect ACKs for 1 packet. EXPECT_CALL(*send_algorithm_, UpdateRtt(_)); @@ -3733,9 +3733,10 @@ class MockQuicConnectionDebugVisitor MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&)); - MOCK_METHOD4(OnPacketSent, + MOCK_METHOD5(OnPacketSent, void(QuicPacketSequenceNumber, EncryptionLevel, + TransmissionType, const QuicEncryptedPacket&, WriteResult)); @@ -3804,7 +3805,7 @@ TEST_P(QuicConnectionTest, Pacing) { } TEST_P(QuicConnectionTest, ControlFramesInstigateAcks) { - if (version() < QUIC_VERSION_14) { + if (version() == QUIC_VERSION_13) { return; } EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc index d30a9b7..c25926e 100644 --- a/net/quic/quic_framer.cc +++ b/net/quic/quic_framer.cc @@ -1428,7 +1428,7 @@ bool QuicFramer::ProcessReceivedInfo(uint8 frame_type, last_sequence_number -= (range_length + 1); } - if (quic_version_ > QUIC_VERSION_14) { + if (quic_version_ != QUIC_VERSION_13) { // Parse the revived packets list. uint8 num_revived_packets; if (!reader_->ReadBytes(&num_revived_packets, 1)) { @@ -1485,7 +1485,7 @@ bool QuicFramer::ProcessQuicCongestionFeedbackFrame( case kInterArrival: { CongestionFeedbackMessageInterArrival* inter_arrival = &frame->inter_arrival; - if (quic_version_ <= QUIC_VERSION_14) { + if (quic_version_ == QUIC_VERSION_13) { uint16 unused_accumulated_number_of_lost_packets; if (!reader_->ReadUInt16( &unused_accumulated_number_of_lost_packets)) { @@ -1552,7 +1552,7 @@ bool QuicFramer::ProcessQuicCongestionFeedbackFrame( } case kTCP: { CongestionFeedbackMessageTCP* tcp = &frame->tcp; - if (quic_version_ <= QUIC_VERSION_14) { + if (quic_version_ == QUIC_VERSION_13) { uint16 unused_accumulated_number_of_lost_packets; if (!reader_->ReadUInt16(&unused_accumulated_number_of_lost_packets)) { set_detailed_error( @@ -1849,7 +1849,7 @@ size_t QuicFramer::GetAckFrameSize( largest_observed_length); if (!ack_info.nack_ranges.empty()) { ack_size += kNumberOfMissingPacketsSize + - (quic_version_ <= QUIC_VERSION_14 ? 0 : kNumberOfRevivedPacketsSize); + (quic_version_ == QUIC_VERSION_13 ? 0 : kNumberOfRevivedPacketsSize); ack_size += ack_info.nack_ranges.size() * (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER); ack_size += @@ -1882,7 +1882,7 @@ size_t QuicFramer::ComputeFrameLength( case kInterArrival: { const CongestionFeedbackMessageInterArrival& inter_arrival = congestion_feedback.inter_arrival; - if (quic_version_ <= QUIC_VERSION_14) { + if (quic_version_ == QUIC_VERSION_13) { len += 2; // Accumulated number of lost packets. } len += 1; // Number received packets. @@ -1899,7 +1899,7 @@ size_t QuicFramer::ComputeFrameLength( len += 4; // Bitrate. break; case kTCP: - if (quic_version_ <= QUIC_VERSION_14) { + if (quic_version_ == QUIC_VERSION_13) { len += 2; // Accumulated number of lost packets. } len += 2; // Receive window. @@ -2059,7 +2059,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte( GetMinAckFrameSize(quic_version_, header.public_header.sequence_number_length, largest_observed_length) - - (quic_version_ <= QUIC_VERSION_14 ? 0 : kNumberOfRevivedPacketsSize); + (quic_version_ == QUIC_VERSION_13 ? 0 : kNumberOfRevivedPacketsSize); size_t max_num_ranges = available_range_bytes / (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER); max_num_ranges = @@ -2168,7 +2168,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte( } DCHECK_EQ(num_missing_ranges, num_ranges_written); - if (quic_version_ > QUIC_VERSION_14) { + if (quic_version_ != QUIC_VERSION_13) { // Append revived packets. // If not all the revived packets fit, only mention the ones that do. uint8 num_revived_packets = @@ -2206,7 +2206,7 @@ bool QuicFramer::AppendCongestionFeedbackFrame( case kInterArrival: { const CongestionFeedbackMessageInterArrival& inter_arrival = frame.inter_arrival; - if (quic_version_ <= QUIC_VERSION_14) { + if (quic_version_ == QUIC_VERSION_13) { // accumulated_number_of_lost_packets is removed. Always write 0. if (!writer->WriteUInt16(0)) { return false; @@ -2272,7 +2272,7 @@ bool QuicFramer::AppendCongestionFeedbackFrame( DCHECK_LE(tcp.receive_window, 1u << 20); // Simple bit packing, don't send the 4 least significant bits. uint16 receive_window = static_cast<uint16>(tcp.receive_window >> 4); - if (quic_version_ <= QUIC_VERSION_14) { + if (quic_version_ == QUIC_VERSION_13) { // accumulated_number_of_lost_packets is removed. Always write 0. if (!writer->WriteUInt16(0)) { return false; diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc index 84f1cdf..43c2984 100644 --- a/net/quic/quic_framer_test.cc +++ b/net/quic/quic_framer_test.cc @@ -1674,8 +1674,8 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) { CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); } -TEST_P(QuicFramerTest, AckFrameV14) { - if (framer_.version() > QUIC_VERSION_14) { +TEST_P(QuicFramerTest, AckFrameV13) { + if (framer_.version() != QUIC_VERSION_13) { return; } @@ -2475,8 +2475,8 @@ TEST_P(QuicFramerTest, AckFrame500Nacks15) { AsChars(packet), arraysize(packet)); } -TEST_P(QuicFramerTest, AckFrame500NacksV14) { - if (framer_.version() > QUIC_VERSION_14) { +TEST_P(QuicFramerTest, AckFrame500NacksV13) { + if (framer_.version() != QUIC_VERSION_13) { return; } unsigned char packet[] = { @@ -2555,7 +2555,7 @@ TEST_P(QuicFramerTest, AckFrame500NacksV14) { } TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) { - if (framer_.version() <= QUIC_VERSION_14) { + if (framer_.version() == QUIC_VERSION_13) { return; } unsigned char packet[] = { @@ -2608,8 +2608,8 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) { } } -TEST_P(QuicFramerTest, CongestionFeedbackFrameTCPV14) { - if (framer_.version() > QUIC_VERSION_14) { +TEST_P(QuicFramerTest, CongestionFeedbackFrameTCPV13) { + if (framer_.version() != QUIC_VERSION_13) { return; } unsigned char packet[] = { @@ -2667,7 +2667,7 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameTCPV14) { } TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrival) { - if (framer_.version() <= QUIC_VERSION_14) { + if (framer_.version() == QUIC_VERSION_13) { return; } unsigned char packet[] = { @@ -2759,8 +2759,8 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrival) { } } -TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrivalV14) { - if (framer_.version() > QUIC_VERSION_14) { +TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrivalV13) { + if (framer_.version() != QUIC_VERSION_13) { return; } unsigned char packet[] = { @@ -4111,8 +4111,8 @@ TEST_P(QuicFramerTest, BuildAckFramePacket15) { AsChars(packet), arraysize(packet)); } -TEST_P(QuicFramerTest, BuildAckFramePacketV14) { - if (version_ > QUIC_VERSION_14) { +TEST_P(QuicFramerTest, BuildAckFramePacketV13) { + if (version_ != QUIC_VERSION_13) { return; } QuicPacketHeader header; @@ -4181,7 +4181,7 @@ TEST_P(QuicFramerTest, BuildAckFramePacketV14) { } TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCP) { - if (version_ <= QUIC_VERSION_14) { + if (version_ == QUIC_VERSION_13) { return; } QuicPacketHeader header; @@ -4229,8 +4229,8 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCP) { AsChars(packet), arraysize(packet)); } -TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCPV14) { - if (version_ > QUIC_VERSION_14) { +TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCPV13) { + if (version_ != QUIC_VERSION_13) { return; } QuicPacketHeader header; @@ -4281,7 +4281,7 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCPV14) { } TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrival) { - if (version_ <= QUIC_VERSION_14) { + if (version_ == QUIC_VERSION_13) { return; } QuicPacketHeader header; @@ -4353,8 +4353,8 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrival) { AsChars(packet), arraysize(packet)); } -TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrivalV14) { - if (version_ > QUIC_VERSION_14) { +TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrivalV13) { + if (version_ != QUIC_VERSION_13) { return; } QuicPacketHeader header; diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc index 9d47256..97c4c18 100644 --- a/net/quic/quic_packet_creator.cc +++ b/net/quic/quic_packet_creator.cc @@ -90,7 +90,7 @@ bool QuicPacketCreator::ShouldSendFec(bool force_close) const { void QuicPacketCreator::MaybeStartFEC() { // Don't send FEC until QUIC_VERSION_15. - if (framer_->version() > QUIC_VERSION_14 && + if (framer_->version() != QUIC_VERSION_13 && options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) { DCHECK(queued_frames_.empty()); // Set the fec group number to the sequence number of the next packet. diff --git a/net/quic/quic_packet_generator.h b/net/quic/quic_packet_generator.h index 1434451..12caf34 100644 --- a/net/quic/quic_packet_generator.h +++ b/net/quic/quic_packet_generator.h @@ -83,7 +83,7 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator { virtual ~DebugDelegateInterface() {} // Called when a frame has been added to the current packet. - virtual void OnFrameAddedToPacket(const QuicFrame& frame) = 0; + virtual void OnFrameAddedToPacket(const QuicFrame& frame) {} }; QuicPacketGenerator(DelegateInterface* delegate, diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc index c601659..f98af28 100644 --- a/net/quic/quic_protocol.cc +++ b/net/quic/quic_protocol.cc @@ -156,8 +156,6 @@ QuicTag QuicVersionToQuicTag(const QuicVersion version) { switch (version) { case QUIC_VERSION_13: return MakeQuicTag('Q', '0', '1', '3'); - case QUIC_VERSION_14: - return MakeQuicTag('Q', '0', '1', '4'); case QUIC_VERSION_15: return MakeQuicTag('Q', '0', '1', '5'); case QUIC_VERSION_16: @@ -189,7 +187,6 @@ return #x string QuicVersionToString(const QuicVersion version) { switch (version) { RETURN_STRING_LITERAL(QUIC_VERSION_13); - RETURN_STRING_LITERAL(QUIC_VERSION_14); RETURN_STRING_LITERAL(QUIC_VERSION_15); RETURN_STRING_LITERAL(QUIC_VERSION_16); default: diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h index 2e5a921..7f4392e 100644 --- a/net/quic/quic_protocol.h +++ b/net/quic/quic_protocol.h @@ -254,7 +254,6 @@ enum QuicVersion { QUIC_VERSION_UNSUPPORTED = 0, QUIC_VERSION_13 = 13, - QUIC_VERSION_14 = 14, QUIC_VERSION_15 = 15, QUIC_VERSION_16 = 16, // Current version. }; @@ -268,7 +267,6 @@ enum QuicVersion { // http://sites/quic/adding-and-removing-versions static const QuicVersion kSupportedQuicVersions[] = {QUIC_VERSION_16, QUIC_VERSION_15, - QUIC_VERSION_14, QUIC_VERSION_13}; typedef std::vector<QuicVersion> QuicVersionVector; diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc index b84eb6a..96fd30b 100644 --- a/net/quic/quic_session.cc +++ b/net/quic/quic_session.cc @@ -320,6 +320,9 @@ void QuicSession::SendRstStream(QuicStreamId id, } void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) { + if (goaway_sent_) { + return; + } goaway_sent_ = true; connection_->SendGoAway(error_code, largest_peer_created_stream_id_, reason); } @@ -457,12 +460,6 @@ QuicDataStream* QuicSession::GetIncomingDataStream(QuicStreamId stream_id) { return NULL; } - if (goaway_sent_) { - // We've already sent a GoAway - SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0); - return NULL; - } - implicitly_created_streams_.erase(stream_id); if (stream_id > largest_peer_created_stream_id_) { // TODO(rch) add unit test for this diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc index daf36ae..54c6cbb 100644 --- a/net/quic/quic_session_test.cc +++ b/net/quic/quic_session_test.cc @@ -427,15 +427,22 @@ TEST_P(QuicSessionTest, OnCanWriteWithClosedStream) { } TEST_P(QuicSessionTest, SendGoAway) { - // After sending a GoAway, ensure new incoming streams cannot be created and - // result in a RST being sent. EXPECT_CALL(*connection_, SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); EXPECT_TRUE(session_.goaway_sent()); - EXPECT_CALL(*connection_, SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)); - EXPECT_FALSE(session_.GetIncomingDataStream(3u)); + EXPECT_CALL(*connection_, + SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); + EXPECT_TRUE(session_.GetIncomingDataStream(3u)); +} + +TEST_P(QuicSessionTest, DoNotSendGoAwayTwice) { + EXPECT_CALL(*connection_, + SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")).Times(1); + session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); + EXPECT_TRUE(session_.goaway_sent()); + session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); } TEST_P(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) { diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc index 782b3bc..62524f9 100644 --- a/net/quic/quic_utils.cc +++ b/net/quic/quic_utils.cc @@ -231,6 +231,17 @@ const char* QuicUtils::EncryptionLevelToString(EncryptionLevel level) { } // static +const char* QuicUtils::TransmissionTypeToString(TransmissionType type) { + switch (type) { + RETURN_STRING_LITERAL(NOT_RETRANSMISSION); + RETURN_STRING_LITERAL(NACK_RETRANSMISSION); + RETURN_STRING_LITERAL(RTO_RETRANSMISSION); + RETURN_STRING_LITERAL(TLP_RETRANSMISSION); + } + return "INVALID_TRANSMISSION_TYPE"; +} + +// static string QuicUtils::TagToString(QuicTag tag) { char chars[4]; bool ascii = true; diff --git a/net/quic/quic_utils.h b/net/quic/quic_utils.h index 05d88ca..39a9a5c 100644 --- a/net/quic/quic_utils.h +++ b/net/quic/quic_utils.h @@ -59,6 +59,9 @@ class NET_EXPORT_PRIVATE QuicUtils { // Returns the level of encryption as a char* static const char* EncryptionLevelToString(EncryptionLevel level); + // Returns TransmissionType as a char* + static const char* TransmissionTypeToString(TransmissionType type); + // TagToString is a utility function for pretty-printing handshake messages // that converts a tag to a string. It will try to maintain the human friendly // name if possible (i.e. kABCD -> "ABCD"), or will just treat it as a number diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index 0199e68..f6e188a 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h @@ -486,7 +486,10 @@ class MockAckNotifierDelegate : public QuicAckNotifier::DelegateInterface { public: MockAckNotifierDelegate(); - MOCK_METHOD0(OnAckNotification, void()); + MOCK_METHOD4(OnAckNotification, void(int num_original_packets, + int num_original_bytes, + int num_retransmitted_packets, + int num_retransmitted_bytes)); protected: // Object is ref counted. |