diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-16 19:42:03 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-16 19:42:03 +0000 |
commit | c05a6d22e32698902910edae7561b94bb4886d23 (patch) | |
tree | f0228df6bbca9a7a97ff95712d8045c5be405618 /net/quic | |
parent | 619d2b1416d4b12bc8c91f94296f51e53f787f0c (diff) | |
download | chromium_src-c05a6d22e32698902910edae7561b94bb4886d23.zip chromium_src-c05a6d22e32698902910edae7561b94bb4886d23.tar.gz chromium_src-c05a6d22e32698902910edae7561b94bb4886d23.tar.bz2 |
Land Recent QUIC Changes.
Add convenience HighestPriority and LowestPriority methods to QuicUtils
Merge internal change: 58122394
https://codereview.chromium.org/112463003/
Change QUIC to only ack every other packet when there are no losses
within the last four received packets.
Merge internal change: 58111242
https://codereview.chromium.org/113123004/
Add a version() convenience method to ReliableQuicStream.
Merge internal change: 58110960
https://codereview.chromium.org/112273003/
Fix two tests that fail when FLAGS_enable_quic_pacing is enabled
Merge internal change: 58101756
https://codereview.chromium.org/115393003/
Remove deprecated flag FLAGS_pad_quic_handshake_packets.
Merge internal change: 58101024
https://codereview.chromium.org/114923007/
Remove the is_server argument from the QuicSession constructor.
In a previous CL, I removed this from TestSession, but I missed, that
it's an argument of the main QuicSession constructor.
Merge internal change: 58059515
https://codereview.chromium.org/102313005/
Fix QUIC's TCP style retransmission logic to only send a maximum of 2
packets per incoming ack instead of 10.
Merge internal change: 58059328
https://codereview.chromium.org/109993008/
Remove redundant |is_server| argument from TestSession and call the
connection's is_server() method instead.
Merge internal change: 58047118
https://codereview.chromium.org/110373004/
Minor cleanup of QUIC MockConnection and PacketSavingConnection
constructors.
Merge internal change: 58042657
https://codereview.chromium.org/114933003/
Cleanup in QUIC to merge the previous_transmissions_map in
QuicSentPacketManager with the unacked_packets map.
Merge internal change: 58011531
https://codereview.chromium.org/109323012/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/115463002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240972 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic')
33 files changed, 277 insertions, 259 deletions
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc index e4a7df0..ab70e7f 100644 --- a/net/quic/quic_client_session.cc +++ b/net/quic/quic_client_session.cc @@ -90,7 +90,7 @@ QuicClientSession::QuicClientSession( const QuicConfig& config, QuicCryptoClientConfig* crypto_config, NetLog* net_log) - : QuicSession(connection, config, false), + : QuicSession(connection, config), require_confirmation_(false), stream_factory_(stream_factory), socket_(socket.Pass()), diff --git a/net/quic/quic_client_session_test.cc b/net/quic/quic_client_session_test.cc index f18f71b..f0b4dd4 100644 --- a/net/quic/quic_client_session_test.cc +++ b/net/quic/quic_client_session_test.cc @@ -64,9 +64,8 @@ class TestPacketWriter : public QuicDefaultPacketWriter { class QuicClientSessionTest : public ::testing::Test { protected: QuicClientSessionTest() - : guid_(1), - writer_(new TestPacketWriter()), - connection_(new PacketSavingConnection(guid_, IPEndPoint(), false)), + : writer_(new TestPacketWriter()), + connection_(new PacketSavingConnection(false)), session_(connection_, GetSocket().Pass(), writer_.Pass(), NULL, NULL, kServerHostname, DefaultQuicConfig(), &crypto_config_, &net_log_) { @@ -93,7 +92,6 @@ class QuicClientSessionTest : public ::testing::Test { ASSERT_EQ(OK, callback_.WaitForResult()); } - QuicGuid guid_; scoped_ptr<QuicDefaultPacketWriter> writer_; PacketSavingConnection* connection_; CapturingNetLog net_log_; diff --git a/net/quic/quic_config_test.cc b/net/quic/quic_config_test.cc index 401fa47..2434cd7 100644 --- a/net/quic/quic_config_test.cc +++ b/net/quic/quic_config_test.cc @@ -29,6 +29,8 @@ class QuicConfigTest : public ::testing::Test { }; TEST_F(QuicConfigTest, ToHandshakeMessage) { + FLAGS_enable_quic_pacing = false; + config_.SetDefaults(); config_.set_idle_connection_state_lifetime(QuicTime::Delta::FromSeconds(5), QuicTime::Delta::FromSeconds(2)); config_.set_max_streams_per_connection(4, 2); diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index b93fdee..51a83cc 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -659,11 +659,9 @@ void QuicConnection::OnPacketComplete() { // from unacket_packets_, increasing the least_unacked. const bool last_packet_should_instigate_ack = ShouldLastPacketInstigateAck(); - // If we are missing any packets from the peer, then we want to ack - // immediately. We need to check both before and after we process the - // current packet because we want to ack immediately when we discover - // a missing packet AND when we receive the last missing packet. - bool send_ack_immediately = received_packet_manager_.HasMissingPackets(); + // If the incoming packet was missing, send an ack immediately. + bool send_ack_immediately = received_packet_manager_.IsMissing( + last_header_.packet_sequence_number); // Ensure the visitor can process the stream frames before recording and // processing the rest of the packet. @@ -698,7 +696,8 @@ void QuicConnection::OnPacketComplete() { DCHECK(!connected_); } - if (received_packet_manager_.HasMissingPackets()) { + // If there are new missing packets to report, send an ack immediately. + if (received_packet_manager_.HasNewMissingPackets()) { send_ack_immediately = true; } diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index 05aeeeb..39655d0 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -313,6 +313,11 @@ class TestPacketWriter : public QuicPacketWriter { return is_write_blocked_data_buffered_; } + // Resets the visitor's state by clearing out the headers and frames. + void Reset() { + visitor_.Reset(); + } + QuicPacketHeader* header() { return visitor_.header(); } size_t frame_count() const { return visitor_.frame_count(); } @@ -918,8 +923,8 @@ TEST_F(QuicConnectionTest, TruncatedAck) { EXPECT_CALL(entropy_calculator_, EntropyHash(511)).WillOnce(testing::Return(0)); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(256); - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(10); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(10); + EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2); ProcessAckPacket(&frame); QuicReceivedPacketManager* received_packet_manager = @@ -933,8 +938,8 @@ TEST_F(QuicConnectionTest, TruncatedAck) { // Removing one missing packet allows us to ack 192 and one more range. EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(2); - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(10); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(10); + EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2); ProcessAckPacket(&frame); EXPECT_EQ(num_packets, received_packet_manager->peer_largest_observed_packet()); @@ -1788,7 +1793,7 @@ TEST_F(QuicConnectionTest, ResumptionAlarmThenWriteBlocked) { TEST_F(QuicConnectionTest, LimitPacketsPerNack) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); EXPECT_CALL(*send_algorithm_, OnPacketAcked(15, _, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(13); + EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(4); int offset = 0; // Send packets 1 to 15. for (int i = 0; i < 15; ++i) { @@ -1806,15 +1811,14 @@ TEST_F(QuicConnectionTest, LimitPacketsPerNack) { QuicConnectionPeer::GetSentEntropyHash(&connection_, 15) ^ QuicConnectionPeer::GetSentEntropyHash(&connection_, 14); - // 13 packets have been NACK'd 3 times, but we limit retransmissions to 10. - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(10); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(10); + // 13 packets have been NACK'd 3 times, but we limit retransmissions to 2. + EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2); ProcessAckPacket(&nack); - // The next call should trigger retransmitting 3 more packets, because 14 - // only has 2 nacks so far. - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(3); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3); + // The next call should trigger retransmitting 2 more packets. + EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2); ProcessAckPacket(&nack); } @@ -2611,6 +2615,31 @@ TEST_F(QuicConnectionTest, SendDelayedAckOnSecondPacket) { EXPECT_FALSE(connection_.GetAckAlarm()->IsSet()); } +TEST_F(QuicConnectionTest, NoAckOnOldNacks) { + EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); + // Drop one packet, triggering a sequence of acks. + ProcessPacket(2); + EXPECT_EQ(1u, writer_->frame_count()); + EXPECT_TRUE(writer_->ack()); + writer_->Reset(); + ProcessPacket(3); + EXPECT_EQ(1u, writer_->frame_count()); + EXPECT_TRUE(writer_->ack()); + writer_->Reset(); + ProcessPacket(4); + EXPECT_EQ(1u, writer_->frame_count()); + EXPECT_TRUE(writer_->ack()); + writer_->Reset(); + ProcessPacket(5); + EXPECT_EQ(1u, writer_->frame_count()); + EXPECT_TRUE(writer_->ack()); + // Now only set the timer on the 6th packet, instead of sending another ack. + writer_->Reset(); + ProcessPacket(6); + EXPECT_EQ(0u, writer_->frame_count()); + EXPECT_TRUE(connection_.GetAckAlarm()->IsSet()); +} + TEST_F(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); ProcessPacket(1); diff --git a/net/quic/quic_crypto_client_stream_test.cc b/net/quic/quic_crypto_client_stream_test.cc index d49e2c5..8154d17 100644 --- a/net/quic/quic_crypto_client_stream_test.cc +++ b/net/quic/quic_crypto_client_stream_test.cc @@ -24,9 +24,8 @@ const char kServerHostname[] = "example.com"; class QuicCryptoClientStreamTest : public ::testing::Test { public: QuicCryptoClientStreamTest() - : addr_(), - connection_(new PacketSavingConnection(1, addr_, false)), - session_(new TestSession(connection_, DefaultQuicConfig(), false)), + : connection_(new PacketSavingConnection(false)), + session_(new TestSession(connection_, DefaultQuicConfig())), stream_(new QuicCryptoClientStream(kServerHostname, session_.get(), &crypto_config_)) { session_->SetCryptoStream(stream_.get()); @@ -43,7 +42,6 @@ class QuicCryptoClientStreamTest : public ::testing::Test { message_data_.reset(framer.ConstructHandshakeMessage(message_)); } - IPEndPoint addr_; PacketSavingConnection* connection_; scoped_ptr<TestSession> session_; scoped_ptr<QuicCryptoClientStream> stream_; @@ -88,7 +86,8 @@ TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) { CompleteCryptoHandshake(); const QuicConfig* config = session_->config(); - EXPECT_EQ(kQBIC, config->congestion_control()); + EXPECT_EQ(FLAGS_enable_quic_pacing ? kPACE : kQBIC, + config->congestion_control()); EXPECT_EQ(kDefaultTimeoutSecs, config->idle_connection_state_lifetime().ToSeconds()); EXPECT_EQ(kDefaultMaxStreamsPerConnection, @@ -115,8 +114,8 @@ TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) { // Seed the config with a cached server config. CompleteCryptoHandshake(); - connection_ = new PacketSavingConnection(1, addr_, true); - session_.reset(new TestSession(connection_, DefaultQuicConfig(), true)); + connection_ = new PacketSavingConnection(true); + session_.reset(new TestSession(connection_, DefaultQuicConfig())); stream_.reset(new QuicCryptoClientStream(kServerHostname, session_.get(), &crypto_config_)); diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc index cc50dce..9897e22 100644 --- a/net/quic/quic_crypto_server_stream_test.cc +++ b/net/quic/quic_crypto_server_stream_test.cc @@ -52,11 +52,8 @@ namespace { class QuicCryptoServerStreamTest : public testing::TestWithParam<bool> { public: QuicCryptoServerStreamTest() - : guid_(1), - addr_(ParseIPLiteralToNumber("192.0.2.33", &ip_) ? - ip_ : IPAddressNumber(), 1), - connection_(new PacketSavingConnection(guid_, addr_, true)), - session_(connection_, DefaultQuicConfig(), true), + : connection_(new PacketSavingConnection(true)), + session_(connection_, DefaultQuicConfig()), crypto_config_(QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance()), stream_(crypto_config_, &session_), @@ -104,9 +101,6 @@ class QuicCryptoServerStreamTest : public testing::TestWithParam<bool> { } protected: - IPAddressNumber ip_; - QuicGuid guid_; - IPEndPoint addr_; PacketSavingConnection* connection_; TestSession session_; QuicConfig config_; @@ -136,21 +130,15 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) { } TEST_P(QuicCryptoServerStreamTest, ZeroRTT) { - QuicGuid guid(1); - IPAddressNumber ip; - ParseIPLiteralToNumber("127.0.0.1", &ip); - IPEndPoint addr(ip, 0); - PacketSavingConnection* client_conn = - new PacketSavingConnection(guid, addr, false); - PacketSavingConnection* server_conn = - new PacketSavingConnection(guid, addr, false); + PacketSavingConnection* client_conn = new PacketSavingConnection(false); + PacketSavingConnection* server_conn = new PacketSavingConnection(false); client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(100000)); server_conn->AdvanceTime(QuicTime::Delta::FromSeconds(100000)); QuicConfig client_config; client_config.SetDefaults(); scoped_ptr<TestSession> client_session( - new TestSession(client_conn, client_config, false)); + new TestSession(client_conn, client_config)); QuicCryptoClientConfig client_crypto_config; client_crypto_config.SetDefaults(); @@ -163,8 +151,7 @@ TEST_P(QuicCryptoServerStreamTest, ZeroRTT) { CHECK(client->CryptoConnect()); CHECK_EQ(1u, client_conn->packets_.size()); - scoped_ptr<TestSession> server_session( - new TestSession(server_conn, config_, true)); + scoped_ptr<TestSession> server_session(new TestSession(server_conn, config_)); scoped_ptr<QuicCryptoServerStream> server( new QuicCryptoServerStream(crypto_config_, server_session.get())); server_session->SetCryptoStream(server.get()); @@ -176,8 +163,8 @@ TEST_P(QuicCryptoServerStreamTest, ZeroRTT) { // Now do another handshake, hopefully in 0-RTT. LOG(INFO) << "Resetting for 0-RTT handshake attempt"; - client_conn = new PacketSavingConnection(guid, addr, false); - server_conn = new PacketSavingConnection(guid, addr, false); + client_conn = new PacketSavingConnection(false); + server_conn = new PacketSavingConnection(false); // We need to advance time past the strike-server window so that it's // authoritative in this time span. client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(102000)); @@ -186,8 +173,8 @@ TEST_P(QuicCryptoServerStreamTest, ZeroRTT) { // This causes the client's nonce to be different and thus stops the // strike-register from rejecting the repeated nonce. reinterpret_cast<MockRandom*>(client_conn->random_generator())->ChangeValue(); - client_session.reset(new TestSession(client_conn, client_config, false)); - server_session.reset(new TestSession(server_conn, config_, true)); + client_session.reset(new TestSession(client_conn, client_config)); + server_session.reset(new TestSession(server_conn, config_)); client.reset(new QuicCryptoClientStream( "test.example.com", client_session.get(), &client_crypto_config)); client_session->SetCryptoStream(client.get()); diff --git a/net/quic/quic_crypto_stream.cc b/net/quic/quic_crypto_stream.cc index d1ad84b..d79fa73 100644 --- a/net/quic/quic_crypto_stream.cc +++ b/net/quic/quic_crypto_stream.cc @@ -48,7 +48,7 @@ uint32 QuicCryptoStream::ProcessRawData(const char* data, } QuicPriority QuicCryptoStream::EffectivePriority() const { - return 0; + return QuicUtils::HighestPriority(); } void QuicCryptoStream::SendHandshakeMessage( diff --git a/net/quic/quic_crypto_stream_test.cc b/net/quic/quic_crypto_stream_test.cc index ea59659..c8dbab5 100644 --- a/net/quic/quic_crypto_stream_test.cc +++ b/net/quic/quic_crypto_stream_test.cc @@ -46,9 +46,8 @@ class MockQuicCryptoStream : public QuicCryptoStream { class QuicCryptoStreamTest : public ::testing::Test { public: QuicCryptoStreamTest() - : addr_(IPAddressNumber(), 1), - connection_(new MockConnection(1, addr_, false)), - session_(connection_, true), + : connection_(new MockConnection(false)), + session_(connection_), stream_(&session_) { message_.set_tag(kSHLO); message_.SetStringPiece(1, "abc"); @@ -62,7 +61,6 @@ class QuicCryptoStreamTest : public ::testing::Test { } protected: - IPEndPoint addr_; MockConnection* connection_; MockSession session_; MockQuicCryptoStream stream_; diff --git a/net/quic/quic_data_stream.cc b/net/quic/quic_data_stream.cc index c19f484..3c992a7 100644 --- a/net/quic/quic_data_stream.cc +++ b/net/quic/quic_data_stream.cc @@ -308,7 +308,7 @@ uint32 QuicDataStream::StripPriorityAndHeaderId( // Spdy priorities are inverted, so the highest numerical value is the // lowest legal priority. - if (temporary_priority > static_cast<QuicPriority>(kLowestPriority)) { + if (temporary_priority > QuicUtils::LowestPriority()) { session()->connection()->SendConnectionClose(QUIC_INVALID_PRIORITY); return 0; } diff --git a/net/quic/quic_data_stream_test.cc b/net/quic/quic_data_stream_test.cc index 4dd90bb..551ef44 100644 --- a/net/quic/quic_data_stream_test.cc +++ b/net/quic/quic_data_stream_test.cc @@ -27,7 +27,6 @@ namespace net { namespace test { namespace { -const QuicGuid kGuid = 42; const QuicGuid kStreamId = 3; const bool kIsServer = true; const bool kShouldProcessData = true; @@ -91,10 +90,8 @@ class QuicDataStreamTest : public ::testing::TestWithParam<bool> { } void Initialize(bool stream_should_process_data) { - connection_ = new testing::StrictMock<MockConnection>( - kGuid, IPEndPoint(), kIsServer); - session_.reset(new testing::StrictMock<MockSession>( - connection_, kIsServer)); + connection_ = new StrictMock<MockConnection>(kIsServer); + session_.reset(new StrictMock<MockSession>(connection_)); stream_.reset(new TestStream(kStreamId, session_.get(), stream_should_process_data)); stream2_.reset(new TestStream(kStreamId + 2, session_.get(), @@ -120,20 +117,19 @@ TEST_F(QuicDataStreamTest, ProcessHeaders) { Initialize(kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(compressed_headers)); stream_->OnStreamFrame(frame); EXPECT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_), stream_->data()); - EXPECT_EQ(static_cast<QuicPriority>(kHighestPriority), - stream_->EffectivePriority()); + EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); } TEST_F(QuicDataStreamTest, ProcessHeadersWithInvalidHeaderId) { Initialize(kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); compressed_headers[4] = '\xFF'; // Illegal header id. QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(compressed_headers)); @@ -145,7 +141,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersWithInvalidPriority) { Initialize(kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); compressed_headers[0] = '\xFF'; // Illegal priority. QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(compressed_headers)); @@ -157,7 +153,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersAndBody) { Initialize(kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); string body = "this is the body"; string data = compressed_headers + body; QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data)); @@ -171,7 +167,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyFragments) { Initialize(kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kLowestPriority, headers_); + QuicUtils::LowestPriority(), headers_); string body = "this is the body"; string data = compressed_headers + body; @@ -204,15 +200,14 @@ TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyFragments) { ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body, stream_->data()) << "split_point: " << split_point; } - EXPECT_EQ(static_cast<QuicPriority>(kLowestPriority), - stream_->EffectivePriority()); + EXPECT_EQ(QuicUtils::LowestPriority(), stream_->EffectivePriority()); } TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyReadv) { Initialize(!kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); string body = "this is the body"; string data = compressed_headers + body; QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data)); @@ -242,7 +237,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) { Initialize(!kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); string body = "this is the body"; string data = compressed_headers + body; QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data)); @@ -268,7 +263,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { Initialize(!kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); string body = "this is the body"; string data = compressed_headers + body; QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data)); @@ -298,7 +293,7 @@ TEST_F(QuicDataStreamTest, ProcessCorruptHeadersEarly) { Initialize(kShouldProcessData); string compressed_headers1 = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); QuicStreamFrame frame1( stream_->id(), false, 0, MakeIOVector(compressed_headers1)); string decompressed_headers1 = @@ -306,7 +301,7 @@ TEST_F(QuicDataStreamTest, ProcessCorruptHeadersEarly) { headers_["content-type"] = "text/plain"; string compressed_headers2 = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); // Corrupt the compressed data. compressed_headers2[compressed_headers2.length() - 1] ^= 0xA1; QuicStreamFrame frame2( @@ -340,7 +335,7 @@ TEST_F(QuicDataStreamTest, ProcessPartialHeadersEarly) { Initialize(kShouldProcessData); string compressed_headers1 = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); QuicStreamFrame frame1( stream_->id(), false, 0, MakeIOVector(compressed_headers1)); string decompressed_headers1 = @@ -348,7 +343,7 @@ TEST_F(QuicDataStreamTest, ProcessPartialHeadersEarly) { headers_["content-type"] = "text/plain"; string compressed_headers2 = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); string partial_compressed_headers = compressed_headers2.substr(0, compressed_headers2.length() / 2); QuicStreamFrame frame2( @@ -393,7 +388,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersEarly) { Initialize(kShouldProcessData); string compressed_headers1 = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); QuicStreamFrame frame1( stream_->id(), false, 0, MakeIOVector(compressed_headers1)); string decompressed_headers1 = @@ -401,7 +396,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersEarly) { headers_["content-type"] = "text/plain"; string compressed_headers2 = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); QuicStreamFrame frame2( stream2_->id(), false, 0, MakeIOVector(compressed_headers2)); string decompressed_headers2 = @@ -431,7 +426,7 @@ TEST_F(QuicDataStreamTest, ProcessHeadersDelay) { Initialize(!kShouldProcessData); string compressed_headers = compressor_->CompressHeadersWithPriority( - kHighestPriority, headers_); + QuicUtils::HighestPriority(), headers_); QuicStreamFrame frame1( stream_->id(), false, 0, MakeIOVector(compressed_headers)); string decompressed_headers = diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc index 5b0e1c6..cb37cc2 100644 --- a/net/quic/quic_packet_creator.cc +++ b/net/quic/quic_packet_creator.cc @@ -17,10 +17,6 @@ using std::min; using std::pair; using std::vector; -// If true, then QUIC handshake packets will be padded to the maximium packet -// size. -bool FLAGS_pad_quic_handshake_packets = true; - namespace net { // A QuicRandom wrapper that gets a bucket of entropy and distributes it @@ -320,9 +316,7 @@ SerializedPacket QuicPacketCreator::SerializePacket() { QuicPacketHeader header; FillPacketHeader(fec_group_number_, false, false, &header); - if (FLAGS_pad_quic_handshake_packets) { - MaybeAddPadding(); - } + MaybeAddPadding(); size_t max_plaintext_size = framer_->GetMaxPlaintextSize(options_.max_packet_length); diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h index 1416836..b6756af 100644 --- a/net/quic/quic_packet_creator.h +++ b/net/quic/quic_packet_creator.h @@ -18,8 +18,6 @@ #include "net/quic/quic_framer.h" #include "net/quic/quic_protocol.h" -NET_EXPORT_PRIVATE extern bool FLAGS_pad_quic_handshake_packets; - namespace net { namespace test { class QuicPacketCreatorPeer; diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc index 7b38819..33f2e5c 100644 --- a/net/quic/quic_packet_creator_test.cc +++ b/net/quic/quic_packet_creator_test.cc @@ -374,8 +374,6 @@ TEST_F(QuicPacketCreatorTest, StreamFrameConsumption) { } TEST_F(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) { - ValueRestore<bool> old_flag(&FLAGS_pad_quic_handshake_packets, true); - // Compute the total overhead for a single frame in packet. const size_t overhead = GetPacketHeaderOverhead() + GetEncryptionOverhead() + GetStreamFrameOverhead(); @@ -408,10 +406,7 @@ TEST_F(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) { } } - TEST_F(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) { - ValueRestore<bool> old_flag(&FLAGS_pad_quic_handshake_packets, true); - // Compute the total overhead for a single frame in packet. const size_t overhead = GetPacketHeaderOverhead() + GetEncryptionOverhead() + GetStreamFrameOverhead(); diff --git a/net/quic/quic_received_packet_manager.cc b/net/quic/quic_received_packet_manager.cc index 844ad43..b24ac7c 100644 --- a/net/quic/quic_received_packet_manager.cc +++ b/net/quic/quic_received_packet_manager.cc @@ -5,6 +5,7 @@ #include "net/quic/quic_received_packet_manager.h" #include "base/logging.h" +#include "base/stl_util.h" #include "net/base/linked_hash_map.h" using std::make_pair; @@ -13,6 +14,17 @@ using std::min; namespace net { +namespace { + +// The maximum number of packets to ack immediately after a missing packet for +// fast retransmission to kick in at the sender. This limit is created to +// reduce the number of acks sent that have no benefit for fast retransmission. +// Set to the number of nacks needed for fast retransmit plus one for protection +// against an ack loss +const size_t kMaxPacketsAfterNewMissing = 4; + +} + QuicReceivedPacketManager::QuicReceivedPacketManager( CongestionFeedbackType congestion_type) : packets_entropy_hash_(0), @@ -60,6 +72,11 @@ void QuicReceivedPacketManager::RecordPacketReceived( } } +bool QuicReceivedPacketManager::IsMissing( + QuicPacketSequenceNumber sequence_number) { + return ContainsKey(received_info_.missing_packets, sequence_number); +} + bool QuicReceivedPacketManager::IsAwaitingPacket( QuicPacketSequenceNumber sequence_number) { return ::net::IsAwaitingPacket(received_info_, sequence_number); @@ -213,4 +230,10 @@ bool QuicReceivedPacketManager::HasMissingPackets() { return !received_info_.missing_packets.empty(); } +bool QuicReceivedPacketManager::HasNewMissingPackets() { + return HasMissingPackets() && + (received_info_.largest_observed - + *received_info_.missing_packets.rbegin()) <= kMaxPacketsAfterNewMissing; +} + } // namespace net diff --git a/net/quic/quic_received_packet_manager.h b/net/quic/quic_received_packet_manager.h index 6cc752e..9e2fb59 100644 --- a/net/quic/quic_received_packet_manager.h +++ b/net/quic/quic_received_packet_manager.h @@ -39,6 +39,9 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager : QuicTime receipt_time, bool revived); + // Checks whether |sequence_number| is missing and less than largest observed. + bool IsMissing(QuicPacketSequenceNumber sequence_number); + // Checks if we're still waiting for the packet with |sequence_number|. bool IsAwaitingPacket(QuicPacketSequenceNumber sequence_number); @@ -69,6 +72,10 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager : // Returns whether the peer is missing packets. bool HasMissingPackets(); + // Returns true when there are new missing packets to be reported within 3 + // packets of the largest observed. + bool HasNewMissingPackets(); + QuicPacketSequenceNumber peer_largest_observed_packet() { return peer_largest_observed_packet_; } diff --git a/net/quic/quic_reliable_client_stream_test.cc b/net/quic/quic_reliable_client_stream_test.cc index 8999d26..081186e 100644 --- a/net/quic/quic_reliable_client_stream_test.cc +++ b/net/quic/quic_reliable_client_stream_test.cc @@ -40,7 +40,7 @@ class MockDelegate : public QuicReliableClientStream::Delegate { class QuicReliableClientStreamTest : public ::testing::Test { public: QuicReliableClientStreamTest() - : session_(new MockConnection(1, IPEndPoint(), false), false), + : session_(new MockConnection(false)), stream_(kStreamId, &session_, BoundNetLog()) { stream_.SetDelegate(&delegate_); } diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc index 55693e5..bda30c7 100644 --- a/net/quic/quic_sent_packet_manager.cc +++ b/net/quic/quic_sent_packet_manager.cc @@ -44,10 +44,8 @@ static const int kMinRetransmissionTimeMs = 200; static const int kMaxRetransmissionTimeMs = 60000; static const size_t kMaxRetransmissions = 10; -// We want to make sure if we get a nack packet which triggers several -// retransmissions, we don't queue up too many packets. 10 is TCP's default -// initial congestion window(RFC 6928). -static const size_t kMaxRetransmissionsPerAck = kDefaultInitialWindow; +// We only retransmit 2 packets per ack. +static const size_t kMaxRetransmissionsPerAck = 2; // TCP retransmits after 3 nacks. static const size_t kNumberOfNacksBeforeRetransmission = 3; @@ -78,16 +76,11 @@ QuicSentPacketManager::~QuicSentPacketManager() { for (UnackedPacketMap::iterator it = unacked_packets_.begin(); it != unacked_packets_.end(); ++it) { delete it->second.retransmittable_frames; - } - while (!previous_transmissions_map_.empty()) { - SequenceNumberSet* previous_transmissions = - previous_transmissions_map_.begin()->second; - for (SequenceNumberSet::const_iterator it = previous_transmissions->begin(); - it != previous_transmissions->end(); ++it) { - DCHECK(ContainsKey(previous_transmissions_map_, *it)); - previous_transmissions_map_.erase(*it); + // Only delete previous_transmissions once, for the newest packet. + if (it->second.previous_transmissions != NULL && + it->first == *it->second.previous_transmissions->rbegin()) { + delete it->second.previous_transmissions; } - delete previous_transmissions; } STLDeleteValues(&packet_history_map_); } @@ -138,8 +131,9 @@ void QuicSentPacketManager::OnRetransmittedPacket( pending_retransmissions_.erase(old_sequence_number); - RetransmittableFrames* frames = - unacked_packets_[old_sequence_number].retransmittable_frames; + UnackedPacketMap::iterator unacked_it = + unacked_packets_.find(old_sequence_number); + RetransmittableFrames* frames = unacked_it->second.retransmittable_frames; DCHECK(frames); // A notifier may be waiting to hear about ACKs for the original sequence @@ -149,26 +143,23 @@ void QuicSentPacketManager::OnRetransmittedPacket( // We keep the old packet in the unacked packet list until it, or one of // the retransmissions of it are acked. - unacked_packets_[old_sequence_number].retransmittable_frames = NULL; + unacked_it->second.retransmittable_frames = NULL; unacked_packets_[new_sequence_number] = TransmissionInfo(frames, GetSequenceNumberLength(old_sequence_number)); // Keep track of all sequence numbers that this packet // has been transmitted as. - SequenceNumberSet* previous_transmissions; - PreviousTransmissionMap::iterator it = - previous_transmissions_map_.find(old_sequence_number); - if (it == previous_transmissions_map_.end()) { + SequenceNumberSet* previous_transmissions = + unacked_it->second.previous_transmissions; + if (previous_transmissions == NULL) { // This is the first retransmission of this packet, so create a new entry. previous_transmissions = new SequenceNumberSet; - previous_transmissions_map_[old_sequence_number] = previous_transmissions; + unacked_it->second.previous_transmissions = previous_transmissions; previous_transmissions->insert(old_sequence_number); - } else { - // Otherwise, use the existing entry. - previous_transmissions = it->second; } previous_transmissions->insert(new_sequence_number); - previous_transmissions_map_[new_sequence_number] = previous_transmissions; + unacked_packets_[new_sequence_number].previous_transmissions = + previous_transmissions; DCHECK(HasRetransmittableFrames(new_sequence_number)); } @@ -240,28 +231,30 @@ void QuicSentPacketManager::HandleAckForSentPackets( } void QuicSentPacketManager::ClearPreviousRetransmissions(size_t num_to_clear) { - UnackedPacketMap::const_iterator it = unacked_packets_.begin(); + UnackedPacketMap::iterator it = unacked_packets_.begin(); while (it != unacked_packets_.end() && num_to_clear > 0) { QuicPacketSequenceNumber sequence_number = it->first; - ++it; // If this is not a previous transmission then there is no point // in clearing out any further packets, because it will not affect // the high water mark. - if (!IsPreviousTransmission(sequence_number)) { + SequenceNumberSet* previous_transmissions = + it->second.previous_transmissions; + if (previous_transmissions == NULL) { + break; + } + QuicPacketSequenceNumber newest_transmission = + *previous_transmissions->rbegin(); + if (sequence_number == newest_transmission) { break; } - DCHECK(ContainsKey(previous_transmissions_map_, sequence_number)); - DCHECK(!HasRetransmittableFrames(sequence_number)); - unacked_packets_.erase(sequence_number); - SequenceNumberSet* previous_transmissions = - previous_transmissions_map_[sequence_number]; - previous_transmissions_map_.erase(sequence_number); + DCHECK(it->second.retransmittable_frames == NULL); previous_transmissions->erase(sequence_number); if (previous_transmissions->size() == 1) { - previous_transmissions_map_.erase(*previous_transmissions->begin()); + unacked_packets_[newest_transmission].previous_transmissions = NULL; delete previous_transmissions; } + unacked_packets_.erase(it++); --num_to_clear; } } @@ -343,42 +336,25 @@ bool QuicSentPacketManager::IsPreviousTransmission( QuicPacketSequenceNumber sequence_number) const { DCHECK(ContainsKey(unacked_packets_, sequence_number)); - PreviousTransmissionMap::const_iterator it = - previous_transmissions_map_.find(sequence_number); - if (it == previous_transmissions_map_.end()) { + UnackedPacketMap::const_iterator it = unacked_packets_.find(sequence_number); + if (it->second.previous_transmissions == NULL) { return false; } - SequenceNumberSet* previous_transmissions = it->second; + SequenceNumberSet* previous_transmissions = it->second.previous_transmissions; DCHECK(!previous_transmissions->empty()); return *previous_transmissions->rbegin() != sequence_number; } -QuicPacketSequenceNumber QuicSentPacketManager::GetMostRecentTransmission( - QuicPacketSequenceNumber sequence_number) const { - DCHECK(ContainsKey(unacked_packets_, sequence_number)); - - PreviousTransmissionMap::const_iterator it = - previous_transmissions_map_.find(sequence_number); - if (it == previous_transmissions_map_.end()) { - return sequence_number; - } - - SequenceNumberSet* previous_transmissions = - previous_transmissions_map_.find(sequence_number)->second; - DCHECK(!previous_transmissions->empty()); - return *previous_transmissions->rbegin(); -} - QuicSentPacketManager::UnackedPacketMap::iterator QuicSentPacketManager::MarkPacketReceivedByPeer( QuicPacketSequenceNumber sequence_number) { DCHECK(ContainsKey(unacked_packets_, sequence_number)); // If this packet has never been retransmitted, then simply drop it. - PreviousTransmissionMap::const_iterator previous_it = - previous_transmissions_map_.find(sequence_number); - if (previous_it == previous_transmissions_map_.end()) { + UnackedPacketMap::const_iterator previous_it = + unacked_packets_.find(sequence_number); + if (previous_it->second.previous_transmissions == NULL) { UnackedPacketMap::iterator next_unacked = unacked_packets_.find(sequence_number); ++next_unacked; @@ -386,7 +362,8 @@ QuicSentPacketManager::MarkPacketReceivedByPeer( return next_unacked; } - SequenceNumberSet* previous_transmissions = previous_it->second; + SequenceNumberSet* previous_transmissions = + previous_it->second.previous_transmissions; DCHECK(!previous_transmissions->empty()); SequenceNumberSet::reverse_iterator previous_transmissions_it = previous_transmissions->rbegin(); @@ -399,17 +376,15 @@ QuicSentPacketManager::MarkPacketReceivedByPeer( // but prevent the data from being retransmitted. delete unacked_packets_[newest_transmission].retransmittable_frames; unacked_packets_[newest_transmission].retransmittable_frames = NULL; + unacked_packets_[newest_transmission].previous_transmissions = NULL; pending_retransmissions_.erase(newest_transmission); } - previous_transmissions_map_.erase(newest_transmission); // Clear out information all previous transmissions. ++previous_transmissions_it; while (previous_transmissions_it != previous_transmissions->rend()) { QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it; ++previous_transmissions_it; - DCHECK(ContainsKey(previous_transmissions_map_, previous_transmission)); - previous_transmissions_map_.erase(previous_transmission); DiscardPacket(previous_transmission); } diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h index 9e7bdb8..71c61e9 100644 --- a/net/quic/quic_sent_packet_manager.h +++ b/net/quic/quic_sent_packet_manager.h @@ -204,18 +204,23 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { TransmissionInfo() : retransmittable_frames(NULL), sequence_number_length(PACKET_1BYTE_SEQUENCE_NUMBER), - sent_time(QuicTime::Zero()) { } + sent_time(QuicTime::Zero()), + previous_transmissions(NULL) { } TransmissionInfo(RetransmittableFrames* retransmittable_frames, QuicSequenceNumberLength sequence_number_length) : retransmittable_frames(retransmittable_frames), sequence_number_length(sequence_number_length), - sent_time(QuicTime::Zero()) { + sent_time(QuicTime::Zero()), + previous_transmissions(NULL) { } RetransmittableFrames* retransmittable_frames; QuicSequenceNumberLength sequence_number_length; // Zero when the packet is serialized, non-zero once it's sent. QuicTime sent_time; + // Stores all previous transmissions if the packet has been retransmitted, + // and is NULL otherwise. + SequenceNumberSet* previous_transmissions; }; typedef linked_hash_map<QuicPacketSequenceNumber, @@ -252,11 +257,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { QuicSequenceNumberLength GetSequenceNumberLength( QuicPacketSequenceNumber sequence_number) const; - // Returns the sequence number of the packet that |sequence_number| was - // most recently transmitted as. - QuicPacketSequenceNumber GetMostRecentTransmission( - QuicPacketSequenceNumber sequence_number) const; - // Clears up to |num_to_clear| previous transmissions in order to make room // in the ack frame for new acks. void ClearPreviousRetransmissions(size_t num_to_clear); @@ -276,12 +276,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { // Pending retransmissions which have not been packetized and sent yet. PendingRetransmissionMap pending_retransmissions_; - // Map from sequence number to set of all sequence number that this packet has - // been transmitted as. If a packet has not been retransmitted, it will not - // have an entry in this map. If any transmission of a packet has been acked - // it will not have an entry in this map. - PreviousTransmissionMap previous_transmissions_map_; - // Tracks if the connection was created by the server. bool is_server_; diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc index 0429a26..168cbf3 100644 --- a/net/quic/quic_sent_packet_manager_test.cc +++ b/net/quic/quic_sent_packet_manager_test.cc @@ -631,7 +631,7 @@ TEST_F(QuicSentPacketManagerTest, DontEarlyRetransmitPacket) { EXPECT_EQ(3u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); } -TEST_F(QuicSentPacketManagerTest, NackRetransmit10Packets) { +TEST_F(QuicSentPacketManagerTest, NackRetransmit2Packets) { const size_t kNumSentPackets = 20; // Transmit 20 packets. for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) { @@ -651,18 +651,18 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit10Packets) { } EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(10); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(10); + EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2); SequenceNumberSet retransmissions = manager_.OnIncomingAckFrame(received_info, clock_.Now()); - EXPECT_EQ(10u, retransmissions.size()); + EXPECT_EQ(2u, retransmissions.size()); for (size_t i = 1; i < kNumSentPackets; ++i) { EXPECT_EQ(kNumSentPackets - i, QuicSentPacketManagerPeer::GetNackCount(&manager_, i)); } } -TEST_F(QuicSentPacketManagerTest, NackRetransmit10PacketsAlternateAcks) { +TEST_F(QuicSentPacketManagerTest, NackRetransmit2PacketsAlternateAcks) { const size_t kNumSentPackets = 30; // Transmit 15 packets of data and 15 ack packets. The send algorithm will // inform the congestion manager not to save the acks by returning false. @@ -684,11 +684,11 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit10PacketsAlternateAcks) { } // We never actually get an ack call, since the kNumSentPackets packet was // not saved. - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(10); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(10); + EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2); SequenceNumberSet retransmissions = manager_.OnIncomingAckFrame(received_info, clock_.Now()); - EXPECT_EQ(10u, retransmissions.size()); + EXPECT_EQ(2u, retransmissions.size()); // Only non-ack packets have a nack count. for (size_t i = 1; i < kNumSentPackets; i += 2) { EXPECT_EQ(kNumSentPackets - i, diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc index 360c79e..67cdf54 100644 --- a/net/quic/quic_session.cc +++ b/net/quic/quic_session.cc @@ -20,7 +20,7 @@ namespace net { const size_t kMaxPrematurelyClosedStreamsTracked = 20; const size_t kMaxZombieStreams = 20; -#define ENDPOINT (is_server_ ? "Server: " : " Client: ") +#define ENDPOINT (is_server() ? "Server: " : " Client: ") // We want to make sure we delete any closed streams in a safe manner. // To avoid deleting a stream in mid-operation, we have a simple shim between @@ -78,14 +78,12 @@ class VisitorShim : public QuicConnectionVisitorInterface { }; QuicSession::QuicSession(QuicConnection* connection, - const QuicConfig& config, - bool is_server) + const QuicConfig& config) : connection_(connection), visitor_shim_(new VisitorShim(this)), config_(config), max_open_streams_(config_.max_streams_per_connection()), - next_stream_id_(is_server ? 2 : 3), - is_server_(is_server), + next_stream_id_(is_server() ? 2 : 3), largest_peer_created_stream_id_(0), error_(QUIC_NO_ERROR), goaway_received_(false), @@ -293,7 +291,7 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id, // a request before receiving the response) then we need to make sure that // we keep the stream alive long enough to process any response or // RST_STREAM frames. - if (locally_reset && !is_server_) { + if (locally_reset && !is_server()) { AddZombieStream(stream_id); return; } diff --git a/net/quic/quic_session.h b/net/quic/quic_session.h index 515f2b9..083990b 100644 --- a/net/quic/quic_session.h +++ b/net/quic/quic_session.h @@ -54,8 +54,7 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface { }; QuicSession(QuicConnection* connection, - const QuicConfig& config, - bool is_server); + const QuicConfig& config); virtual ~QuicSession(); @@ -173,7 +172,7 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface { QuicErrorCode error() const { return error_; } - bool is_server() const { return is_server_; } + bool is_server() const { return connection_->is_server(); } protected: typedef base::hash_map<QuicStreamId, QuicDataStream*> DataStreamMap; @@ -274,7 +273,6 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface { // Map from StreamId to pointers to streams that are owned by the caller. DataStreamMap stream_map_; QuicStreamId next_stream_id_; - bool is_server_; // Set of stream ids that have been "implicitly created" by receipt // of a stream id larger than the next expected stream id. diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc index f0d4e5c..ecbafb5 100644 --- a/net/quic/quic_session_test.cc +++ b/net/quic/quic_session_test.cc @@ -90,8 +90,8 @@ class StreamBlocker { class TestSession : public QuicSession { public: - TestSession(QuicConnection* connection, bool is_server) - : QuicSession(connection, DefaultQuicConfig(), is_server), + explicit TestSession(QuicConnection* connection) + : QuicSession(connection, DefaultQuicConfig()), crypto_stream_(this) { } @@ -123,9 +123,8 @@ class TestSession : public QuicSession { class QuicSessionTest : public ::testing::Test { protected: QuicSessionTest() - : guid_(1), - connection_(new MockConnection(guid_, IPEndPoint(), false)), - session_(connection_, true) { + : connection_(new MockConnection(true)), + session_(connection_) { headers_[":host"] = "www.google.com"; headers_[":path"] = "/index.hml"; headers_[":scheme"] = "http"; @@ -170,7 +169,6 @@ class QuicSessionTest : public ::testing::Test { closed_streams_.insert(id); } - QuicGuid guid_; MockConnection* connection_; TestSession session_; set<QuicStreamId> closed_streams_; @@ -178,7 +176,7 @@ class QuicSessionTest : public ::testing::Test { }; TEST_F(QuicSessionTest, PeerAddress) { - EXPECT_EQ(IPEndPoint(), session_.peer_address()); + EXPECT_EQ(IPEndPoint(Loopback4(), kTestPort), session_.peer_address()); } TEST_F(QuicSessionTest, IsCryptoHandshakeConfirmed) { @@ -248,6 +246,7 @@ TEST_F(QuicSessionTest, DecompressionError) { ReliableQuicStream* stream = session_.GetIncomingReliableStream(3); EXPECT_CALL(*connection_, SendConnectionClose(QUIC_DECOMPRESSION_FAILURE)); const char data[] = + "\0\0\0\0" // priority "\1\0\0\0" // headers id "\0\0\0\4" // length "abcd"; // invalid compressed data @@ -395,8 +394,8 @@ TEST_F(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) { TEST_F(QuicSessionTest, ZombieStream) { StrictMock<MockConnection>* connection = - new StrictMock<MockConnection>(guid_, IPEndPoint(), false); - TestSession session(connection, /*is_server=*/ false); + new StrictMock<MockConnection>(false); + TestSession session(connection); TestStream* stream3 = session.CreateOutgoingDataStream(); EXPECT_EQ(3u, stream3->id()); @@ -435,8 +434,8 @@ TEST_F(QuicSessionTest, ZombieStream) { TEST_F(QuicSessionTest, ZombieStreamConnectionClose) { StrictMock<MockConnection>* connection = - new StrictMock<MockConnection>(guid_, IPEndPoint(), false); - TestSession session(connection, /*is_server=*/ false); + new StrictMock<MockConnection>(false); + TestSession session(connection); TestStream* stream3 = session.CreateOutgoingDataStream(); EXPECT_EQ(3u, stream3->id()); diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc index eb760af..f898e66 100644 --- a/net/quic/quic_stream_sequencer_test.cc +++ b/net/quic/quic_stream_sequencer_test.cc @@ -75,7 +75,9 @@ class MockStream : public ReliableQuicStream { const string& details)); MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error)); MOCK_METHOD0(OnCanWrite, void()); - virtual QuicPriority EffectivePriority() const { return 0; } + virtual QuicPriority EffectivePriority() const { + return QuicUtils::HighestPriority(); + } }; namespace { @@ -86,8 +88,8 @@ static const char kPayload[] = class QuicStreamSequencerTest : public ::testing::Test { protected: QuicStreamSequencerTest() - : connection_(new MockConnection(1, IPEndPoint(), false)), - session_(connection_, true), + : connection_(new MockConnection(false)), + session_(connection_), stream_(&session_, 1), sequencer_(new QuicStreamSequencerPeer(&stream_)) { } diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc index cc57cb7..0aff377 100644 --- a/net/quic/quic_utils.cc +++ b/net/quic/quic_utils.cc @@ -12,6 +12,7 @@ #include "base/port.h" #include "base/strings/stringprintf.h" #include "base/strings/string_number_conversions.h" +#include "net/spdy/write_blocked_list.h" using base::StringPiece; using std::string; @@ -281,4 +282,14 @@ string QuicUtils::StringToHexASCIIDump(StringPiece in_buffer) { return s; } +// static +QuicPriority QuicUtils::LowestPriority() { + return static_cast<QuicPriority>(kLowestPriority); +} + +// static +QuicPriority QuicUtils::HighestPriority() { + return static_cast<QuicPriority>(kHighestPriority); +} + } // namespace net diff --git a/net/quic/quic_utils.h b/net/quic/quic_utils.h index 0ee1174..23f3b53 100644 --- a/net/quic/quic_utils.h +++ b/net/quic/quic_utils.h @@ -75,6 +75,10 @@ class NET_EXPORT_PRIVATE QuicUtils { static char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); } + + static QuicPriority LowestPriority(); + + static QuicPriority HighestPriority(); }; // Utility function that returns an IOVector object wrapped around |str|. diff --git a/net/quic/reliable_quic_stream.cc b/net/quic/reliable_quic_stream.cc index 1db5357..5d9c3cc 100644 --- a/net/quic/reliable_quic_stream.cc +++ b/net/quic/reliable_quic_stream.cc @@ -112,6 +112,10 @@ void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error, session()->connection()->SendConnectionCloseWithDetails(error, details); } +QuicVersion ReliableQuicStream::version() { + return session()->connection()->version(); +} + void ReliableQuicStream::WriteOrBufferData(StringPiece data, bool fin) { DCHECK(data.size() > 0 || fin); DCHECK(!fin_buffered_); diff --git a/net/quic/reliable_quic_stream.h b/net/quic/reliable_quic_stream.h index 210b8ad..7b0a790 100644 --- a/net/quic/reliable_quic_stream.h +++ b/net/quic/reliable_quic_stream.h @@ -86,6 +86,8 @@ class NET_EXPORT_PRIVATE ReliableQuicStream { uint64 stream_bytes_read() { return stream_bytes_read_; } uint64 stream_bytes_written() { return stream_bytes_written_; } + QuicVersion version(); + protected: // Sends as much of 'data' to the connection as the connection will consume, // and then buffers any remaining data in queued_data_. diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc index 60414ae..7e82f53 100644 --- a/net/quic/reliable_quic_stream_test.cc +++ b/net/quic/reliable_quic_stream_test.cc @@ -30,7 +30,6 @@ namespace { const char kData1[] = "FooAndBar"; const char kData2[] = "EepAndBaz"; const size_t kDataLen = 9; -const QuicGuid kGuid = 42; const QuicGuid kStreamId = 3; const bool kIsServer = true; const bool kShouldProcessData = true; @@ -50,7 +49,9 @@ class TestStream : public ReliableQuicStream { return should_process_data_ ? data_len : 0; } - virtual QuicPriority EffectivePriority() const OVERRIDE { return 0; } + virtual QuicPriority EffectivePriority() const OVERRIDE { + return QuicUtils::HighestPriority(); + } using ReliableQuicStream::WriteOrBufferData; using ReliableQuicStream::CloseReadSide; @@ -96,10 +97,8 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> { } void Initialize(bool stream_should_process_data) { - connection_ = new testing::StrictMock<MockConnection>( - kGuid, IPEndPoint(), kIsServer); - session_.reset(new testing::StrictMock<MockSession>( - connection_, kIsServer)); + connection_ = new StrictMock<MockConnection>(kIsServer); + session_.reset(new StrictMock<MockSession>(connection_)); stream_.reset(new TestStream(kStreamId, session_.get(), stream_should_process_data)); stream2_.reset(new TestStream(kStreamId + 2, session_.get(), diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc index e14d7ab..a6b6cc1 100644 --- a/net/quic/test_tools/crypto_test_utils.cc +++ b/net/quic/test_tools/crypto_test_utils.cc @@ -133,13 +133,8 @@ CryptoTestUtils::FakeClientOptions::FakeClientOptions() int CryptoTestUtils::HandshakeWithFakeServer( PacketSavingConnection* client_conn, QuicCryptoClientStream* client) { - QuicGuid guid(1); - IPAddressNumber ip; - CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); - IPEndPoint addr = IPEndPoint(ip, 1); - PacketSavingConnection* server_conn = - new PacketSavingConnection(guid, addr, true); - TestSession server_session(server_conn, DefaultQuicConfig(), true); + PacketSavingConnection* server_conn = new PacketSavingConnection(true); + TestSession server_session(server_conn, DefaultQuicConfig()); QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance()); @@ -166,13 +161,8 @@ int CryptoTestUtils::HandshakeWithFakeClient( PacketSavingConnection* server_conn, QuicCryptoServerStream* server, const FakeClientOptions& options) { - QuicGuid guid(1); - IPAddressNumber ip; - CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); - IPEndPoint addr = IPEndPoint(ip, 1); - PacketSavingConnection* client_conn = - new PacketSavingConnection(guid, addr, false); - TestSession client_session(client_conn, DefaultQuicConfig(), false); + PacketSavingConnection* client_conn = new PacketSavingConnection(false); + TestSession client_session(client_conn, DefaultQuicConfig()); QuicCryptoClientConfig crypto_config; client_session.config()->SetDefaults(); diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.cc b/net/quic/test_tools/quic_sent_packet_manager_peer.cc index 2284d0e..e2e7c02 100644 --- a/net/quic/test_tools/quic_sent_packet_manager_peer.cc +++ b/net/quic/test_tools/quic_sent_packet_manager_peer.cc @@ -49,8 +49,8 @@ bool QuicSentPacketManagerPeer::IsRetransmission( QuicPacketSequenceNumber sequence_number) { DCHECK(sent_packet_manager->HasRetransmittableFrames(sequence_number)); return sent_packet_manager->HasRetransmittableFrames(sequence_number) && - ContainsKey(sent_packet_manager->previous_transmissions_map_, - sequence_number); + sent_packet_manager-> + unacked_packets_[sequence_number].previous_transmissions != NULL; } // static diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc index 4de2cad..d85f92f 100644 --- a/net/quic/test_tools/quic_test_utils.cc +++ b/net/quic/test_tools/quic_test_utils.cc @@ -231,40 +231,46 @@ void MockHelper::AdvanceTime(QuicTime::Delta delta) { clock_.AdvanceTime(delta); } -MockConnection::MockConnection(QuicGuid guid, - IPEndPoint address, +MockConnection::MockConnection(bool is_server) + : QuicConnection(kTestGuid, + IPEndPoint(Loopback4(), kTestPort), + new testing::NiceMock<MockHelper>(), + new testing::NiceMock<MockPacketWriter>(), + is_server, QuicSupportedVersions()), + writer_(QuicConnectionPeer::GetWriter(this)), + helper_(helper()) { +} + +MockConnection::MockConnection(IPEndPoint address, bool is_server) - : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(), + : QuicConnection(kTestGuid, address, + new testing::NiceMock<MockHelper>(), new testing::NiceMock<MockPacketWriter>(), is_server, QuicSupportedVersions()), - has_mock_helper_(true), writer_(QuicConnectionPeer::GetWriter(this)), helper_(helper()) { } MockConnection::MockConnection(QuicGuid guid, - IPEndPoint address, - QuicConnectionHelperInterface* helper, - QuicPacketWriter* writer, bool is_server) - : QuicConnection(guid, address, helper, writer, is_server, - QuicSupportedVersions()), - has_mock_helper_(false) { + : QuicConnection(guid, + IPEndPoint(Loopback4(), kTestPort), + new testing::NiceMock<MockHelper>(), + new testing::NiceMock<MockPacketWriter>(), + is_server, QuicSupportedVersions()), + writer_(QuicConnectionPeer::GetWriter(this)), + helper_(helper()) { } MockConnection::~MockConnection() { } void MockConnection::AdvanceTime(QuicTime::Delta delta) { - CHECK(has_mock_helper_) << "Cannot advance time unless a MockClock is being" - " used"; static_cast<MockHelper*>(helper())->AdvanceTime(delta); } -PacketSavingConnection::PacketSavingConnection(QuicGuid guid, - IPEndPoint address, - bool is_server) - : MockConnection(guid, address, is_server) { +PacketSavingConnection::PacketSavingConnection(bool is_server) + : MockConnection(is_server) { } PacketSavingConnection::~PacketSavingConnection() { @@ -283,8 +289,8 @@ bool PacketSavingConnection::SendOrQueuePacket( return true; } -MockSession::MockSession(QuicConnection* connection, bool is_server) - : QuicSession(connection, DefaultQuicConfig(), is_server) { +MockSession::MockSession(QuicConnection* connection) + : QuicSession(connection, DefaultQuicConfig()) { ON_CALL(*this, WritevData(_, _, _, _, _, _)) .WillByDefault(testing::Return(QuicConsumedData(0, false))); } @@ -293,9 +299,8 @@ MockSession::~MockSession() { } TestSession::TestSession(QuicConnection* connection, - const QuicConfig& config, - bool is_server) - : QuicSession(connection, config, is_server), + const QuicConfig& config) + : QuicSession(connection, config), crypto_stream_(NULL) { } @@ -372,6 +377,12 @@ QuicVersion QuicVersionMax() { return QuicSupportedVersions().front(); } QuicVersion QuicVersionMin() { return QuicSupportedVersions().back(); } +IPAddressNumber Loopback4() { + net::IPAddressNumber addr; + CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &addr)); + return addr; +} + void CompareCharArraysWithHexError( const string& description, const char* actual, diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index 3bec87c..06c3431 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h @@ -26,12 +26,18 @@ namespace net { namespace test { +static const QuicGuid kTestGuid = 42; +static const int kTestPort = 123; + // Upper limit on versions we support. QuicVersion QuicVersionMax(); // Lower limit on versions we support. QuicVersion QuicVersionMin(); +// Returns an address for 127.0.0.1. +IPAddressNumber Loopback4(); + void CompareCharArraysWithHexError(const std::string& description, const char* actual, const int actual_len, @@ -244,13 +250,17 @@ class MockHelper : public QuicConnectionHelperInterface { class MockConnection : public QuicConnection { public: - // Uses a MockHelper. - MockConnection(QuicGuid guid, IPEndPoint address, bool is_server); + // Uses a MockHelper, GUID of 42, and 127.0.0.1:123. + explicit MockConnection(bool is_server); + + // Uses a MockHelper, GUID of 42. + MockConnection(IPEndPoint address, + bool is_server); + + // Uses a MockHelper, and 127.0.0.1:123 MockConnection(QuicGuid guid, - IPEndPoint address, - QuicConnectionHelperInterface* helper, - QuicPacketWriter* writer, bool is_server); + virtual ~MockConnection(); // If the constructor that uses a MockHelper has been used then this method @@ -282,7 +292,6 @@ class MockConnection : public QuicConnection { } private: - const bool has_mock_helper_; scoped_ptr<QuicPacketWriter> writer_; scoped_ptr<QuicConnectionHelperInterface> helper_; @@ -291,7 +300,7 @@ class MockConnection : public QuicConnection { class PacketSavingConnection : public MockConnection { public: - PacketSavingConnection(QuicGuid guid, IPEndPoint address, bool is_server); + explicit PacketSavingConnection(bool is_server); virtual ~PacketSavingConnection(); virtual bool SendOrQueuePacket(EncryptionLevel level, @@ -307,7 +316,7 @@ class PacketSavingConnection : public MockConnection { class MockSession : public QuicSession { public: - MockSession(QuicConnection* connection, bool is_server); + explicit MockSession(QuicConnection* connection); virtual ~MockSession(); MOCK_METHOD4(OnPacket, bool(const IPEndPoint& self_address, @@ -334,9 +343,7 @@ class MockSession : public QuicSession { class TestSession : public QuicSession { public: - TestSession(QuicConnection* connection, - const QuicConfig& config, - bool is_server); + TestSession(QuicConnection* connection, const QuicConfig& config); virtual ~TestSession(); MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id)); |