| 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 <ostream> | 7 #include <ostream> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" | 24 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" |
| 25 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" | 25 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" |
| 26 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 28 | 28 |
| 29 using base::StringPiece; | 29 using base::StringPiece; |
| 30 using net::EpollServer; | 30 using net::EpollServer; |
| 31 using net::test::ConstructEncryptedPacket; | 31 using net::test::ConstructEncryptedPacket; |
| 32 using net::test::CryptoTestUtils; | 32 using net::test::CryptoTestUtils; |
| 33 using net::test::MockConnection; | 33 using net::test::MockConnection; |
| 34 using net::test::MockHelper; | 34 using net::test::MockConnectionHelper; |
| 35 using net::test::ValueRestore; | 35 using net::test::ValueRestore; |
| 36 using net::test::TestWriterFactory; | 36 using net::test::TestWriterFactory; |
| 37 using std::string; | 37 using std::string; |
| 38 using std::vector; | 38 using std::vector; |
| 39 using testing::DoAll; | 39 using testing::DoAll; |
| 40 using testing::InSequence; | 40 using testing::InSequence; |
| 41 using testing::Invoke; | 41 using testing::Invoke; |
| 42 using testing::WithoutArgs; | 42 using testing::WithoutArgs; |
| 43 using testing::_; | 43 using testing::_; |
| 44 | 44 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 using QuicDispatcher::current_client_address; | 91 using QuicDispatcher::current_client_address; |
| 92 }; | 92 }; |
| 93 | 93 |
| 94 // A Connection class which unregisters the session from the dispatcher when | 94 // A Connection class which unregisters the session from the dispatcher when |
| 95 // sending connection close. | 95 // sending connection close. |
| 96 // It'd be slightly more realistic to do this from the Session but it would | 96 // It'd be slightly more realistic to do this from the Session but it would |
| 97 // involve a lot more mocking. | 97 // involve a lot more mocking. |
| 98 class MockServerConnection : public MockConnection { | 98 class MockServerConnection : public MockConnection { |
| 99 public: | 99 public: |
| 100 MockServerConnection(QuicConnectionId connection_id, | 100 MockServerConnection(QuicConnectionId connection_id, |
| 101 MockHelper* helper, | 101 MockConnectionHelper* helper, |
| 102 QuicDispatcher* dispatcher) | 102 QuicDispatcher* dispatcher) |
| 103 : MockConnection(connection_id, helper, Perspective::IS_SERVER), | 103 : MockConnection(connection_id, helper, Perspective::IS_SERVER), |
| 104 dispatcher_(dispatcher) {} | 104 dispatcher_(dispatcher) {} |
| 105 | 105 |
| 106 void UnregisterOnConnectionClosed() { | 106 void UnregisterOnConnectionClosed() { |
| 107 LOG(ERROR) << "Unregistering " << connection_id(); | 107 LOG(ERROR) << "Unregistering " << connection_id(); |
| 108 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR); | 108 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR); |
| 109 } | 109 } |
| 110 | 110 |
| 111 private: | 111 private: |
| 112 QuicDispatcher* dispatcher_; | 112 QuicDispatcher* dispatcher_; |
| 113 }; | 113 }; |
| 114 | 114 |
| 115 QuicServerSession* CreateSession(QuicDispatcher* dispatcher, | 115 QuicServerSession* CreateSession(QuicDispatcher* dispatcher, |
| 116 const QuicConfig& config, | 116 const QuicConfig& config, |
| 117 QuicConnectionId connection_id, | 117 QuicConnectionId connection_id, |
| 118 const IPEndPoint& client_address, | 118 const IPEndPoint& client_address, |
| 119 MockHelper* helper, | 119 MockConnectionHelper* helper, |
| 120 const QuicCryptoServerConfig* crypto_config, | 120 const QuicCryptoServerConfig* crypto_config, |
| 121 TestQuicSpdyServerSession** session) { | 121 TestQuicSpdyServerSession** session) { |
| 122 MockServerConnection* connection = | 122 MockServerConnection* connection = |
| 123 new MockServerConnection(connection_id, helper, dispatcher); | 123 new MockServerConnection(connection_id, helper, dispatcher); |
| 124 *session = new TestQuicSpdyServerSession(config, connection, crypto_config); | 124 *session = new TestQuicSpdyServerSession(config, connection, crypto_config); |
| 125 connection->set_visitor(*session); | 125 connection->set_visitor(*session); |
| 126 ON_CALL(*connection, SendConnectionClose(_)).WillByDefault( | 126 ON_CALL(*connection, SendConnectionClose(_)).WillByDefault( |
| 127 WithoutArgs(Invoke( | 127 WithoutArgs(Invoke( |
| 128 connection, &MockServerConnection::UnregisterOnConnectionClosed))); | 128 connection, &MockServerConnection::UnregisterOnConnectionClosed))); |
| 129 EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), | 129 EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 void CreateTimeWaitListManager() { | 196 void CreateTimeWaitListManager() { |
| 197 time_wait_list_manager_ = new MockTimeWaitListManager( | 197 time_wait_list_manager_ = new MockTimeWaitListManager( |
| 198 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &helper_); | 198 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &helper_); |
| 199 // dispatcher_ takes the ownership of time_wait_list_manager_. | 199 // dispatcher_ takes the ownership of time_wait_list_manager_. |
| 200 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, | 200 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, |
| 201 time_wait_list_manager_); | 201 time_wait_list_manager_); |
| 202 } | 202 } |
| 203 | 203 |
| 204 EpollServer eps_; | 204 EpollServer eps_; |
| 205 QuicEpollConnectionHelper helper_; | 205 QuicEpollConnectionHelper helper_; |
| 206 MockHelper mock_helper_; | 206 MockConnectionHelper mock_helper_; |
| 207 QuicConfig config_; | 207 QuicConfig config_; |
| 208 QuicCryptoServerConfig crypto_config_; | 208 QuicCryptoServerConfig crypto_config_; |
| 209 IPEndPoint server_address_; | 209 IPEndPoint server_address_; |
| 210 TestDispatcher dispatcher_; | 210 TestDispatcher dispatcher_; |
| 211 MockTimeWaitListManager* time_wait_list_manager_; | 211 MockTimeWaitListManager* time_wait_list_manager_; |
| 212 TestQuicSpdyServerSession* session1_; | 212 TestQuicSpdyServerSession* session1_; |
| 213 TestQuicSpdyServerSession* session2_; | 213 TestQuicSpdyServerSession* session2_; |
| 214 string data_; | 214 string data_; |
| 215 }; | 215 }; |
| 216 | 216 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 void set_handshake_confirmed_for_testing(bool handshake_confirmed) { | 321 void set_handshake_confirmed_for_testing(bool handshake_confirmed) { |
| 322 handshake_confirmed_ = handshake_confirmed; | 322 handshake_confirmed_ = handshake_confirmed; |
| 323 } | 323 } |
| 324 | 324 |
| 325 private: | 325 private: |
| 326 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); | 326 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); |
| 327 }; | 327 }; |
| 328 | 328 |
| 329 struct StatelessRejectTestParams { | 329 struct StatelessRejectTestParams { |
| 330 StatelessRejectTestParams(bool enable_stateless_rejects_via_flag, | 330 StatelessRejectTestParams(bool enable_stateless_rejects_via_flag, |
| 331 bool use_stateless_rejects_if_peer_supported, | |
| 332 bool client_supports_statelesss_rejects, | 331 bool client_supports_statelesss_rejects, |
| 333 bool crypto_handshake_successful) | 332 bool crypto_handshake_successful) |
| 334 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag), | 333 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag), |
| 335 use_stateless_rejects_if_peer_supported( | |
| 336 use_stateless_rejects_if_peer_supported), | |
| 337 client_supports_statelesss_rejects(client_supports_statelesss_rejects), | 334 client_supports_statelesss_rejects(client_supports_statelesss_rejects), |
| 338 crypto_handshake_successful(crypto_handshake_successful) {} | 335 crypto_handshake_successful(crypto_handshake_successful) {} |
| 339 | 336 |
| 340 friend std::ostream& operator<<(std::ostream& os, | 337 friend std::ostream& operator<<(std::ostream& os, |
| 341 const StatelessRejectTestParams& p) { | 338 const StatelessRejectTestParams& p) { |
| 342 os << " enable_stateless_rejects_via_flag: " | 339 os << " enable_stateless_rejects_via_flag: " |
| 343 << p.enable_stateless_rejects_via_flag << std::endl; | 340 << p.enable_stateless_rejects_via_flag << std::endl; |
| 344 os << "{ use_stateless_rejects_if_peer_supported: " | |
| 345 << p.use_stateless_rejects_if_peer_supported << std::endl; | |
| 346 os << "{ client_supports_statelesss_rejects: " | 341 os << "{ client_supports_statelesss_rejects: " |
| 347 << p.client_supports_statelesss_rejects << std::endl; | 342 << p.client_supports_statelesss_rejects << std::endl; |
| 348 os << " crypto_handshake_successful: " << p.crypto_handshake_successful | 343 os << " crypto_handshake_successful: " << p.crypto_handshake_successful |
| 349 << " }"; | 344 << " }"; |
| 350 return os; | 345 return os; |
| 351 } | 346 } |
| 352 | 347 |
| 353 // This only enables the stateless reject feature via the feature-flag. | 348 // This only enables the stateless reject feature via the feature-flag. |
| 354 // It does not force the crypto server to emit stateless rejects. | 349 // This should be a no-op if the peer does not support them. |
| 355 bool enable_stateless_rejects_via_flag; | 350 bool enable_stateless_rejects_via_flag; |
| 356 // If true, this forces the server to send a stateless reject when rejecting | |
| 357 // messages. This should be a no-op if enable_stateless_rejects_via_flag is | |
| 358 // false or the peer does not support them. | |
| 359 bool use_stateless_rejects_if_peer_supported; | |
| 360 // Whether or not the client supports stateless rejects. | 351 // Whether or not the client supports stateless rejects. |
| 361 bool client_supports_statelesss_rejects; | 352 bool client_supports_statelesss_rejects; |
| 362 // Should the initial crypto handshake succeed or not. | 353 // Should the initial crypto handshake succeed or not. |
| 363 bool crypto_handshake_successful; | 354 bool crypto_handshake_successful; |
| 364 }; | 355 }; |
| 365 | 356 |
| 366 // Constructs various test permutations for stateless rejects. | 357 // Constructs various test permutations for stateless rejects. |
| 367 vector<StatelessRejectTestParams> GetStatelessRejectTestParams() { | 358 vector<StatelessRejectTestParams> GetStatelessRejectTestParams() { |
| 368 vector<StatelessRejectTestParams> params; | 359 vector<StatelessRejectTestParams> params; |
| 369 for (bool enable_stateless_rejects_via_flag : {true, false}) { | 360 for (bool enable_stateless_rejects_via_flag : {true, false}) { |
| 370 for (bool use_stateless_rejects_if_peer_supported : {true, false}) { | 361 for (bool client_supports_statelesss_rejects : {true, false}) { |
| 371 for (bool client_supports_statelesss_rejects : {true, false}) { | 362 for (bool crypto_handshake_successful : {true, false}) { |
| 372 for (bool crypto_handshake_successful : {true, false}) { | 363 params.push_back(StatelessRejectTestParams( |
| 373 params.push_back(StatelessRejectTestParams( | 364 enable_stateless_rejects_via_flag, |
| 374 enable_stateless_rejects_via_flag, | 365 client_supports_statelesss_rejects, crypto_handshake_successful)); |
| 375 use_stateless_rejects_if_peer_supported, | |
| 376 client_supports_statelesss_rejects, crypto_handshake_successful)); | |
| 377 } | |
| 378 } | 366 } |
| 379 } | 367 } |
| 380 } | 368 } |
| 381 return params; | 369 return params; |
| 382 } | 370 } |
| 383 | 371 |
| 384 class QuicDispatcherStatelessRejectTest | 372 class QuicDispatcherStatelessRejectTest |
| 385 : public QuicDispatcherTest, | 373 : public QuicDispatcherTest, |
| 386 public ::testing::WithParamInterface<StatelessRejectTestParams> { | 374 public ::testing::WithParamInterface<StatelessRejectTestParams> { |
| 387 public: | 375 public: |
| 388 QuicDispatcherStatelessRejectTest() : crypto_stream1_(nullptr) {} | 376 QuicDispatcherStatelessRejectTest() : crypto_stream1_(nullptr) {} |
| 389 | 377 |
| 390 ~QuicDispatcherStatelessRejectTest() override { | 378 ~QuicDispatcherStatelessRejectTest() override { |
| 391 if (crypto_stream1_) { | 379 if (crypto_stream1_) { |
| 392 delete crypto_stream1_; | 380 delete crypto_stream1_; |
| 393 } | 381 } |
| 394 } | 382 } |
| 395 | 383 |
| 396 // This test setup assumes that all testing will be done using | 384 // This test setup assumes that all testing will be done using |
| 397 // crypto_stream1_. | 385 // crypto_stream1_. |
| 398 void SetUp() override { | 386 void SetUp() override { |
| 399 FLAGS_enable_quic_stateless_reject_support = | 387 FLAGS_enable_quic_stateless_reject_support = |
| 400 GetParam().enable_stateless_rejects_via_flag; | 388 GetParam().enable_stateless_rejects_via_flag; |
| 401 } | 389 } |
| 402 | 390 |
| 403 // Returns true or false, depending on whether the server will emit | 391 // Returns true or false, depending on whether the server will emit |
| 404 // a stateless reject, depending upon the parameters of the test. | 392 // a stateless reject, depending upon the parameters of the test. |
| 405 bool ExpectStatelessReject() { | 393 bool ExpectStatelessReject() { |
| 406 return GetParam().enable_stateless_rejects_via_flag && | 394 return GetParam().enable_stateless_rejects_via_flag && |
| 407 GetParam().use_stateless_rejects_if_peer_supported && | |
| 408 !GetParam().crypto_handshake_successful && | 395 !GetParam().crypto_handshake_successful && |
| 409 GetParam().client_supports_statelesss_rejects; | 396 GetParam().client_supports_statelesss_rejects; |
| 410 } | 397 } |
| 411 | 398 |
| 412 // Sets up dispatcher_, sesession1_, and crypto_stream1_ based on | 399 // Sets up dispatcher_, sesession1_, and crypto_stream1_ based on |
| 413 // the test parameters. | 400 // the test parameters. |
| 414 QuicServerSession* CreateSessionBasedOnTestParams( | 401 QuicServerSession* CreateSessionBasedOnTestParams( |
| 415 QuicConnectionId connection_id, | 402 QuicConnectionId connection_id, |
| 416 const IPEndPoint& client_address) { | 403 const IPEndPoint& client_address) { |
| 417 CreateSession(&dispatcher_, config_, connection_id, client_address, | 404 CreateSession(&dispatcher_, config_, connection_id, client_address, |
| 418 &mock_helper_, &crypto_config_, &session1_); | 405 &mock_helper_, &crypto_config_, &session1_); |
| 419 | 406 |
| 420 crypto_stream1_ = new MockQuicCryptoServerStream(crypto_config_, session1_); | 407 crypto_stream1_ = new MockQuicCryptoServerStream(crypto_config_, session1_); |
| 421 session1_->SetCryptoStream(crypto_stream1_); | 408 session1_->SetCryptoStream(crypto_stream1_); |
| 422 crypto_stream1_->set_use_stateless_rejects_if_peer_supported( | |
| 423 GetParam().use_stateless_rejects_if_peer_supported); | |
| 424 crypto_stream1_->set_handshake_confirmed_for_testing( | 409 crypto_stream1_->set_handshake_confirmed_for_testing( |
| 425 GetParam().crypto_handshake_successful); | 410 GetParam().crypto_handshake_successful); |
| 426 crypto_stream1_->set_peer_supports_stateless_rejects( | 411 crypto_stream1_->set_peer_supports_stateless_rejects( |
| 427 GetParam().client_supports_statelesss_rejects); | 412 GetParam().client_supports_statelesss_rejects); |
| 428 return session1_; | 413 return session1_; |
| 429 } | 414 } |
| 430 | 415 |
| 431 MockQuicCryptoServerStream* crypto_stream1_; | 416 MockQuicCryptoServerStream* crypto_stream1_; |
| 432 }; | 417 }; |
| 433 | 418 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 void SetBlocked() { | 602 void SetBlocked() { |
| 618 writer_->write_blocked_ = true; | 603 writer_->write_blocked_ = true; |
| 619 } | 604 } |
| 620 | 605 |
| 621 void BlockConnection2() { | 606 void BlockConnection2() { |
| 622 writer_->write_blocked_ = true; | 607 writer_->write_blocked_ = true; |
| 623 dispatcher_.OnWriteBlocked(connection2()); | 608 dispatcher_.OnWriteBlocked(connection2()); |
| 624 } | 609 } |
| 625 | 610 |
| 626 protected: | 611 protected: |
| 627 MockHelper helper_; | 612 MockConnectionHelper helper_; |
| 628 BlockingWriter* writer_; | 613 BlockingWriter* writer_; |
| 629 QuicDispatcher::WriteBlockedList* blocked_list_; | 614 QuicDispatcher::WriteBlockedList* blocked_list_; |
| 630 }; | 615 }; |
| 631 | 616 |
| 632 TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) { | 617 TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) { |
| 633 // No OnCanWrite calls because no connections are blocked. | 618 // No OnCanWrite calls because no connections are blocked. |
| 634 dispatcher_.OnCanWrite(); | 619 dispatcher_.OnCanWrite(); |
| 635 | 620 |
| 636 // Register connection 1 for events, and make sure it's notified. | 621 // Register connection 1 for events, and make sure it's notified. |
| 637 SetBlocked(); | 622 SetBlocked(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 // And we'll resume where we left off when we get another call. | 741 // And we'll resume where we left off when we get another call. |
| 757 EXPECT_CALL(*connection2(), OnCanWrite()); | 742 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 758 dispatcher_.OnCanWrite(); | 743 dispatcher_.OnCanWrite(); |
| 759 EXPECT_FALSE(dispatcher_.HasPendingWrites()); | 744 EXPECT_FALSE(dispatcher_.HasPendingWrites()); |
| 760 } | 745 } |
| 761 | 746 |
| 762 } // namespace | 747 } // namespace |
| 763 } // namespace test | 748 } // namespace test |
| 764 } // namespace tools | 749 } // namespace tools |
| 765 } // namespace net | 750 } // namespace net |
| OLD | NEW |