| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/tools/quic/quic_dispatcher.h" | 5 #include "net/tools/quic/quic_dispatcher.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <ostream> | 8 #include <ostream> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "net/quic/core/crypto/crypto_handshake.h" | 13 #include "net/quic/core/crypto/crypto_handshake.h" |
| 14 #include "net/quic/core/crypto/quic_crypto_server_config.h" | 14 #include "net/quic/core/crypto/quic_crypto_server_config.h" |
| 15 #include "net/quic/core/crypto/quic_random.h" | 15 #include "net/quic/core/crypto/quic_random.h" |
| 16 #include "net/quic/core/quic_crypto_stream.h" | 16 #include "net/quic/core/quic_crypto_stream.h" |
| 17 #include "net/quic/core/quic_flags.h" | 17 #include "net/quic/core/quic_flags.h" |
| 18 #include "net/quic/core/quic_utils.h" | 18 #include "net/quic/core/quic_utils.h" |
| 19 #include "net/quic/test_tools/crypto_test_utils.h" | 19 #include "net/quic/test_tools/crypto_test_utils.h" |
| 20 #include "net/quic/test_tools/quic_buffered_packet_store_peer.h" |
| 20 #include "net/quic/test_tools/quic_test_utils.h" | 21 #include "net/quic/test_tools/quic_test_utils.h" |
| 22 #include "net/test/gtest_util.h" |
| 21 #include "net/tools/epoll_server/epoll_server.h" | 23 #include "net/tools/epoll_server/epoll_server.h" |
| 24 #include "net/tools/quic/chlo_extractor.h" |
| 22 #include "net/tools/quic/quic_epoll_alarm_factory.h" | 25 #include "net/tools/quic/quic_epoll_alarm_factory.h" |
| 23 #include "net/tools/quic/quic_epoll_connection_helper.h" | 26 #include "net/tools/quic/quic_epoll_connection_helper.h" |
| 24 #include "net/tools/quic/quic_packet_writer_wrapper.h" | 27 #include "net/tools/quic/quic_packet_writer_wrapper.h" |
| 25 #include "net/tools/quic/quic_simple_server_session_helper.h" | 28 #include "net/tools/quic/quic_simple_server_session_helper.h" |
| 26 #include "net/tools/quic/quic_time_wait_list_manager.h" | 29 #include "net/tools/quic/quic_time_wait_list_manager.h" |
| 30 #include "net/tools/quic/stateless_rejector.h" |
| 27 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" | 31 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" |
| 28 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" | 32 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" | 33 #include "testing/gmock/include/gmock/gmock.h" |
| 34 #include "testing/gmock_mutant.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
| 31 | 36 |
| 37 using base::IntToString; |
| 32 using base::StringPiece; | 38 using base::StringPiece; |
| 33 using net::EpollServer; | 39 using net::EpollServer; |
| 34 using net::test::ConstructEncryptedPacket; | 40 using net::test::ConstructEncryptedPacket; |
| 35 using net::test::CryptoTestUtils; | 41 using net::test::CryptoTestUtils; |
| 36 using net::test::MockQuicConnection; | 42 using net::test::MockQuicConnection; |
| 37 using net::test::MockQuicConnectionHelper; | 43 using net::test::MockQuicConnectionHelper; |
| 38 using net::test::ValueRestore; | 44 using net::test::ValueRestore; |
| 45 using std::ostream; |
| 39 using std::string; | 46 using std::string; |
| 40 using std::vector; | 47 using std::vector; |
| 48 using testing::CreateFunctor; |
| 41 using testing::DoAll; | 49 using testing::DoAll; |
| 42 using testing::InSequence; | 50 using testing::InSequence; |
| 43 using testing::Invoke; | 51 using testing::Invoke; |
| 44 using testing::WithoutArgs; | 52 using testing::WithoutArgs; |
| 45 using testing::_; | 53 using testing::_; |
| 46 | 54 |
| 55 static const size_t kDefaultMaxConnectionsInStore = 100; |
| 56 |
| 47 namespace net { | 57 namespace net { |
| 48 namespace test { | 58 namespace test { |
| 49 namespace { | 59 namespace { |
| 50 | 60 |
| 51 class TestQuicSpdyServerSession : public QuicServerSessionBase { | 61 class TestQuicSpdyServerSession : public QuicServerSessionBase { |
| 52 public: | 62 public: |
| 53 TestQuicSpdyServerSession(const QuicConfig& config, | 63 TestQuicSpdyServerSession(const QuicConfig& config, |
| 54 QuicConnection* connection, | 64 QuicConnection* connection, |
| 55 const QuicCryptoServerConfig* crypto_config, | 65 const QuicCryptoServerConfig* crypto_config, |
| 56 QuicCompressedCertsCache* compressed_certs_cache) | 66 QuicCompressedCertsCache* compressed_certs_cache) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)), | 118 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)), |
| 109 std::unique_ptr<QuicServerSessionBase::Helper>( | 119 std::unique_ptr<QuicServerSessionBase::Helper>( |
| 110 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), | 120 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), |
| 111 std::unique_ptr<QuicEpollAlarmFactory>( | 121 std::unique_ptr<QuicEpollAlarmFactory>( |
| 112 new QuicEpollAlarmFactory(eps))) {} | 122 new QuicEpollAlarmFactory(eps))) {} |
| 113 | 123 |
| 114 MOCK_METHOD2(CreateQuicSession, | 124 MOCK_METHOD2(CreateQuicSession, |
| 115 QuicServerSessionBase*(QuicConnectionId connection_id, | 125 QuicServerSessionBase*(QuicConnectionId connection_id, |
| 116 const IPEndPoint& client_address)); | 126 const IPEndPoint& client_address)); |
| 117 | 127 |
| 128 MOCK_METHOD1(OnNewConnectionAdded, void(QuicConnectionId connection_id)); |
| 129 |
| 118 using QuicDispatcher::current_server_address; | 130 using QuicDispatcher::current_server_address; |
| 119 using QuicDispatcher::current_client_address; | 131 using QuicDispatcher::current_client_address; |
| 120 }; | 132 }; |
| 121 | 133 |
| 122 // A Connection class which unregisters the session from the dispatcher when | 134 // A Connection class which unregisters the session from the dispatcher when |
| 123 // sending connection close. | 135 // sending connection close. |
| 124 // It'd be slightly more realistic to do this from the Session but it would | 136 // It'd be slightly more realistic to do this from the Session but it would |
| 125 // involve a lot more mocking. | 137 // involve a lot more mocking. |
| 126 class MockServerConnection : public MockQuicConnection { | 138 class MockServerConnection : public MockQuicConnection { |
| 127 public: | 139 public: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 138 void UnregisterOnConnectionClosed() { | 150 void UnregisterOnConnectionClosed() { |
| 139 LOG(ERROR) << "Unregistering " << connection_id(); | 151 LOG(ERROR) << "Unregistering " << connection_id(); |
| 140 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR, | 152 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR, |
| 141 "Unregistering."); | 153 "Unregistering."); |
| 142 } | 154 } |
| 143 | 155 |
| 144 private: | 156 private: |
| 145 QuicDispatcher* dispatcher_; | 157 QuicDispatcher* dispatcher_; |
| 146 }; | 158 }; |
| 147 | 159 |
| 148 QuicServerSessionBase* CreateSession( | |
| 149 QuicDispatcher* dispatcher, | |
| 150 const QuicConfig& config, | |
| 151 QuicConnectionId connection_id, | |
| 152 const IPEndPoint& client_address, | |
| 153 MockQuicConnectionHelper* helper, | |
| 154 MockAlarmFactory* alarm_factory, | |
| 155 const QuicCryptoServerConfig* crypto_config, | |
| 156 QuicCompressedCertsCache* compressed_certs_cache, | |
| 157 TestQuicSpdyServerSession** session) { | |
| 158 MockServerConnection* connection = new MockServerConnection( | |
| 159 connection_id, helper, alarm_factory, dispatcher); | |
| 160 *session = new TestQuicSpdyServerSession(config, connection, crypto_config, | |
| 161 compressed_certs_cache); | |
| 162 connection->set_visitor(*session); | |
| 163 ON_CALL(*connection, CloseConnection(_, _, _)) | |
| 164 .WillByDefault(WithoutArgs(Invoke( | |
| 165 connection, &MockServerConnection::UnregisterOnConnectionClosed))); | |
| 166 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>((*session)->connection()), | |
| 167 ProcessUdpPacket(_, client_address, _)); | |
| 168 | |
| 169 return *session; | |
| 170 } | |
| 171 | |
| 172 class QuicDispatcherTest : public ::testing::Test { | 160 class QuicDispatcherTest : public ::testing::Test { |
| 173 public: | 161 public: |
| 174 QuicDispatcherTest() | 162 QuicDispatcherTest() |
| 175 : helper_(&eps_, QuicAllocator::BUFFER_POOL), | 163 : helper_(&eps_, QuicAllocator::BUFFER_POOL), |
| 176 alarm_factory_(&eps_), | 164 alarm_factory_(&eps_), |
| 177 version_manager_(QuicSupportedVersions()), | 165 version_manager_(QuicSupportedVersions()), |
| 178 crypto_config_(QuicCryptoServerConfig::TESTING, | 166 crypto_config_(QuicCryptoServerConfig::TESTING, |
| 179 QuicRandom::GetInstance(), | 167 QuicRandom::GetInstance(), |
| 180 CryptoTestUtils::ProofSourceForTesting()), | 168 CryptoTestUtils::ProofSourceForTesting()), |
| 181 dispatcher_(new TestDispatcher(config_, | 169 dispatcher_(new TestDispatcher(config_, |
| 182 &crypto_config_, | 170 &crypto_config_, |
| 183 &version_manager_, | 171 &version_manager_, |
| 184 &eps_)), | 172 &eps_)), |
| 185 time_wait_list_manager_(nullptr), | 173 time_wait_list_manager_(nullptr), |
| 186 session1_(nullptr), | 174 session1_(nullptr), |
| 187 session2_(nullptr) { | 175 session2_(nullptr), |
| 176 store_(nullptr) {} |
| 177 |
| 178 void SetUp() override { |
| 188 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); | 179 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); |
| 189 } | 180 } |
| 190 | 181 |
| 191 ~QuicDispatcherTest() override {} | 182 ~QuicDispatcherTest() override {} |
| 192 | 183 |
| 193 MockQuicConnection* connection1() { | 184 MockQuicConnection* connection1() { |
| 194 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); | 185 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); |
| 195 } | 186 } |
| 196 | 187 |
| 197 MockQuicConnection* connection2() { | 188 MockQuicConnection* connection2() { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 QuicConnectionIdLength connection_id_length, | 240 QuicConnectionIdLength connection_id_length, |
| 250 QuicPacketNumberLength packet_number_length, | 241 QuicPacketNumberLength packet_number_length, |
| 251 QuicPacketNumber packet_number) { | 242 QuicPacketNumber packet_number) { |
| 252 QuicVersionVector versions(SupportedVersions(version)); | 243 QuicVersionVector versions(SupportedVersions(version)); |
| 253 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( | 244 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( |
| 254 connection_id, has_version_flag, false, false, 0, packet_number, data, | 245 connection_id, has_version_flag, false, false, 0, packet_number, data, |
| 255 connection_id_length, packet_number_length, &versions)); | 246 connection_id_length, packet_number_length, &versions)); |
| 256 std::unique_ptr<QuicReceivedPacket> received_packet( | 247 std::unique_ptr<QuicReceivedPacket> received_packet( |
| 257 ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); | 248 ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); |
| 258 | 249 |
| 259 data_ = string(packet->data(), packet->length()); | 250 if (ChloExtractor::Extract(*packet, versions, nullptr)) { |
| 251 // Add CHLO packet to the beginning to be verified first, because it is |
| 252 // also processed first by new session. |
| 253 data_connection_map_[connection_id].push_front( |
| 254 string(packet->data(), packet->length())); |
| 255 } else { |
| 256 // For non-CHLO, always append to last. |
| 257 data_connection_map_[connection_id].push_back( |
| 258 string(packet->data(), packet->length())); |
| 259 } |
| 260 dispatcher_->ProcessPacket(server_address_, client_address, | 260 dispatcher_->ProcessPacket(server_address_, client_address, |
| 261 *received_packet); | 261 *received_packet); |
| 262 } | 262 } |
| 263 | 263 |
| 264 void ValidatePacket(const QuicEncryptedPacket& packet) { | 264 void ValidatePacket(QuicConnectionId conn_id, |
| 265 EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); | 265 const QuicEncryptedPacket& packet) { |
| 266 EXPECT_EQ(data_, packet.AsStringPiece()); | 266 EXPECT_EQ(data_connection_map_[conn_id].front().length(), |
| 267 packet.AsStringPiece().length()); |
| 268 EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece()); |
| 269 data_connection_map_[conn_id].pop_front(); |
| 270 } |
| 271 |
| 272 QuicServerSessionBase* CreateSession( |
| 273 QuicDispatcher* dispatcher, |
| 274 const QuicConfig& config, |
| 275 QuicConnectionId connection_id, |
| 276 const IPEndPoint& client_address, |
| 277 MockQuicConnectionHelper* helper, |
| 278 MockAlarmFactory* alarm_factory, |
| 279 const QuicCryptoServerConfig* crypto_config, |
| 280 QuicCompressedCertsCache* compressed_certs_cache, |
| 281 TestQuicSpdyServerSession** session) { |
| 282 MockServerConnection* connection = new MockServerConnection( |
| 283 connection_id, helper, alarm_factory, dispatcher); |
| 284 *session = new TestQuicSpdyServerSession(config, connection, crypto_config, |
| 285 compressed_certs_cache); |
| 286 connection->set_visitor(*session); |
| 287 ON_CALL(*connection, CloseConnection(_, _, _)) |
| 288 .WillByDefault(WithoutArgs(Invoke( |
| 289 connection, &MockServerConnection::UnregisterOnConnectionClosed))); |
| 290 return *session; |
| 267 } | 291 } |
| 268 | 292 |
| 269 void CreateTimeWaitListManager() { | 293 void CreateTimeWaitListManager() { |
| 270 time_wait_list_manager_ = new MockTimeWaitListManager( | 294 time_wait_list_manager_ = new MockTimeWaitListManager( |
| 271 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), | 295 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), |
| 272 &helper_, &alarm_factory_); | 296 &helper_, &alarm_factory_); |
| 273 // dispatcher_ takes the ownership of time_wait_list_manager_. | 297 // dispatcher_ takes the ownership of time_wait_list_manager_. |
| 274 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), | 298 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), |
| 275 time_wait_list_manager_); | 299 time_wait_list_manager_); |
| 276 } | 300 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 287 QuicEpollAlarmFactory alarm_factory_; | 311 QuicEpollAlarmFactory alarm_factory_; |
| 288 MockAlarmFactory mock_alarm_factory_; | 312 MockAlarmFactory mock_alarm_factory_; |
| 289 QuicConfig config_; | 313 QuicConfig config_; |
| 290 QuicVersionManager version_manager_; | 314 QuicVersionManager version_manager_; |
| 291 QuicCryptoServerConfig crypto_config_; | 315 QuicCryptoServerConfig crypto_config_; |
| 292 IPEndPoint server_address_; | 316 IPEndPoint server_address_; |
| 293 std::unique_ptr<TestDispatcher> dispatcher_; | 317 std::unique_ptr<TestDispatcher> dispatcher_; |
| 294 MockTimeWaitListManager* time_wait_list_manager_; | 318 MockTimeWaitListManager* time_wait_list_manager_; |
| 295 TestQuicSpdyServerSession* session1_; | 319 TestQuicSpdyServerSession* session1_; |
| 296 TestQuicSpdyServerSession* session2_; | 320 TestQuicSpdyServerSession* session2_; |
| 297 string data_; | 321 std::map<QuicConnectionId, std::list<string>> data_connection_map_; |
| 322 QuicBufferedPacketStore* store_; |
| 298 }; | 323 }; |
| 299 | 324 |
| 300 TEST_F(QuicDispatcherTest, ProcessPackets) { | 325 TEST_F(QuicDispatcherTest, ProcessPackets) { |
| 301 IPEndPoint client_address(net::test::Loopback4(), 1); | 326 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 302 server_address_ = IPEndPoint(net::test::Any4(), 5); | 327 server_address_ = IPEndPoint(net::test::Any4(), 5); |
| 303 | 328 |
| 304 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) | 329 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) |
| 305 .WillOnce(testing::Return(CreateSession( | 330 .WillOnce(testing::Return(CreateSession( |
| 306 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 331 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
| 307 &mock_alarm_factory_, &crypto_config_, | 332 &mock_alarm_factory_, &crypto_config_, |
| 308 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 333 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 334 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 335 ProcessUdpPacket(_, _, _)) |
| 336 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 337 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 309 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 338 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
| 310 EXPECT_EQ(client_address, dispatcher_->current_client_address()); | 339 EXPECT_EQ(client_address, dispatcher_->current_client_address()); |
| 311 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); | 340 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); |
| 312 | 341 |
| 313 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address)) | 342 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address)) |
| 314 .WillOnce(testing::Return(CreateSession( | 343 .WillOnce(testing::Return(CreateSession( |
| 315 dispatcher_.get(), config_, 2, client_address, &mock_helper_, | 344 dispatcher_.get(), config_, 2, client_address, &mock_helper_, |
| 316 &mock_alarm_factory_, &crypto_config_, | 345 &mock_alarm_factory_, &crypto_config_, |
| 317 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); | 346 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); |
| 347 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()), |
| 348 ProcessUdpPacket(_, _, _)) |
| 349 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 350 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); |
| 318 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); | 351 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); |
| 319 | 352 |
| 320 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 353 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 321 ProcessUdpPacket(_, _, _)) | 354 ProcessUdpPacket(_, _, _)) |
| 322 .Times(1) | 355 .Times(1) |
| 323 .WillOnce(testing::WithArgs<2>( | 356 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 324 Invoke(this, &QuicDispatcherTest::ValidatePacket))); | 357 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 325 ProcessPacket(client_address, 1, false, false, "data"); | 358 ProcessPacket(client_address, 1, false, false, "data"); |
| 326 } | 359 } |
| 327 | 360 |
| 328 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { | 361 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { |
| 329 IPEndPoint client_address(net::test::Loopback4(), 1); | 362 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 330 server_address_ = IPEndPoint(net::test::Any4(), 5); | 363 server_address_ = IPEndPoint(net::test::Any4(), 5); |
| 331 | 364 |
| 332 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0); | 365 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0); |
| 333 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1); | 366 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1); |
| 334 ProcessPacket(client_address, 1, true, version, SerializeCHLO(), | 367 ProcessPacket(client_address, 1, true, version, SerializeCHLO(), |
| 335 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); | 368 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); |
| 336 } | 369 } |
| 337 | 370 |
| 338 TEST_F(QuicDispatcherTest, Shutdown) { | 371 TEST_F(QuicDispatcherTest, Shutdown) { |
| 339 IPEndPoint client_address(net::test::Loopback4(), 1); | 372 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 340 | 373 |
| 341 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 374 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
| 342 .WillOnce(testing::Return(CreateSession( | 375 .WillOnce(testing::Return(CreateSession( |
| 343 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 376 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
| 344 &mock_alarm_factory_, &crypto_config_, | 377 &mock_alarm_factory_, &crypto_config_, |
| 345 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 378 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 379 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 380 ProcessUdpPacket(_, _, _)) |
| 381 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 382 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 346 | 383 |
| 347 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 384 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
| 348 | 385 |
| 349 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 386 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 350 CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 387 CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
| 351 | 388 |
| 352 dispatcher_->Shutdown(); | 389 dispatcher_->Shutdown(); |
| 353 } | 390 } |
| 354 | 391 |
| 355 TEST_F(QuicDispatcherTest, TimeWaitListManager) { | 392 TEST_F(QuicDispatcherTest, TimeWaitListManager) { |
| 356 CreateTimeWaitListManager(); | 393 CreateTimeWaitListManager(); |
| 357 | 394 |
| 358 // Create a new session. | 395 // Create a new session. |
| 359 IPEndPoint client_address(net::test::Loopback4(), 1); | 396 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 360 QuicConnectionId connection_id = 1; | 397 QuicConnectionId connection_id = 1; |
| 361 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 398 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 362 .WillOnce(testing::Return(CreateSession( | 399 .WillOnce(testing::Return(CreateSession( |
| 363 dispatcher_.get(), config_, connection_id, client_address, | 400 dispatcher_.get(), config_, connection_id, client_address, |
| 364 &mock_helper_, &mock_alarm_factory_, &crypto_config_, | 401 &mock_helper_, &mock_alarm_factory_, &crypto_config_, |
| 365 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 402 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 403 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 404 ProcessUdpPacket(_, _, _)) |
| 405 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 406 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 407 |
| 366 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); | 408 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); |
| 367 | 409 |
| 368 // Close the connection by sending public reset packet. | 410 // Close the connection by sending public reset packet. |
| 369 QuicPublicResetPacket packet; | 411 QuicPublicResetPacket packet; |
| 370 packet.public_header.connection_id = connection_id; | 412 packet.public_header.connection_id = connection_id; |
| 371 packet.public_header.reset_flag = true; | 413 packet.public_header.reset_flag = true; |
| 372 packet.public_header.version_flag = false; | 414 packet.public_header.version_flag = false; |
| 373 packet.rejected_packet_number = 19191; | 415 packet.rejected_packet_number = 19191; |
| 374 packet.nonce_proof = 132232; | 416 packet.nonce_proof = 132232; |
| 375 std::unique_ptr<QuicEncryptedPacket> encrypted( | 417 std::unique_ptr<QuicEncryptedPacket> encrypted( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { | 475 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { |
| 434 IPEndPoint client_address(net::test::Loopback4(), 1); | 476 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 435 QuicConnectionId connection_id = 1; | 477 QuicConnectionId connection_id = 1; |
| 436 server_address_ = IPEndPoint(net::test::Any4(), 5); | 478 server_address_ = IPEndPoint(net::test::Any4(), 5); |
| 437 | 479 |
| 438 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) | 480 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) |
| 439 .WillOnce(testing::Return(CreateSession( | 481 .WillOnce(testing::Return(CreateSession( |
| 440 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 482 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
| 441 &mock_alarm_factory_, &crypto_config_, | 483 &mock_alarm_factory_, &crypto_config_, |
| 442 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 484 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 485 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 486 ProcessUdpPacket(_, _, _)) |
| 487 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 488 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 443 // A packet whose packet number is the largest that is allowed to start a | 489 // A packet whose packet number is the largest that is allowed to start a |
| 444 // connection. | 490 // connection. |
| 445 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), | 491 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), |
| 446 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, | 492 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 447 kDefaultPathId, | 493 kDefaultPathId, |
| 448 QuicDispatcher::kMaxReasonableInitialPacketNumber); | 494 QuicDispatcher::kMaxReasonableInitialPacketNumber); |
| 449 EXPECT_EQ(client_address, dispatcher_->current_client_address()); | 495 EXPECT_EQ(client_address, dispatcher_->current_client_address()); |
| 450 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); | 496 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); |
| 451 } | 497 } |
| 452 | 498 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 } | 575 } |
| 530 } | 576 } |
| 531 } | 577 } |
| 532 return params; | 578 return params; |
| 533 } | 579 } |
| 534 | 580 |
| 535 class QuicDispatcherStatelessRejectTest | 581 class QuicDispatcherStatelessRejectTest |
| 536 : public QuicDispatcherTest, | 582 : public QuicDispatcherTest, |
| 537 public ::testing::WithParamInterface<StatelessRejectTestParams> { | 583 public ::testing::WithParamInterface<StatelessRejectTestParams> { |
| 538 public: | 584 public: |
| 539 QuicDispatcherStatelessRejectTest() : crypto_stream1_(nullptr) {} | 585 QuicDispatcherStatelessRejectTest() |
| 586 : QuicDispatcherTest(), crypto_stream1_(nullptr) {} |
| 540 | 587 |
| 541 ~QuicDispatcherStatelessRejectTest() override { | 588 ~QuicDispatcherStatelessRejectTest() override { |
| 542 if (crypto_stream1_) { | 589 if (crypto_stream1_) { |
| 543 delete crypto_stream1_; | 590 delete crypto_stream1_; |
| 544 } | 591 } |
| 545 } | 592 } |
| 546 | 593 |
| 547 // This test setup assumes that all testing will be done using | 594 // This test setup assumes that all testing will be done using |
| 548 // crypto_stream1_. | 595 // crypto_stream1_. |
| 549 void SetUp() override { | 596 void SetUp() override { |
| 597 QuicDispatcherTest::SetUp(); |
| 550 FLAGS_enable_quic_stateless_reject_support = | 598 FLAGS_enable_quic_stateless_reject_support = |
| 551 GetParam().enable_stateless_rejects_via_flag; | 599 GetParam().enable_stateless_rejects_via_flag; |
| 552 } | 600 } |
| 553 | 601 |
| 554 // Returns true or false, depending on whether the server will emit | 602 // Returns true or false, depending on whether the server will emit |
| 555 // a stateless reject, depending upon the parameters of the test. | 603 // a stateless reject, depending upon the parameters of the test. |
| 556 bool ExpectStatelessReject() { | 604 bool ExpectStatelessReject() { |
| 557 return GetParam().enable_stateless_rejects_via_flag && | 605 return GetParam().enable_stateless_rejects_via_flag && |
| 558 !GetParam().crypto_handshake_successful && | 606 !GetParam().crypto_handshake_successful && |
| 559 GetParam().client_supports_statelesss_rejects; | 607 GetParam().client_supports_statelesss_rejects; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 590 ::testing::ValuesIn(GetStatelessRejectTestParams())); | 638 ::testing::ValuesIn(GetStatelessRejectTestParams())); |
| 591 | 639 |
| 592 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) { | 640 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) { |
| 593 CreateTimeWaitListManager(); | 641 CreateTimeWaitListManager(); |
| 594 | 642 |
| 595 IPEndPoint client_address(net::test::Loopback4(), 1); | 643 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 596 QuicConnectionId connection_id = 1; | 644 QuicConnectionId connection_id = 1; |
| 597 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 645 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 598 .WillOnce(testing::Return( | 646 .WillOnce(testing::Return( |
| 599 CreateSessionBasedOnTestParams(connection_id, client_address))); | 647 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 600 | 648 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 649 ProcessUdpPacket(_, _, _)) |
| 650 .WillOnce(testing::WithArgs<2>( |
| 651 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 652 base::Unretained(this), connection_id)))); |
| 601 // Process the first packet for the connection. | 653 // Process the first packet for the connection. |
| 602 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); | 654 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); |
| 603 if (ExpectStatelessReject()) { | 655 if (ExpectStatelessReject()) { |
| 604 // If this is a stateless reject, the crypto stream will close the | 656 // If this is a stateless reject, the crypto stream will close the |
| 605 // connection. | 657 // connection. |
| 606 session1_->connection()->CloseConnection( | 658 session1_->connection()->CloseConnection( |
| 607 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", | 659 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", |
| 608 ConnectionCloseBehavior::SILENT_CLOSE); | 660 ConnectionCloseBehavior::SILENT_CLOSE); |
| 609 } | 661 } |
| 610 | 662 |
| 611 // Send a second packet and check the results. If this is a stateless reject, | 663 // Send a second packet and check the results. If this is a stateless reject, |
| 612 // the existing connection_id will go on the time-wait list. | 664 // the existing connection_id will go on the time-wait list. |
| 613 EXPECT_EQ(ExpectStatelessReject(), | 665 EXPECT_EQ(ExpectStatelessReject(), |
| 614 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 666 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 615 if (ExpectStatelessReject()) { | 667 if (ExpectStatelessReject()) { |
| 616 // The second packet will be processed on the time-wait list. | 668 // The second packet will be processed on the time-wait list. |
| 617 EXPECT_CALL(*time_wait_list_manager_, | 669 EXPECT_CALL(*time_wait_list_manager_, |
| 618 ProcessPacket(_, _, connection_id, _, _)) | 670 ProcessPacket(_, _, connection_id, _, _)) |
| 619 .Times(1); | 671 .Times(1); |
| 620 } else { | 672 } else { |
| 621 // The second packet will trigger a packet-validation | 673 // The second packet will trigger a packet-validation |
| 622 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 674 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 623 ProcessUdpPacket(_, _, _)) | 675 ProcessUdpPacket(_, _, _)) |
| 624 .Times(1) | 676 .Times(1) |
| 625 .WillOnce(testing::WithArgs<2>( | 677 .WillOnce(testing::WithArgs<2>( |
| 626 Invoke(this, &QuicDispatcherTest::ValidatePacket))); | 678 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 679 base::Unretained(this), connection_id)))); |
| 627 } | 680 } |
| 628 ProcessPacket(client_address, connection_id, true, false, "data"); | 681 ProcessPacket(client_address, connection_id, true, false, "data"); |
| 629 } | 682 } |
| 630 | 683 |
| 631 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { | 684 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { |
| 632 FLAGS_quic_use_cheap_stateless_rejects = true; | 685 FLAGS_quic_use_cheap_stateless_rejects = true; |
| 686 FLAGS_quic_buffer_packet_till_chlo = true; |
| 633 CreateTimeWaitListManager(); | 687 CreateTimeWaitListManager(); |
| 634 | 688 |
| 635 IPEndPoint client_address(net::test::Loopback4(), 1); | 689 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 636 QuicConnectionId connection_id = 1; | 690 QuicConnectionId connection_id = 1; |
| 637 if (GetParam().enable_stateless_rejects_via_flag) { | 691 if (GetParam().enable_stateless_rejects_via_flag) { |
| 638 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 692 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 639 .Times(0); | 693 .Times(0); |
| 640 } else { | 694 } else { |
| 641 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 695 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 642 .WillOnce(testing::Return( | 696 .WillOnce(testing::Return( |
| 643 CreateSessionBasedOnTestParams(connection_id, client_address))); | 697 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 698 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 699 ProcessUdpPacket(_, _, _)) |
| 700 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 701 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 644 } | 702 } |
| 645 | 703 |
| 646 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); | 704 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); |
| 647 VLOG(1) << "Params: " << GetParam(); | 705 VLOG(1) << "Params: " << GetParam(); |
| 648 // Process the first packet for the connection. | 706 // Process the first packet for the connection. |
| 649 // clang-format off | 707 // clang-format off |
| 650 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 708 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 651 "CHLO", | 709 "CHLO", |
| 652 "AEAD", "AESG", | 710 "AEAD", "AESG", |
| 653 "KEXS", "C255", | 711 "KEXS", "C255", |
| 654 "COPT", "SREJ", | 712 "COPT", "SREJ", |
| 655 "NONC", "1234567890123456789012", | 713 "NONC", "1234567890123456789012", |
| 656 "VER\0", "Q025", | 714 "VER\0", "Q025", |
| 657 "$padding", static_cast<int>(kClientHelloMinimumSize), | 715 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 658 nullptr); | 716 nullptr); |
| 659 // clang-format on | 717 // clang-format on |
| 660 | 718 |
| 661 ProcessPacket(client_address, connection_id, true, false, | 719 ProcessPacket(client_address, connection_id, true, false, |
| 662 client_hello.GetSerialized().AsStringPiece().as_string()); | 720 client_hello.GetSerialized().AsStringPiece().as_string()); |
| 663 | 721 |
| 664 if (GetParam().enable_stateless_rejects_via_flag) { | 722 if (GetParam().enable_stateless_rejects_via_flag) { |
| 665 EXPECT_EQ(true, | 723 EXPECT_EQ(true, |
| 666 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 724 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 667 } | 725 } |
| 668 } | 726 } |
| 669 | 727 |
| 670 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { | 728 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { |
| 671 FLAGS_quic_use_cheap_stateless_rejects = true; | 729 FLAGS_quic_use_cheap_stateless_rejects = true; |
| 730 FLAGS_quic_always_log_bugs_for_tests = true; |
| 672 CreateTimeWaitListManager(); | 731 CreateTimeWaitListManager(); |
| 673 | 732 |
| 674 const IPEndPoint client_address(net::test::Loopback4(), 1); | 733 const IPEndPoint client_address(net::test::Loopback4(), 1); |
| 675 const QuicConnectionId connection_id = 1; | 734 const QuicConnectionId connection_id = 1; |
| 676 | 735 |
| 677 if (!GetParam().enable_stateless_rejects_via_flag) { | 736 if (!GetParam().enable_stateless_rejects_via_flag && |
| 678 // If stateless rejects are not being used, then a connection will be | 737 !FLAGS_quic_buffer_packet_till_chlo) { |
| 679 // created immediately. | 738 // If stateless rejects are not being used and early arrived packets are not |
| 739 // buffered, then a connection will be created immediately. |
| 680 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 740 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 681 .WillOnce(testing::Return( | 741 .WillOnce(testing::Return( |
| 682 CreateSessionBasedOnTestParams(connection_id, client_address))); | 742 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 743 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 744 ProcessUdpPacket(_, client_address, _)) |
| 745 .WillOnce(testing::WithArg<2>( |
| 746 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 747 base::Unretained(this), connection_id)))); |
| 683 } | 748 } |
| 684 ProcessPacket(client_address, connection_id, true, false, | 749 bool first_packet_dropped = GetParam().enable_stateless_rejects_via_flag && |
| 685 "NOT DATA FOR A CHLO"); | 750 !FLAGS_quic_buffer_packet_till_chlo; |
| 751 if (first_packet_dropped) { |
| 752 // Never do stateless reject while |
| 753 // FLAGS_quic_buffer_packet_till_chlo is off. |
| 754 EXPECT_DFATAL( |
| 755 ProcessPacket(client_address, connection_id, true, false, |
| 756 "NOT DATA FOR A CHLO"), |
| 757 "Have to drop packet because buffering non-chlo packet is " |
| 758 "not supported while trying to do stateless reject. " |
| 759 "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false " |
| 760 "--gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"); |
| 761 } else { |
| 762 ProcessPacket(client_address, connection_id, true, false, |
| 763 "NOT DATA FOR A CHLO"); |
| 764 } |
| 686 | 765 |
| 687 // Process the first packet for the connection. | 766 // Process the first packet for the connection. |
| 688 // clang-format off | 767 // clang-format off |
| 689 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 768 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 690 "CHLO", | 769 "CHLO", |
| 691 "AEAD", "AESG", | 770 "AEAD", "AESG", |
| 692 "KEXS", "C255", | 771 "KEXS", "C255", |
| 693 "NONC", "1234567890123456789012", | 772 "NONC", "1234567890123456789012", |
| 694 "VER\0", "Q025", | 773 "VER\0", "Q025", |
| 695 "$padding", static_cast<int>(kClientHelloMinimumSize), | 774 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 696 nullptr); | 775 nullptr); |
| 697 // clang-format on | 776 // clang-format on |
| 698 | 777 |
| 699 if (GetParam().enable_stateless_rejects_via_flag) { | 778 if (GetParam().enable_stateless_rejects_via_flag || |
| 779 FLAGS_quic_buffer_packet_till_chlo) { |
| 700 // If stateless rejects are enabled then a connection will be created now | 780 // If stateless rejects are enabled then a connection will be created now |
| 701 // and the buffered packet will be processed | 781 // and the buffered packet will be processed |
| 702 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 782 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 703 .WillOnce(testing::Return( | 783 .WillOnce(testing::Return( |
| 704 CreateSessionBasedOnTestParams(connection_id, client_address))); | 784 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 785 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 786 ProcessUdpPacket(_, client_address, _)) |
| 787 .WillOnce(testing::WithArg<2>( |
| 788 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 789 base::Unretained(this), connection_id)))); |
| 705 } | 790 } |
| 706 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 791 if (!first_packet_dropped) { |
| 707 ProcessUdpPacket(_, client_address, _)) | 792 // Expect both packets to be passed to ProcessUdpPacket(). And one of them |
| 708 .RetiresOnSaturation(); | 793 // is already expected in CreateSessionBasedOnTestParams(). |
| 794 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 795 ProcessUdpPacket(_, client_address, _)) |
| 796 .WillOnce(testing::WithArg<2>( |
| 797 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 798 base::Unretained(this), connection_id)))) |
| 799 .RetiresOnSaturation(); |
| 800 } else { |
| 801 // Since first packet is dropped, remove it from map to skip |
| 802 // ValidatePacket() on it. |
| 803 data_connection_map_[connection_id].pop_front(); |
| 804 } |
| 709 ProcessPacket(client_address, connection_id, true, false, | 805 ProcessPacket(client_address, connection_id, true, false, |
| 710 client_hello.GetSerialized().AsStringPiece().as_string()); | 806 client_hello.GetSerialized().AsStringPiece().as_string()); |
| 711 EXPECT_FALSE( | 807 EXPECT_FALSE( |
| 712 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 808 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 713 } | 809 } |
| 714 | 810 |
| 715 // Verify the stopgap test: Packets with truncated connection IDs should be | 811 // Verify the stopgap test: Packets with truncated connection IDs should be |
| 716 // dropped. | 812 // dropped. |
| 717 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {}; | 813 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {}; |
| 718 | 814 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 LOG(DFATAL) << "Not supported"; | 848 LOG(DFATAL) << "Not supported"; |
| 753 return WriteResult(); | 849 return WriteResult(); |
| 754 } | 850 } |
| 755 | 851 |
| 756 bool write_blocked_; | 852 bool write_blocked_; |
| 757 }; | 853 }; |
| 758 | 854 |
| 759 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { | 855 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { |
| 760 public: | 856 public: |
| 761 void SetUp() override { | 857 void SetUp() override { |
| 858 QuicDispatcherTest::SetUp(); |
| 762 writer_ = new BlockingWriter; | 859 writer_ = new BlockingWriter; |
| 763 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); | 860 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); |
| 764 | 861 |
| 765 IPEndPoint client_address(net::test::Loopback4(), 1); | 862 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 766 | 863 |
| 767 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 864 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
| 768 .WillOnce(testing::Return(CreateSession( | 865 .WillOnce(testing::Return(CreateSession( |
| 769 dispatcher_.get(), config_, 1, client_address, &helper_, | 866 dispatcher_.get(), config_, 1, client_address, &helper_, |
| 770 &alarm_factory_, &crypto_config_, | 867 &alarm_factory_, &crypto_config_, |
| 771 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 868 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 869 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 870 ProcessUdpPacket(_, _, _)) |
| 871 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 872 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 772 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 873 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
| 773 | 874 |
| 774 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 875 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
| 775 .WillOnce(testing::Return(CreateSession( | 876 .WillOnce(testing::Return(CreateSession( |
| 776 dispatcher_.get(), config_, 2, client_address, &helper_, | 877 dispatcher_.get(), config_, 2, client_address, &helper_, |
| 777 &alarm_factory_, &crypto_config_, | 878 &alarm_factory_, &crypto_config_, |
| 778 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); | 879 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); |
| 880 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()), |
| 881 ProcessUdpPacket(_, _, _)) |
| 882 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 883 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); |
| 779 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); | 884 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); |
| 780 | 885 |
| 781 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); | 886 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); |
| 782 } | 887 } |
| 783 | 888 |
| 784 void TearDown() override { | 889 void TearDown() override { |
| 785 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 890 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
| 786 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 891 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
| 787 dispatcher_->Shutdown(); | 892 dispatcher_->Shutdown(); |
| 788 } | 893 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); | 1030 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); |
| 926 dispatcher_->OnCanWrite(); | 1031 dispatcher_->OnCanWrite(); |
| 927 EXPECT_TRUE(dispatcher_->HasPendingWrites()); | 1032 EXPECT_TRUE(dispatcher_->HasPendingWrites()); |
| 928 | 1033 |
| 929 // And we'll resume where we left off when we get another call. | 1034 // And we'll resume where we left off when we get another call. |
| 930 EXPECT_CALL(*connection2(), OnCanWrite()); | 1035 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 931 dispatcher_->OnCanWrite(); | 1036 dispatcher_->OnCanWrite(); |
| 932 EXPECT_FALSE(dispatcher_->HasPendingWrites()); | 1037 EXPECT_FALSE(dispatcher_->HasPendingWrites()); |
| 933 } | 1038 } |
| 934 | 1039 |
| 1040 // Tests that bufferring packets works in stateful reject, expensive stateless |
| 1041 // reject and cheap stateless reject. |
| 1042 struct BufferedPacketStoreTestParams { |
| 1043 BufferedPacketStoreTestParams(bool enable_stateless_rejects_via_flag, |
| 1044 bool support_cheap_stateless_reject) |
| 1045 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag), |
| 1046 support_cheap_stateless_reject(support_cheap_stateless_reject) {} |
| 1047 |
| 1048 friend ostream& operator<<(ostream& os, |
| 1049 const BufferedPacketStoreTestParams& p) { |
| 1050 os << "{ enable_stateless_rejects_via_flag: " |
| 1051 << p.enable_stateless_rejects_via_flag << std::endl; |
| 1052 os << " support_cheap_stateless_reject: " |
| 1053 << p.support_cheap_stateless_reject << " }"; |
| 1054 return os; |
| 1055 } |
| 1056 |
| 1057 // This only enables the stateless reject feature via the feature-flag. |
| 1058 // This should be a no-op if the peer does not support them. |
| 1059 bool enable_stateless_rejects_via_flag; |
| 1060 // Whether to do cheap stateless or not. |
| 1061 bool support_cheap_stateless_reject; |
| 1062 }; |
| 1063 |
| 1064 vector<BufferedPacketStoreTestParams> GetBufferedPacketStoreTestParams() { |
| 1065 vector<BufferedPacketStoreTestParams> params; |
| 1066 for (bool enable_stateless_rejects_via_flag : {true, false}) { |
| 1067 for (bool support_cheap_stateless_reject : {true, false}) { |
| 1068 params.push_back(BufferedPacketStoreTestParams( |
| 1069 enable_stateless_rejects_via_flag, support_cheap_stateless_reject)); |
| 1070 } |
| 1071 } |
| 1072 return params; |
| 1073 } |
| 1074 |
| 1075 // A dispatcher whose stateless rejector will always ACCEPTs CHLO. |
| 1076 class BufferedPacketStoreTest |
| 1077 : public QuicDispatcherTest, |
| 1078 public ::testing::WithParamInterface<BufferedPacketStoreTestParams> { |
| 1079 public: |
| 1080 BufferedPacketStoreTest() |
| 1081 : QuicDispatcherTest(), client_addr_(Loopback4(), 1234) { |
| 1082 FLAGS_quic_buffer_packet_till_chlo = true; |
| 1083 FLAGS_quic_use_cheap_stateless_rejects = |
| 1084 GetParam().support_cheap_stateless_reject; |
| 1085 FLAGS_enable_quic_stateless_reject_support = |
| 1086 GetParam().enable_stateless_rejects_via_flag; |
| 1087 } |
| 1088 |
| 1089 void SetUp() override { |
| 1090 QuicDispatcherTest::SetUp(); |
| 1091 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock(); |
| 1092 |
| 1093 QuicVersion version = QuicSupportedVersions().front(); |
| 1094 CryptoHandshakeMessage chlo = CryptoTestUtils::GenerateDefaultInchoateCHLO( |
| 1095 clock_, version, &crypto_config_); |
| 1096 chlo.SetVector(net::kCOPT, net::QuicTagVector{net::kSREJ}); |
| 1097 // Pass an inchoate CHLO. |
| 1098 CryptoTestUtils::GenerateFullCHLO( |
| 1099 chlo, &crypto_config_, server_ip_, client_addr_, version, clock_, |
| 1100 &proof_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &full_chlo_); |
| 1101 } |
| 1102 |
| 1103 string SerializeFullCHLO() { |
| 1104 return full_chlo_.GetSerialized().AsStringPiece().as_string(); |
| 1105 } |
| 1106 |
| 1107 protected: |
| 1108 IPAddress server_ip_; |
| 1109 IPEndPoint client_addr_; |
| 1110 QuicCryptoProof proof_; |
| 1111 const QuicClock* clock_; |
| 1112 CryptoHandshakeMessage full_chlo_; |
| 1113 }; |
| 1114 |
| 1115 INSTANTIATE_TEST_CASE_P( |
| 1116 BufferedPacketStoreTests, |
| 1117 BufferedPacketStoreTest, |
| 1118 ::testing::ValuesIn(GetBufferedPacketStoreTestParams())); |
| 1119 |
| 1120 TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) { |
| 1121 InSequence s; |
| 1122 IPEndPoint client_address(Loopback4(), 1); |
| 1123 server_address_ = IPEndPoint(Any4(), 5); |
| 1124 QuicConnectionId conn_id = 1; |
| 1125 // A bunch of non-CHLO should be buffered upon arrival, and the first one |
| 1126 // should trigger OnNewConnectionAdded(). |
| 1127 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)).Times(1); |
| 1128 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) { |
| 1129 ProcessPacket(client_address, conn_id, true, false, |
| 1130 "data packet " + IntToString(i + 1), |
| 1131 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 1132 kDefaultPathId, |
| 1133 /*packet_number=*/i + 1); |
| 1134 } |
| 1135 EXPECT_EQ(0u, dispatcher_->session_map().size()) |
| 1136 << "No session should be created before CHLO arrives."; |
| 1137 |
| 1138 // Pop out the last packet as it is also be dropped by the store. |
| 1139 data_connection_map_[conn_id].pop_back(); |
| 1140 // When CHLO arrives, a new session should be created, and all packets |
| 1141 // buffered should be delivered to the session. |
| 1142 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1143 .WillOnce(testing::Return(CreateSession( |
| 1144 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1145 &mock_alarm_factory_, &crypto_config_, |
| 1146 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1147 |
| 1148 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they |
| 1149 // should be delivered in arrival order. |
| 1150 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1151 ProcessUdpPacket(_, _, _)) |
| 1152 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO. |
| 1153 .WillRepeatedly(testing::WithArg<2>( |
| 1154 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1155 base::Unretained(this), conn_id)))); |
| 1156 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1157 } |
| 1158 |
| 1159 TEST_P(BufferedPacketStoreTest, |
| 1160 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) { |
| 1161 InSequence s; |
| 1162 server_address_ = IPEndPoint(Any4(), 5); |
| 1163 // A bunch of non-CHLO should be buffered upon arrival. |
| 1164 for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { |
| 1165 IPEndPoint client_address(Loopback4(), i); |
| 1166 QuicConnectionId conn_id = i; |
| 1167 if (i <= kDefaultMaxConnectionsInStore) { |
| 1168 // As they are on different connection, they should trigger |
| 1169 // OnNewConnectionAdded(). The last packet should be dropped. |
| 1170 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
| 1171 } |
| 1172 ProcessPacket(client_address, conn_id, true, false, |
| 1173 "data packet on connection " + IntToString(i), |
| 1174 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 1175 kDefaultPathId, |
| 1176 /*packet_number=*/2); |
| 1177 } |
| 1178 |
| 1179 // Pop out the packet on last connection as it shouldn't be enqueued in store |
| 1180 // as well. |
| 1181 data_connection_map_[kDefaultMaxConnectionsInStore + 1].pop_front(); |
| 1182 |
| 1183 // Process CHLOs. |
| 1184 for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { |
| 1185 IPEndPoint client_address(Loopback4(), i); |
| 1186 QuicConnectionId conn_id = i; |
| 1187 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1188 .WillOnce(testing::Return(CreateSession( |
| 1189 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1190 &mock_alarm_factory_, &crypto_config_, |
| 1191 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1192 if (conn_id == kDefaultMaxConnectionsInStore + 1) { |
| 1193 // The last CHLO should trigger OnNewConnectionAdded() since it's the |
| 1194 // first packet arrives on that connection. |
| 1195 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
| 1196 } |
| 1197 // First |kDefaultMaxConnectionsInStore| connections should have buffered |
| 1198 // a packet in store. The rest should have been dropped. |
| 1199 if (i <= kDefaultMaxConnectionsInStore) { |
| 1200 EXPECT_CALL( |
| 1201 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1202 ProcessUdpPacket(_, client_address, _)) |
| 1203 .Times(2) |
| 1204 .WillRepeatedly(testing::WithArg<2>( |
| 1205 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1206 base::Unretained(this), conn_id)))); |
| 1207 } |
| 1208 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1209 } |
| 1210 } |
| 1211 |
| 1212 // Tests that store delivers empty packet list if CHLO arrives firstly. |
| 1213 TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { |
| 1214 QuicConnectionId conn_id = 1; |
| 1215 IPEndPoint client_address(Loopback4(), 1); |
| 1216 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
| 1217 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1218 .WillOnce(testing::Return(CreateSession( |
| 1219 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1220 &mock_alarm_factory_, &crypto_config_, |
| 1221 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1222 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1223 } |
| 1224 |
| 1225 // Tests that by the time a retransmitted CHLO arrives, a connection for the |
| 1226 // CHLO should already be created. |
| 1227 TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) { |
| 1228 InSequence s; |
| 1229 IPEndPoint client_address(Loopback4(), 1); |
| 1230 server_address_ = IPEndPoint(Any4(), 5); |
| 1231 QuicConnectionId conn_id = 1; |
| 1232 ProcessPacket(client_address, conn_id, true, false, |
| 1233 "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, |
| 1234 PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, |
| 1235 /*packet_number=*/2); |
| 1236 |
| 1237 // When CHLO arrives, a new session should be created, and all packets |
| 1238 // buffered should be delivered to the session. |
| 1239 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1240 .Times(1) // Only triggered by 1st CHLO. |
| 1241 .WillOnce(testing::Return(CreateSession( |
| 1242 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1243 &mock_alarm_factory_, &crypto_config_, |
| 1244 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1245 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1246 ProcessUdpPacket(_, _, _)) |
| 1247 .Times(3) // Triggered by 1 data packet and 2 CHLOs. |
| 1248 .WillRepeatedly(testing::WithArg<2>( |
| 1249 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1250 base::Unretained(this), conn_id)))); |
| 1251 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1252 |
| 1253 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1254 } |
| 1255 |
| 1256 // Tests that expiration of a connection add connection id to time wait list. |
| 1257 TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) { |
| 1258 InSequence s; |
| 1259 CreateTimeWaitListManager(); |
| 1260 QuicBufferedPacketStore* store = |
| 1261 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1262 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock()); |
| 1263 |
| 1264 IPEndPoint client_address(Loopback4(), 1); |
| 1265 server_address_ = IPEndPoint(Any4(), 5); |
| 1266 QuicConnectionId conn_id = 1; |
| 1267 ProcessPacket(client_address, conn_id, true, false, |
| 1268 "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, |
| 1269 PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, |
| 1270 /*packet_number=*/2); |
| 1271 |
| 1272 mock_helper_.AdvanceTime( |
| 1273 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)); |
| 1274 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store); |
| 1275 // Cancel alarm as if it had been fired. |
| 1276 alarm->Cancel(); |
| 1277 store->OnExpirationTimeout(); |
| 1278 // New arrived CHLO will be dropped because this connection is in time wait |
| 1279 // list. |
| 1280 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
| 1281 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _)); |
| 1282 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1283 } |
| 1284 |
| 935 } // namespace | 1285 } // namespace |
| 936 } // namespace test | 1286 } // namespace test |
| 937 } // namespace net | 1287 } // namespace net |
| OLD | NEW |