| 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) |
| 57 : QuicServerSessionBase(config, | 67 : QuicServerSessionBase(config, |
| 58 connection, | 68 connection, |
| 59 nullptr, | 69 nullptr, |
| 60 nullptr, | 70 nullptr, |
| 61 crypto_config, | 71 crypto_config, |
| 62 compressed_certs_cache), | 72 compressed_certs_cache), |
| 63 crypto_stream_(QuicServerSessionBase::GetCryptoStream()) {} | 73 crypto_stream_(QuicServerSessionBase::GetCryptoStream()) {} |
| 64 ~TestQuicSpdyServerSession() override{}; | 74 |
| 75 ~TestQuicSpdyServerSession() override { delete connection(); }; |
| 65 | 76 |
| 66 MOCK_METHOD3(OnConnectionClosed, | 77 MOCK_METHOD3(OnConnectionClosed, |
| 67 void(QuicErrorCode error, | 78 void(QuicErrorCode error, |
| 68 const string& error_details, | 79 const string& error_details, |
| 69 ConnectionCloseSource source)); | 80 ConnectionCloseSource source)); |
| 70 MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); | 81 MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); |
| 71 MOCK_METHOD1(CreateOutgoingDynamicStream, | 82 MOCK_METHOD1(CreateOutgoingDynamicStream, |
| 72 QuicSpdyStream*(SpdyPriority priority)); | 83 QuicSpdyStream*(SpdyPriority priority)); |
| 73 | 84 |
| 74 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( | 85 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)), | 118 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)), |
| 108 std::unique_ptr<QuicServerSessionBase::Helper>( | 119 std::unique_ptr<QuicServerSessionBase::Helper>( |
| 109 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), | 120 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), |
| 110 std::unique_ptr<QuicEpollAlarmFactory>( | 121 std::unique_ptr<QuicEpollAlarmFactory>( |
| 111 new QuicEpollAlarmFactory(eps))) {} | 122 new QuicEpollAlarmFactory(eps))) {} |
| 112 | 123 |
| 113 MOCK_METHOD2(CreateQuicSession, | 124 MOCK_METHOD2(CreateQuicSession, |
| 114 QuicServerSessionBase*(QuicConnectionId connection_id, | 125 QuicServerSessionBase*(QuicConnectionId connection_id, |
| 115 const IPEndPoint& client_address)); | 126 const IPEndPoint& client_address)); |
| 116 | 127 |
| 128 MOCK_METHOD1(OnNewConnectionAdded, void(QuicConnectionId connection_id)); |
| 129 |
| 117 using QuicDispatcher::current_server_address; | 130 using QuicDispatcher::current_server_address; |
| 118 using QuicDispatcher::current_client_address; | 131 using QuicDispatcher::current_client_address; |
| 119 }; | 132 }; |
| 120 | 133 |
| 121 // A Connection class which unregisters the session from the dispatcher when | 134 // A Connection class which unregisters the session from the dispatcher when |
| 122 // sending connection close. | 135 // sending connection close. |
| 123 // 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 |
| 124 // involve a lot more mocking. | 137 // involve a lot more mocking. |
| 125 class MockServerConnection : public MockQuicConnection { | 138 class MockServerConnection : public MockQuicConnection { |
| 126 public: | 139 public: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 137 void UnregisterOnConnectionClosed() { | 150 void UnregisterOnConnectionClosed() { |
| 138 LOG(ERROR) << "Unregistering " << connection_id(); | 151 LOG(ERROR) << "Unregistering " << connection_id(); |
| 139 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR, | 152 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR, |
| 140 "Unregistering."); | 153 "Unregistering."); |
| 141 } | 154 } |
| 142 | 155 |
| 143 private: | 156 private: |
| 144 QuicDispatcher* dispatcher_; | 157 QuicDispatcher* dispatcher_; |
| 145 }; | 158 }; |
| 146 | 159 |
| 147 QuicServerSessionBase* CreateSession( | |
| 148 QuicDispatcher* dispatcher, | |
| 149 const QuicConfig& config, | |
| 150 QuicConnectionId connection_id, | |
| 151 const IPEndPoint& client_address, | |
| 152 MockQuicConnectionHelper* helper, | |
| 153 MockAlarmFactory* alarm_factory, | |
| 154 const QuicCryptoServerConfig* crypto_config, | |
| 155 QuicCompressedCertsCache* compressed_certs_cache, | |
| 156 TestQuicSpdyServerSession** session) { | |
| 157 MockServerConnection* connection = new MockServerConnection( | |
| 158 connection_id, helper, alarm_factory, dispatcher); | |
| 159 *session = new TestQuicSpdyServerSession(config, connection, crypto_config, | |
| 160 compressed_certs_cache); | |
| 161 connection->set_visitor(*session); | |
| 162 ON_CALL(*connection, CloseConnection(_, _, _)) | |
| 163 .WillByDefault(WithoutArgs(Invoke( | |
| 164 connection, &MockServerConnection::UnregisterOnConnectionClosed))); | |
| 165 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>((*session)->connection()), | |
| 166 ProcessUdpPacket(_, client_address, _)); | |
| 167 | |
| 168 return *session; | |
| 169 } | |
| 170 | |
| 171 class QuicDispatcherTest : public ::testing::Test { | 160 class QuicDispatcherTest : public ::testing::Test { |
| 172 public: | 161 public: |
| 173 QuicDispatcherTest() | 162 QuicDispatcherTest() |
| 174 : helper_(&eps_, QuicAllocator::BUFFER_POOL), | 163 : helper_(&eps_, QuicAllocator::BUFFER_POOL), |
| 175 alarm_factory_(&eps_), | 164 alarm_factory_(&eps_), |
| 176 version_manager_(QuicSupportedVersions()), | 165 version_manager_(AllSupportedVersions()), |
| 177 crypto_config_(QuicCryptoServerConfig::TESTING, | 166 crypto_config_(QuicCryptoServerConfig::TESTING, |
| 178 QuicRandom::GetInstance(), | 167 QuicRandom::GetInstance(), |
| 179 CryptoTestUtils::ProofSourceForTesting()), | 168 CryptoTestUtils::ProofSourceForTesting()), |
| 180 dispatcher_(new TestDispatcher(config_, | 169 dispatcher_(new TestDispatcher(config_, |
| 181 &crypto_config_, | 170 &crypto_config_, |
| 182 &version_manager_, | 171 &version_manager_, |
| 183 &eps_)), | 172 &eps_)), |
| 184 time_wait_list_manager_(nullptr), | 173 time_wait_list_manager_(nullptr), |
| 185 session1_(nullptr), | 174 session1_(nullptr), |
| 186 session2_(nullptr) { | 175 session2_(nullptr), |
| 176 store_(nullptr) {} |
| 177 |
| 178 void SetUp() override { |
| 187 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); | 179 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); |
| 188 } | 180 } |
| 189 | 181 |
| 190 ~QuicDispatcherTest() override {} | 182 ~QuicDispatcherTest() override {} |
| 191 | 183 |
| 192 MockQuicConnection* connection1() { | 184 MockQuicConnection* connection1() { |
| 193 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); | 185 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); |
| 194 } | 186 } |
| 195 | 187 |
| 196 MockQuicConnection* connection2() { | 188 MockQuicConnection* connection2() { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 void ProcessPacket(IPEndPoint client_address, | 220 void ProcessPacket(IPEndPoint client_address, |
| 229 QuicConnectionId connection_id, | 221 QuicConnectionId connection_id, |
| 230 bool has_version_flag, | 222 bool has_version_flag, |
| 231 bool has_multipath_flag, | 223 bool has_multipath_flag, |
| 232 const string& data, | 224 const string& data, |
| 233 QuicConnectionIdLength connection_id_length, | 225 QuicConnectionIdLength connection_id_length, |
| 234 QuicPacketNumberLength packet_number_length, | 226 QuicPacketNumberLength packet_number_length, |
| 235 QuicPathId path_id, | 227 QuicPathId path_id, |
| 236 QuicPacketNumber packet_number) { | 228 QuicPacketNumber packet_number) { |
| 237 ProcessPacket(client_address, connection_id, has_version_flag, | 229 ProcessPacket(client_address, connection_id, has_version_flag, |
| 238 QuicSupportedVersions().front(), data, connection_id_length, | 230 CurrentSupportedVersions().front(), data, |
| 239 packet_number_length, packet_number); | 231 connection_id_length, packet_number_length, packet_number); |
| 240 } | 232 } |
| 241 | 233 |
| 242 // Processes a packet. | 234 // Processes a packet. |
| 243 void ProcessPacket(IPEndPoint client_address, | 235 void ProcessPacket(IPEndPoint client_address, |
| 244 QuicConnectionId connection_id, | 236 QuicConnectionId connection_id, |
| 245 bool has_version_flag, | 237 bool has_version_flag, |
| 246 QuicVersion version, | 238 QuicVersion version, |
| 247 const string& data, | 239 const string& data, |
| 248 QuicConnectionIdLength connection_id_length, | 240 QuicConnectionIdLength connection_id_length, |
| 249 QuicPacketNumberLength packet_number_length, | 241 QuicPacketNumberLength packet_number_length, |
| 250 QuicPacketNumber packet_number) { | 242 QuicPacketNumber packet_number) { |
| 251 QuicVersionVector versions(SupportedVersions(version)); | 243 QuicVersionVector versions(SupportedVersions(version)); |
| 252 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( | 244 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( |
| 253 connection_id, has_version_flag, false, false, 0, packet_number, data, | 245 connection_id, has_version_flag, false, false, 0, packet_number, data, |
| 254 connection_id_length, packet_number_length, &versions)); | 246 connection_id_length, packet_number_length, &versions)); |
| 255 std::unique_ptr<QuicReceivedPacket> received_packet( | 247 std::unique_ptr<QuicReceivedPacket> received_packet( |
| 256 ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); | 248 ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); |
| 257 | 249 |
| 258 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 } |
| 259 dispatcher_->ProcessPacket(server_address_, client_address, | 260 dispatcher_->ProcessPacket(server_address_, client_address, |
| 260 *received_packet); | 261 *received_packet); |
| 261 } | 262 } |
| 262 | 263 |
| 263 void ValidatePacket(const QuicEncryptedPacket& packet) { | 264 void ValidatePacket(QuicConnectionId conn_id, |
| 264 EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); | 265 const QuicEncryptedPacket& packet) { |
| 265 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; |
| 266 } | 291 } |
| 267 | 292 |
| 268 void CreateTimeWaitListManager() { | 293 void CreateTimeWaitListManager() { |
| 269 time_wait_list_manager_ = new MockTimeWaitListManager( | 294 time_wait_list_manager_ = new MockTimeWaitListManager( |
| 270 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), | 295 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), |
| 271 &helper_, &alarm_factory_); | 296 &helper_, &alarm_factory_); |
| 272 // dispatcher_ takes the ownership of time_wait_list_manager_. | 297 // dispatcher_ takes the ownership of time_wait_list_manager_. |
| 273 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), | 298 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), |
| 274 time_wait_list_manager_); | 299 time_wait_list_manager_); |
| 275 } | 300 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 286 QuicEpollAlarmFactory alarm_factory_; | 311 QuicEpollAlarmFactory alarm_factory_; |
| 287 MockAlarmFactory mock_alarm_factory_; | 312 MockAlarmFactory mock_alarm_factory_; |
| 288 QuicConfig config_; | 313 QuicConfig config_; |
| 289 QuicVersionManager version_manager_; | 314 QuicVersionManager version_manager_; |
| 290 QuicCryptoServerConfig crypto_config_; | 315 QuicCryptoServerConfig crypto_config_; |
| 291 IPEndPoint server_address_; | 316 IPEndPoint server_address_; |
| 292 std::unique_ptr<TestDispatcher> dispatcher_; | 317 std::unique_ptr<TestDispatcher> dispatcher_; |
| 293 MockTimeWaitListManager* time_wait_list_manager_; | 318 MockTimeWaitListManager* time_wait_list_manager_; |
| 294 TestQuicSpdyServerSession* session1_; | 319 TestQuicSpdyServerSession* session1_; |
| 295 TestQuicSpdyServerSession* session2_; | 320 TestQuicSpdyServerSession* session2_; |
| 296 string data_; | 321 std::map<QuicConnectionId, std::list<string>> data_connection_map_; |
| 322 QuicBufferedPacketStore* store_; |
| 297 }; | 323 }; |
| 298 | 324 |
| 299 TEST_F(QuicDispatcherTest, ProcessPackets) { | 325 TEST_F(QuicDispatcherTest, ProcessPackets) { |
| 300 IPEndPoint client_address(net::test::Loopback4(), 1); | 326 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 301 server_address_ = IPEndPoint(net::test::Any4(), 5); | 327 server_address_ = IPEndPoint(net::test::Any4(), 5); |
| 302 | 328 |
| 303 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) | 329 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) |
| 304 .WillOnce(testing::Return(CreateSession( | 330 .WillOnce(testing::Return(CreateSession( |
| 305 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 331 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
| 306 &mock_alarm_factory_, &crypto_config_, | 332 &mock_alarm_factory_, &crypto_config_, |
| 307 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)))); |
| 308 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 338 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
| 309 EXPECT_EQ(client_address, dispatcher_->current_client_address()); | 339 EXPECT_EQ(client_address, dispatcher_->current_client_address()); |
| 310 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); | 340 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); |
| 311 | 341 |
| 312 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address)) | 342 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address)) |
| 313 .WillOnce(testing::Return(CreateSession( | 343 .WillOnce(testing::Return(CreateSession( |
| 314 dispatcher_.get(), config_, 2, client_address, &mock_helper_, | 344 dispatcher_.get(), config_, 2, client_address, &mock_helper_, |
| 315 &mock_alarm_factory_, &crypto_config_, | 345 &mock_alarm_factory_, &crypto_config_, |
| 316 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)))); |
| 317 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); | 351 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); |
| 318 | 352 |
| 319 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 353 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 320 ProcessUdpPacket(_, _, _)) | 354 ProcessUdpPacket(_, _, _)) |
| 321 .Times(1) | 355 .Times(1) |
| 322 .WillOnce(testing::WithArgs<2>( | 356 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 323 Invoke(this, &QuicDispatcherTest::ValidatePacket))); | 357 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 324 ProcessPacket(client_address, 1, false, false, "data"); | 358 ProcessPacket(client_address, 1, false, false, "data"); |
| 325 } | 359 } |
| 326 | 360 |
| 327 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { | 361 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { |
| 328 IPEndPoint client_address(net::test::Loopback4(), 1); | 362 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 329 server_address_ = IPEndPoint(net::test::Any4(), 5); | 363 server_address_ = IPEndPoint(net::test::Any4(), 5); |
| 330 | 364 |
| 331 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0); | 365 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0); |
| 332 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1); | 366 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1); |
| 333 ProcessPacket(client_address, 1, true, version, SerializeCHLO(), | 367 ProcessPacket(client_address, 1, true, version, SerializeCHLO(), |
| 334 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); | 368 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); |
| 335 } | 369 } |
| 336 | 370 |
| 337 TEST_F(QuicDispatcherTest, Shutdown) { | 371 TEST_F(QuicDispatcherTest, Shutdown) { |
| 338 IPEndPoint client_address(net::test::Loopback4(), 1); | 372 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 339 | 373 |
| 340 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 374 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
| 341 .WillOnce(testing::Return(CreateSession( | 375 .WillOnce(testing::Return(CreateSession( |
| 342 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 376 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
| 343 &mock_alarm_factory_, &crypto_config_, | 377 &mock_alarm_factory_, &crypto_config_, |
| 344 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)))); |
| 345 | 383 |
| 346 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 384 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
| 347 | 385 |
| 348 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 386 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 349 CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 387 CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
| 350 | 388 |
| 351 dispatcher_->Shutdown(); | 389 dispatcher_->Shutdown(); |
| 352 } | 390 } |
| 353 | 391 |
| 354 TEST_F(QuicDispatcherTest, TimeWaitListManager) { | 392 TEST_F(QuicDispatcherTest, TimeWaitListManager) { |
| 355 CreateTimeWaitListManager(); | 393 CreateTimeWaitListManager(); |
| 356 | 394 |
| 357 // Create a new session. | 395 // Create a new session. |
| 358 IPEndPoint client_address(net::test::Loopback4(), 1); | 396 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 359 QuicConnectionId connection_id = 1; | 397 QuicConnectionId connection_id = 1; |
| 360 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 398 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 361 .WillOnce(testing::Return(CreateSession( | 399 .WillOnce(testing::Return(CreateSession( |
| 362 dispatcher_.get(), config_, connection_id, client_address, | 400 dispatcher_.get(), config_, connection_id, client_address, |
| 363 &mock_helper_, &mock_alarm_factory_, &crypto_config_, | 401 &mock_helper_, &mock_alarm_factory_, &crypto_config_, |
| 364 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 |
| 365 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); | 408 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); |
| 366 | 409 |
| 367 // Close the connection by sending public reset packet. | 410 // Close the connection by sending public reset packet. |
| 368 QuicPublicResetPacket packet; | 411 QuicPublicResetPacket packet; |
| 369 packet.public_header.connection_id = connection_id; | 412 packet.public_header.connection_id = connection_id; |
| 370 packet.public_header.reset_flag = true; | 413 packet.public_header.reset_flag = true; |
| 371 packet.public_header.version_flag = false; | 414 packet.public_header.version_flag = false; |
| 372 packet.rejected_packet_number = 19191; | 415 packet.rejected_packet_number = 19191; |
| 373 packet.nonce_proof = 132232; | 416 packet.nonce_proof = 132232; |
| 374 std::unique_ptr<QuicEncryptedPacket> encrypted( | 417 std::unique_ptr<QuicEncryptedPacket> encrypted( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { | 475 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { |
| 433 IPEndPoint client_address(net::test::Loopback4(), 1); | 476 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 434 QuicConnectionId connection_id = 1; | 477 QuicConnectionId connection_id = 1; |
| 435 server_address_ = IPEndPoint(net::test::Any4(), 5); | 478 server_address_ = IPEndPoint(net::test::Any4(), 5); |
| 436 | 479 |
| 437 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) | 480 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) |
| 438 .WillOnce(testing::Return(CreateSession( | 481 .WillOnce(testing::Return(CreateSession( |
| 439 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 482 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
| 440 &mock_alarm_factory_, &crypto_config_, | 483 &mock_alarm_factory_, &crypto_config_, |
| 441 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)))); |
| 442 // 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 |
| 443 // connection. | 490 // connection. |
| 444 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), | 491 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), |
| 445 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, | 492 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 446 kDefaultPathId, | 493 kDefaultPathId, |
| 447 QuicDispatcher::kMaxReasonableInitialPacketNumber); | 494 QuicDispatcher::kMaxReasonableInitialPacketNumber); |
| 448 EXPECT_EQ(client_address, dispatcher_->current_client_address()); | 495 EXPECT_EQ(client_address, dispatcher_->current_client_address()); |
| 449 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); | 496 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); |
| 450 } | 497 } |
| 451 | 498 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 } | 575 } |
| 529 } | 576 } |
| 530 } | 577 } |
| 531 return params; | 578 return params; |
| 532 } | 579 } |
| 533 | 580 |
| 534 class QuicDispatcherStatelessRejectTest | 581 class QuicDispatcherStatelessRejectTest |
| 535 : public QuicDispatcherTest, | 582 : public QuicDispatcherTest, |
| 536 public ::testing::WithParamInterface<StatelessRejectTestParams> { | 583 public ::testing::WithParamInterface<StatelessRejectTestParams> { |
| 537 public: | 584 public: |
| 538 QuicDispatcherStatelessRejectTest() : crypto_stream1_(nullptr) {} | 585 QuicDispatcherStatelessRejectTest() |
| 586 : QuicDispatcherTest(), crypto_stream1_(nullptr) {} |
| 539 | 587 |
| 540 ~QuicDispatcherStatelessRejectTest() override { | 588 ~QuicDispatcherStatelessRejectTest() override { |
| 541 if (crypto_stream1_) { | 589 if (crypto_stream1_) { |
| 542 delete crypto_stream1_; | 590 delete crypto_stream1_; |
| 543 } | 591 } |
| 544 } | 592 } |
| 545 | 593 |
| 546 // This test setup assumes that all testing will be done using | 594 // This test setup assumes that all testing will be done using |
| 547 // crypto_stream1_. | 595 // crypto_stream1_. |
| 548 void SetUp() override { | 596 void SetUp() override { |
| 597 QuicDispatcherTest::SetUp(); |
| 549 FLAGS_enable_quic_stateless_reject_support = | 598 FLAGS_enable_quic_stateless_reject_support = |
| 550 GetParam().enable_stateless_rejects_via_flag; | 599 GetParam().enable_stateless_rejects_via_flag; |
| 551 } | 600 } |
| 552 | 601 |
| 553 // Returns true or false, depending on whether the server will emit | 602 // Returns true or false, depending on whether the server will emit |
| 554 // a stateless reject, depending upon the parameters of the test. | 603 // a stateless reject, depending upon the parameters of the test. |
| 555 bool ExpectStatelessReject() { | 604 bool ExpectStatelessReject() { |
| 556 return GetParam().enable_stateless_rejects_via_flag && | 605 return GetParam().enable_stateless_rejects_via_flag && |
| 557 !GetParam().crypto_handshake_successful && | 606 !GetParam().crypto_handshake_successful && |
| 558 GetParam().client_supports_statelesss_rejects; | 607 GetParam().client_supports_statelesss_rejects; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 589 ::testing::ValuesIn(GetStatelessRejectTestParams())); | 638 ::testing::ValuesIn(GetStatelessRejectTestParams())); |
| 590 | 639 |
| 591 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) { | 640 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) { |
| 592 CreateTimeWaitListManager(); | 641 CreateTimeWaitListManager(); |
| 593 | 642 |
| 594 IPEndPoint client_address(net::test::Loopback4(), 1); | 643 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 595 QuicConnectionId connection_id = 1; | 644 QuicConnectionId connection_id = 1; |
| 596 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 645 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 597 .WillOnce(testing::Return( | 646 .WillOnce(testing::Return( |
| 598 CreateSessionBasedOnTestParams(connection_id, client_address))); | 647 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 599 | 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)))); |
| 600 // Process the first packet for the connection. | 653 // Process the first packet for the connection. |
| 601 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); | 654 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); |
| 602 if (ExpectStatelessReject()) { | 655 if (ExpectStatelessReject()) { |
| 603 // 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 |
| 604 // connection. | 657 // connection. |
| 605 session1_->connection()->CloseConnection( | 658 session1_->connection()->CloseConnection( |
| 606 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", | 659 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", |
| 607 ConnectionCloseBehavior::SILENT_CLOSE); | 660 ConnectionCloseBehavior::SILENT_CLOSE); |
| 608 } | 661 } |
| 609 | 662 |
| 610 // 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, |
| 611 // the existing connection_id will go on the time-wait list. | 664 // the existing connection_id will go on the time-wait list. |
| 612 EXPECT_EQ(ExpectStatelessReject(), | 665 EXPECT_EQ(ExpectStatelessReject(), |
| 613 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 666 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 614 if (ExpectStatelessReject()) { | 667 if (ExpectStatelessReject()) { |
| 615 // The second packet will be processed on the time-wait list. | 668 // The second packet will be processed on the time-wait list. |
| 616 EXPECT_CALL(*time_wait_list_manager_, | 669 EXPECT_CALL(*time_wait_list_manager_, |
| 617 ProcessPacket(_, _, connection_id, _, _)) | 670 ProcessPacket(_, _, connection_id, _, _)) |
| 618 .Times(1); | 671 .Times(1); |
| 619 } else { | 672 } else { |
| 620 // The second packet will trigger a packet-validation | 673 // The second packet will trigger a packet-validation |
| 621 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 674 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 622 ProcessUdpPacket(_, _, _)) | 675 ProcessUdpPacket(_, _, _)) |
| 623 .Times(1) | 676 .Times(1) |
| 624 .WillOnce(testing::WithArgs<2>( | 677 .WillOnce(testing::WithArgs<2>( |
| 625 Invoke(this, &QuicDispatcherTest::ValidatePacket))); | 678 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 679 base::Unretained(this), connection_id)))); |
| 626 } | 680 } |
| 627 ProcessPacket(client_address, connection_id, true, false, "data"); | 681 ProcessPacket(client_address, connection_id, true, false, "data"); |
| 628 } | 682 } |
| 629 | 683 |
| 630 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { | 684 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { |
| 631 FLAGS_quic_use_cheap_stateless_rejects = true; | 685 FLAGS_quic_use_cheap_stateless_rejects = true; |
| 686 FLAGS_quic_buffer_packet_till_chlo = true; |
| 632 CreateTimeWaitListManager(); | 687 CreateTimeWaitListManager(); |
| 633 | 688 |
| 634 IPEndPoint client_address(net::test::Loopback4(), 1); | 689 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 635 QuicConnectionId connection_id = 1; | 690 QuicConnectionId connection_id = 1; |
| 636 if (GetParam().enable_stateless_rejects_via_flag) { | 691 if (GetParam().enable_stateless_rejects_via_flag) { |
| 637 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 692 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 638 .Times(0); | 693 .Times(0); |
| 639 } else { | 694 } else { |
| 640 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 695 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 641 .WillOnce(testing::Return( | 696 .WillOnce(testing::Return( |
| 642 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)))); |
| 643 } | 702 } |
| 644 | 703 |
| 645 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); | 704 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); |
| 646 VLOG(1) << "Params: " << GetParam(); | 705 VLOG(1) << "Params: " << GetParam(); |
| 647 // Process the first packet for the connection. | 706 // Process the first packet for the connection. |
| 648 // clang-format off | 707 // clang-format off |
| 649 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 708 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 650 "CHLO", | 709 "CHLO", |
| 651 "AEAD", "AESG", | 710 "AEAD", "AESG", |
| 652 "KEXS", "C255", | 711 "KEXS", "C255", |
| 653 "COPT", "SREJ", | 712 "COPT", "SREJ", |
| 654 "NONC", "1234567890123456789012", | 713 "NONC", "1234567890123456789012", |
| 655 "VER\0", "Q025", | 714 "VER\0", "Q025", |
| 656 "$padding", static_cast<int>(kClientHelloMinimumSize), | 715 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 657 nullptr); | 716 nullptr); |
| 658 // clang-format on | 717 // clang-format on |
| 659 | 718 |
| 660 ProcessPacket(client_address, connection_id, true, false, | 719 ProcessPacket(client_address, connection_id, true, false, |
| 661 client_hello.GetSerialized().AsStringPiece().as_string()); | 720 client_hello.GetSerialized().AsStringPiece().as_string()); |
| 662 | 721 |
| 663 if (GetParam().enable_stateless_rejects_via_flag) { | 722 if (GetParam().enable_stateless_rejects_via_flag) { |
| 664 EXPECT_EQ(true, | 723 EXPECT_EQ(true, |
| 665 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 724 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 666 } | 725 } |
| 667 } | 726 } |
| 668 | 727 |
| 669 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { | 728 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { |
| 670 FLAGS_quic_use_cheap_stateless_rejects = true; | 729 FLAGS_quic_use_cheap_stateless_rejects = true; |
| 730 FLAGS_quic_always_log_bugs_for_tests = true; |
| 671 CreateTimeWaitListManager(); | 731 CreateTimeWaitListManager(); |
| 672 | 732 |
| 673 const IPEndPoint client_address(net::test::Loopback4(), 1); | 733 const IPEndPoint client_address(net::test::Loopback4(), 1); |
| 674 const QuicConnectionId connection_id = 1; | 734 const QuicConnectionId connection_id = 1; |
| 675 | 735 |
| 676 if (!GetParam().enable_stateless_rejects_via_flag) { | 736 if (!GetParam().enable_stateless_rejects_via_flag && |
| 677 // If stateless rejects are not being used, then a connection will be | 737 !FLAGS_quic_buffer_packet_till_chlo) { |
| 678 // 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. |
| 679 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 740 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 680 .WillOnce(testing::Return( | 741 .WillOnce(testing::Return( |
| 681 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)))); |
| 682 } | 748 } |
| 683 ProcessPacket(client_address, connection_id, true, false, | 749 bool first_packet_dropped = GetParam().enable_stateless_rejects_via_flag && |
| 684 "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 } |
| 685 | 765 |
| 686 // Process the first packet for the connection. | 766 // Process the first packet for the connection. |
| 687 // clang-format off | 767 // clang-format off |
| 688 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 768 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 689 "CHLO", | 769 "CHLO", |
| 690 "AEAD", "AESG", | 770 "AEAD", "AESG", |
| 691 "KEXS", "C255", | 771 "KEXS", "C255", |
| 692 "NONC", "1234567890123456789012", | 772 "NONC", "1234567890123456789012", |
| 693 "VER\0", "Q025", | 773 "VER\0", "Q025", |
| 694 "$padding", static_cast<int>(kClientHelloMinimumSize), | 774 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 695 nullptr); | 775 nullptr); |
| 696 // clang-format on | 776 // clang-format on |
| 697 | 777 |
| 698 if (GetParam().enable_stateless_rejects_via_flag) { | 778 if (GetParam().enable_stateless_rejects_via_flag || |
| 779 FLAGS_quic_buffer_packet_till_chlo) { |
| 699 // 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 |
| 700 // and the buffered packet will be processed | 781 // and the buffered packet will be processed |
| 701 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 782 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
| 702 .WillOnce(testing::Return( | 783 .WillOnce(testing::Return( |
| 703 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)))); |
| 704 } | 790 } |
| 705 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 791 if (!first_packet_dropped) { |
| 706 ProcessUdpPacket(_, client_address, _)) | 792 // Expect both packets to be passed to ProcessUdpPacket(). And one of them |
| 707 .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 } |
| 708 ProcessPacket(client_address, connection_id, true, false, | 805 ProcessPacket(client_address, connection_id, true, false, |
| 709 client_hello.GetSerialized().AsStringPiece().as_string()); | 806 client_hello.GetSerialized().AsStringPiece().as_string()); |
| 710 EXPECT_FALSE( | 807 EXPECT_FALSE( |
| 711 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 808 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 712 } | 809 } |
| 713 | 810 |
| 714 // Verify the stopgap test: Packets with truncated connection IDs should be | 811 // Verify the stopgap test: Packets with truncated connection IDs should be |
| 715 // dropped. | 812 // dropped. |
| 716 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {}; | 813 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {}; |
| 717 | 814 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 LOG(DFATAL) << "Not supported"; | 848 LOG(DFATAL) << "Not supported"; |
| 752 return WriteResult(); | 849 return WriteResult(); |
| 753 } | 850 } |
| 754 | 851 |
| 755 bool write_blocked_; | 852 bool write_blocked_; |
| 756 }; | 853 }; |
| 757 | 854 |
| 758 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { | 855 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { |
| 759 public: | 856 public: |
| 760 void SetUp() override { | 857 void SetUp() override { |
| 858 QuicDispatcherTest::SetUp(); |
| 761 writer_ = new BlockingWriter; | 859 writer_ = new BlockingWriter; |
| 762 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); | 860 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); |
| 763 | 861 |
| 764 IPEndPoint client_address(net::test::Loopback4(), 1); | 862 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 765 | 863 |
| 766 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 864 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
| 767 .WillOnce(testing::Return(CreateSession( | 865 .WillOnce(testing::Return(CreateSession( |
| 768 dispatcher_.get(), config_, 1, client_address, &helper_, | 866 dispatcher_.get(), config_, 1, client_address, &helper_, |
| 769 &alarm_factory_, &crypto_config_, | 867 &alarm_factory_, &crypto_config_, |
| 770 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)))); |
| 771 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 873 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
| 772 | 874 |
| 773 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 875 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
| 774 .WillOnce(testing::Return(CreateSession( | 876 .WillOnce(testing::Return(CreateSession( |
| 775 dispatcher_.get(), config_, 2, client_address, &helper_, | 877 dispatcher_.get(), config_, 2, client_address, &helper_, |
| 776 &alarm_factory_, &crypto_config_, | 878 &alarm_factory_, &crypto_config_, |
| 777 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)))); |
| 778 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); | 884 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); |
| 779 | 885 |
| 780 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); | 886 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); |
| 781 } | 887 } |
| 782 | 888 |
| 783 void TearDown() override { | 889 void TearDown() override { |
| 784 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 890 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
| 785 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 891 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
| 786 dispatcher_->Shutdown(); | 892 dispatcher_->Shutdown(); |
| 787 } | 893 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); | 1030 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); |
| 925 dispatcher_->OnCanWrite(); | 1031 dispatcher_->OnCanWrite(); |
| 926 EXPECT_TRUE(dispatcher_->HasPendingWrites()); | 1032 EXPECT_TRUE(dispatcher_->HasPendingWrites()); |
| 927 | 1033 |
| 928 // 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. |
| 929 EXPECT_CALL(*connection2(), OnCanWrite()); | 1035 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 930 dispatcher_->OnCanWrite(); | 1036 dispatcher_->OnCanWrite(); |
| 931 EXPECT_FALSE(dispatcher_->HasPendingWrites()); | 1037 EXPECT_FALSE(dispatcher_->HasPendingWrites()); |
| 932 } | 1038 } |
| 933 | 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 = AllSupportedVersions().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 |
| 934 } // namespace | 1285 } // namespace |
| 935 } // namespace test | 1286 } // namespace test |
| 936 } // namespace net | 1287 } // namespace net |
| OLD | NEW |