gfe-relnote: (n/a) Delete some functions from QuicCryptoServerStream and tests that uses those function. Not protected.
The deleted functions are
- UseStatelessRejectsIfPeerSupported
- PeerSupportsStatelessRejects
- SetPeerSupportsStatelessRejects
These functions are not needed since cl/246435575.
PiperOrigin-RevId: 247938469
Change-Id: I9933906c213dad5e01e365fdd399e85e72c73534
diff --git a/quic/core/quic_crypto_client_stream_test.cc b/quic/core/quic_crypto_client_stream_test.cc
index 2d3702f..042d973 100644
--- a/quic/core/quic_crypto_client_stream_test.cc
+++ b/quic/core/quic_crypto_client_stream_test.cc
@@ -352,115 +352,6 @@
client_version_label);
}
-class QuicCryptoClientStreamStatelessTest : public QuicTest {
- public:
- QuicCryptoClientStreamStatelessTest()
- : client_crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
- TlsClientHandshaker::CreateSslCtx()),
- server_crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting(),
- KeyExchangeSource::Default(),
- TlsServerHandshaker::CreateSslCtx()),
- server_compressed_certs_cache_(
- QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- server_id_(kServerHostname, kServerPort, false) {
- TestQuicSpdyClientSession* client_session = nullptr;
- CreateClientSessionForTest(server_id_,
- /* supports_stateless_rejects= */ true,
- QuicTime::Delta::FromSeconds(100000),
- AllSupportedVersions(), &helper_,
- &alarm_factory_, &client_crypto_config_,
- &client_connection_, &client_session);
- CHECK(client_session);
- client_session_.reset(client_session);
- }
-
- QuicCryptoServerStream* server_stream() {
- return server_session_->GetMutableCryptoStream();
- }
-
- void AdvanceHandshakeWithFakeServer() {
- client_session_->GetMutableCryptoStream()->CryptoConnect();
- EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
- .Times(testing::AnyNumber());
- EXPECT_CALL(*server_session_->helper(), GenerateConnectionIdForReject(_, _))
- .Times(testing::AnyNumber());
- crypto_test_utils::AdvanceHandshake(
- client_connection_, client_session_->GetMutableCryptoStream(), 0,
- server_connection_, server_stream(), 0);
- }
-
- // Initializes the server_stream_ for stateless rejects.
- void InitializeFakeStatelessRejectServer() {
- TestQuicSpdyServerSession* server_session = nullptr;
- CreateServerSessionForTest(
- server_id_, QuicTime::Delta::FromSeconds(100000),
- ParsedVersionOfIndex(AllSupportedVersions(), 0), &helper_,
- &alarm_factory_, &server_crypto_config_,
- &server_compressed_certs_cache_, &server_connection_, &server_session);
- CHECK(server_session);
- server_session_.reset(server_session);
- server_session_->OnSuccessfulVersionNegotiation(AllSupportedVersions()[0]);
- crypto_test_utils::FakeServerOptions options;
- crypto_test_utils::SetupCryptoServerConfigForTest(
- server_connection_->clock(), server_connection_->random_generator(),
- &server_crypto_config_, options);
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
- }
-
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
-
- // Client crypto stream state
- PacketSavingConnection* client_connection_;
- std::unique_ptr<TestQuicSpdyClientSession> client_session_;
- QuicCryptoClientConfig client_crypto_config_;
-
- // Server crypto stream state
- PacketSavingConnection* server_connection_;
- std::unique_ptr<TestQuicSpdyServerSession> server_session_;
- QuicCryptoServerConfig server_crypto_config_;
- QuicCompressedCertsCache server_compressed_certs_cache_;
- QuicServerId server_id_;
-};
-
-TEST_F(QuicCryptoClientStreamStatelessTest, StatelessReject) {
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
-
- QuicCryptoClientConfig::CachedState* client_state =
- client_crypto_config_.LookupOrCreate(server_id_);
-
- EXPECT_FALSE(client_state->has_server_designated_connection_id());
- EXPECT_CALL(*client_session_, OnProofValid(testing::_));
-
- InitializeFakeStatelessRejectServer();
- EXPECT_CALL(*client_connection_,
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- AdvanceHandshakeWithFakeServer();
-
- EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
- EXPECT_EQ(0, server_stream()->NumHandshakeMessagesWithServerNonces());
-
- EXPECT_FALSE(client_session_->IsEncryptionEstablished());
- EXPECT_FALSE(client_session_->IsCryptoHandshakeConfirmed());
- // Even though the handshake was not complete, the cached client_state is
- // complete, and can be used for a subsequent successful handshake.
- EXPECT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
-
- ASSERT_TRUE(client_state->has_server_nonce());
- ASSERT_FALSE(client_state->GetNextServerNonce().empty());
- ASSERT_TRUE(client_state->has_server_designated_connection_id());
- QuicConnectionId server_designated_id =
- client_state->GetNextServerDesignatedConnectionId();
- QuicConnectionId expected_id = QuicUtils::CreateRandomConnectionId(
- server_session_->connection()->random_generator());
- EXPECT_EQ(expected_id, server_designated_id);
- EXPECT_FALSE(client_state->has_server_designated_connection_id());
-}
-
} // namespace
} // namespace test
} // namespace quic
diff --git a/quic/core/quic_crypto_server_handshaker.cc b/quic/core/quic_crypto_server_handshaker.cc
index c0e61ef..9e46d6d 100644
--- a/quic/core/quic_crypto_server_handshaker.cc
+++ b/quic/core/quic_crypto_server_handshaker.cc
@@ -138,18 +138,11 @@
QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
result,
std::unique_ptr<ProofSource::Details> details) {
- const CryptoHandshakeMessage& message = result->client_hello;
-
// Clear the callback that got us here.
DCHECK(validate_client_hello_cb_ != nullptr);
DCHECK(process_client_hello_cb_ == nullptr);
validate_client_hello_cb_ = nullptr;
- if (stream_->UseStatelessRejectsIfPeerSupported()) {
- stream_->SetPeerSupportsStatelessRejects(
- QuicCryptoServerStreamBase::DoesPeerSupportStatelessRejects(message));
- }
-
std::unique_ptr<ProcessClientHelloCallback> cb(
new ProcessClientHelloCallback(this, result));
process_client_hello_cb_ = cb.get();
@@ -177,8 +170,7 @@
if (reply->tag() != kSHLO) {
if (reply->tag() == kSREJ) {
- DCHECK(stream_->UseStatelessRejectsIfPeerSupported());
- DCHECK(stream_->PeerSupportsStatelessRejects());
+ DCHECK(false) << "Unexpected SREJ reply.";
// Before sending the SREJ, cause the connection to save crypto packets
// so that they can be added to the time wait list manager and
// retransmitted.
@@ -189,8 +181,7 @@
SendHandshakeMessage(*reply);
if (reply->tag() == kSREJ) {
- DCHECK(stream_->UseStatelessRejectsIfPeerSupported());
- DCHECK(stream_->PeerSupportsStatelessRejects());
+ DCHECK(false) << "Unexpected SREJ reply.";
DCHECK(!handshake_confirmed());
QUIC_DLOG(INFO) << "Closing connection "
<< session()->connection()->connection_id()
@@ -431,16 +422,13 @@
}
previous_source_address_tokens_ = result->info.source_address_tokens;
- const bool use_stateless_rejects_in_crypto_config =
- stream_->UseStatelessRejectsIfPeerSupported() &&
- stream_->PeerSupportsStatelessRejects();
QuicConnection* connection = session()->connection();
const QuicConnectionId server_designated_connection_id =
- GenerateConnectionIdForReject(use_stateless_rejects_in_crypto_config);
+ GenerateConnectionIdForReject(/*use_stateless_rejects=*/false);
crypto_config_->ProcessClientHello(
result, /*reject_only=*/false, connection->connection_id(),
connection->self_address(), GetClientAddress(), connection->version(),
- session()->supported_versions(), use_stateless_rejects_in_crypto_config,
+ session()->supported_versions(), /*use_stateless_rejects=*/false,
server_designated_connection_id, connection->clock(),
connection->random_generator(), compressed_certs_cache_,
crypto_negotiated_params_, signed_config_,
diff --git a/quic/core/quic_crypto_server_stream.cc b/quic/core/quic_crypto_server_stream.cc
index 010ac36..3375e46 100644
--- a/quic/core/quic_crypto_server_stream.cc
+++ b/quic/core/quic_crypto_server_stream.cc
@@ -97,23 +97,10 @@
return handshaker()->PreviousCachedNetworkParams();
}
-bool QuicCryptoServerStream::UseStatelessRejectsIfPeerSupported() const {
- return use_stateless_rejects_if_peer_supported_;
-}
-
-bool QuicCryptoServerStream::PeerSupportsStatelessRejects() const {
- return peer_supports_stateless_rejects_;
-}
-
bool QuicCryptoServerStream::ZeroRttAttempted() const {
return handshaker()->ZeroRttAttempted();
}
-void QuicCryptoServerStream::SetPeerSupportsStatelessRejects(
- bool peer_supports_stateless_rejects) {
- peer_supports_stateless_rejects_ = peer_supports_stateless_rejects;
-}
-
void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
CachedNetworkParameters cached_network_params) {
handshaker()->SetPreviousCachedNetworkParams(cached_network_params);
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h
index a003027..a31f133 100644
--- a/quic/core/quic_crypto_server_stream.h
+++ b/quic/core/quic_crypto_server_stream.h
@@ -51,10 +51,7 @@
// These are all accessors and setters to their respective counters.
virtual uint8_t NumHandshakeMessages() const = 0;
virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0;
- virtual bool UseStatelessRejectsIfPeerSupported() const = 0;
- virtual bool PeerSupportsStatelessRejects() const = 0;
virtual bool ZeroRttAttempted() const = 0;
- virtual void SetPeerSupportsStatelessRejects(bool set) = 0;
virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
const = 0;
virtual void SetPreviousCachedNetworkParams(
@@ -171,11 +168,7 @@
uint8_t NumHandshakeMessagesWithServerNonces() const override;
int NumServerConfigUpdateMessagesSent() const override;
const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
- bool UseStatelessRejectsIfPeerSupported() const override;
- bool PeerSupportsStatelessRejects() const override;
bool ZeroRttAttempted() const override;
- void SetPeerSupportsStatelessRejects(
- bool peer_supports_stateless_rejects) override;
void SetPreviousCachedNetworkParams(
CachedNetworkParameters cached_network_params) override;
diff --git a/quic/core/quic_crypto_server_stream_test.cc b/quic/core/quic_crypto_server_stream_test.cc
index ff7111c..30f954d 100644
--- a/quic/core/quic_crypto_server_stream_test.cc
+++ b/quic/core/quic_crypto_server_stream_test.cc
@@ -45,14 +45,6 @@
namespace quic {
namespace test {
-class QuicCryptoServerStreamPeer {
- public:
- static bool DoesPeerSupportStatelessRejects(
- const CryptoHandshakeMessage& message) {
- return QuicCryptoServerStream::DoesPeerSupportStatelessRejects(message);
- }
-};
-
namespace {
const char kServerHostname[] = "test.example.com";
@@ -74,9 +66,7 @@
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
server_id_(kServerHostname, kServerPort, false),
client_crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
- TlsClientHandshaker::CreateSslCtx()) {
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, false);
- }
+ TlsClientHandshaker::CreateSslCtx()) {}
void Initialize() { InitializeServer(); }
@@ -197,12 +187,6 @@
EXPECT_FALSE(server_stream()->handshake_confirmed());
}
-TEST_P(QuicCryptoServerStreamTest, NotInitiallySendingStatelessRejects) {
- Initialize();
- EXPECT_FALSE(server_stream()->UseStatelessRejectsIfPeerSupported());
- EXPECT_FALSE(server_stream()->PeerSupportsStatelessRejects());
-}
-
TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
// CompleteCryptoHandshake returns the number of client hellos sent. This
// test should send:
@@ -251,109 +235,6 @@
server_session_->connection()->encryption_level());
}
-TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) {
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
- Initialize();
-
- InitializeFakeClient(/* supports_stateless_rejects= */ true);
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- EXPECT_CALL(*client_connection_,
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- AdvanceHandshakeWithFakeClient();
-
- // Check the server to make the sure the handshake did not succeed.
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->handshake_confirmed());
-
- // Check the client state to make sure that it received a server-designated
- // connection id.
- QuicCryptoClientConfig::CachedState* client_state =
- client_crypto_config_.LookupOrCreate(server_id_);
-
- ASSERT_TRUE(client_state->has_server_nonce());
- ASSERT_FALSE(client_state->GetNextServerNonce().empty());
- ASSERT_FALSE(client_state->has_server_nonce());
-
- ASSERT_TRUE(client_state->has_server_designated_connection_id());
- const QuicConnectionId server_designated_connection_id =
- client_state->GetNextServerDesignatedConnectionId();
- const QuicConnectionId expected_id = QuicUtils::CreateRandomConnectionId(
- server_connection_->random_generator());
- EXPECT_EQ(expected_id, server_designated_connection_id);
- EXPECT_FALSE(client_state->has_server_designated_connection_id());
- ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
-}
-
-TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
- Initialize();
-
- InitializeFakeClient(/* supports_stateless_rejects= */ true);
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- EXPECT_CALL(*client_connection_,
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- AdvanceHandshakeWithFakeClient();
-
- // On the first round, encryption will not be established.
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->handshake_confirmed());
- EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
- EXPECT_EQ(0, server_stream()->NumHandshakeMessagesWithServerNonces());
-
- // Now check the client state.
- QuicCryptoClientConfig::CachedState* client_state =
- client_crypto_config_.LookupOrCreate(server_id_);
-
- ASSERT_TRUE(client_state->has_server_designated_connection_id());
- const QuicConnectionId server_designated_connection_id =
- client_state->GetNextServerDesignatedConnectionId();
- const QuicConnectionId expected_id = QuicUtils::CreateRandomConnectionId(
- server_connection_->random_generator());
- EXPECT_EQ(expected_id, server_designated_connection_id);
- EXPECT_FALSE(client_state->has_server_designated_connection_id());
- ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
-
- // Now create new client and server streams with the existing config
- // and try the handshake again (0-RTT handshake).
- InitializeServer();
-
- InitializeFakeClient(/* supports_stateless_rejects= */ true);
- // In the stateless case, the second handshake contains a server-nonce, so the
- // AsyncStrikeRegisterVerification() case will still succeed (unlike a 0-RTT
- // handshake).
- AdvanceHandshakeWithFakeClient();
-
- // On the second round, encryption will be established.
- EXPECT_TRUE(server_stream()->encryption_established());
- EXPECT_TRUE(server_stream()->handshake_confirmed());
- EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
- EXPECT_EQ(1, server_stream()->NumHandshakeMessagesWithServerNonces());
-}
-
-TEST_P(QuicCryptoServerStreamTest, NoStatelessRejectIfNoClientSupport) {
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
- Initialize();
-
- // The server is configured to use stateless rejects, but the client does not
- // support it.
- InitializeFakeClient(/* supports_stateless_rejects= */ false);
- AdvanceHandshakeWithFakeClient();
-
- // Check the server to make the sure the handshake did not succeed.
- EXPECT_FALSE(server_stream()->encryption_established());
- EXPECT_FALSE(server_stream()->handshake_confirmed());
-
- // Check the client state to make sure that it did not receive a
- // server-designated connection id.
- QuicCryptoClientConfig::CachedState* client_state =
- client_crypto_config_.LookupOrCreate(server_id_);
-
- ASSERT_FALSE(client_state->has_server_designated_connection_id());
- ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
-}
-
TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ false);
@@ -450,21 +331,6 @@
EXPECT_EQ(1, client_stream()->num_scup_messages_received());
}
-TEST_P(QuicCryptoServerStreamTest, DoesPeerSupportStatelessRejects) {
- Initialize();
-
- QuicConfig stateless_reject_config = DefaultQuicConfigStatelessRejects();
- stateless_reject_config.ToHandshakeMessage(&message_);
- EXPECT_TRUE(
- QuicCryptoServerStreamPeer::DoesPeerSupportStatelessRejects(message_));
-
- message_.Clear();
- QuicConfig stateful_reject_config = DefaultQuicConfig();
- stateful_reject_config.ToHandshakeMessage(&message_);
- EXPECT_FALSE(
- QuicCryptoServerStreamPeer::DoesPeerSupportStatelessRejects(message_));
-}
-
class QuicCryptoServerStreamTestWithFailingProofSource
: public QuicCryptoServerStreamTest {
public:
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index 16d2584..9c7cd1e 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -1071,262 +1071,6 @@
bool handshake_confirmed_;
};
-struct StatelessRejectTestParams {
- StatelessRejectTestParams(bool enable_stateless_rejects_via_flag,
- bool client_supports_statelesss_rejects,
- bool crypto_handshake_successful)
- : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
- client_supports_statelesss_rejects(client_supports_statelesss_rejects),
- crypto_handshake_successful(crypto_handshake_successful) {}
-
- friend std::ostream& operator<<(std::ostream& os,
- const StatelessRejectTestParams& p) {
- os << "{ enable_stateless_rejects_via_flag: "
- << p.enable_stateless_rejects_via_flag << std::endl;
- os << " client_supports_statelesss_rejects: "
- << p.client_supports_statelesss_rejects << std::endl;
- os << " crypto_handshake_successful: " << p.crypto_handshake_successful
- << " }";
- return os;
- }
-
- // This only enables the stateless reject feature via the feature-flag.
- // This should be a no-op if the peer does not support them.
- bool enable_stateless_rejects_via_flag;
- // Whether or not the client supports stateless rejects.
- bool client_supports_statelesss_rejects;
- // Should the initial crypto handshake succeed or not.
- bool crypto_handshake_successful;
-};
-
-// Constructs various test permutations for stateless rejects.
-std::vector<StatelessRejectTestParams> GetStatelessRejectTestParams() {
- std::vector<StatelessRejectTestParams> params;
- for (bool enable_stateless_rejects_via_flag : {true, false}) {
- for (bool client_supports_statelesss_rejects : {true, false}) {
- for (bool crypto_handshake_successful : {true, false}) {
- params.push_back(StatelessRejectTestParams(
- enable_stateless_rejects_via_flag,
- client_supports_statelesss_rejects, crypto_handshake_successful));
- }
- }
- }
- return params;
-}
-
-class QuicDispatcherStatelessRejectTest
- : public QuicDispatcherTest,
- public testing::WithParamInterface<StatelessRejectTestParams> {
- public:
- QuicDispatcherStatelessRejectTest()
- : QuicDispatcherTest(), crypto_stream1_(nullptr) {}
-
- ~QuicDispatcherStatelessRejectTest() override {
- if (crypto_stream1_) {
- delete crypto_stream1_;
- }
- }
-
- // This test setup assumes that all testing will be done using
- // crypto_stream1_.
- void SetUp() override {
- QuicDispatcherTest::SetUp();
- SetQuicReloadableFlag(enable_quic_stateless_reject_support,
- GetParam().enable_stateless_rejects_via_flag);
- }
-
- // Returns true or false, depending on whether the server will emit
- // a stateless reject, depending upon the parameters of the test.
- bool ExpectStatelessReject() {
- return GetParam().enable_stateless_rejects_via_flag &&
- !GetParam().crypto_handshake_successful &&
- GetParam().client_supports_statelesss_rejects;
- }
-
- // Sets up dispatcher_, session1_, and crypto_stream1_ based on
- // the test parameters.
- QuicServerSessionBase* CreateSessionBasedOnTestParams(
- QuicConnectionId connection_id,
- const QuicSocketAddress& client_address) {
- CreateSession(dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_);
-
- crypto_stream1_ = new MockQuicCryptoServerStream(
- crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- session1_, session1_->stream_helper());
- session1_->SetCryptoStream(crypto_stream1_);
- crypto_stream1_->set_handshake_confirmed_for_testing(
- GetParam().crypto_handshake_successful);
- crypto_stream1_->SetPeerSupportsStatelessRejects(
- GetParam().client_supports_statelesss_rejects);
- return session1_;
- }
-
- MockQuicCryptoServerStream* crypto_stream1_;
-};
-
-// Parameterized test for stateless rejects. Should test all
-// combinations of enabling/disabling, reject/no-reject for stateless
-// rejects.
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherStatelessRejectTests,
- QuicDispatcherStatelessRejectTest,
- ::testing::ValuesIn(GetStatelessRejectTestParams()));
-
-TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = TestConnectionId(1);
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq"), _))
- .WillOnce(testing::Return(
- CreateSessionBasedOnTestParams(connection_id, client_address)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id, _))
- .Times(1);
-
- // Process the first packet for the connection.
- ProcessPacket(client_address, connection_id, true, SerializeCHLO());
- if (ExpectStatelessReject()) {
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
- // If this is a stateless reject, the crypto stream will close the
- // connection.
- session1_->connection()->CloseConnection(
- QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject",
- ConnectionCloseBehavior::SILENT_CLOSE);
- }
-
- // Send a second packet and check the results. If this is a stateless reject,
- // the existing connection_id will go on the time-wait list.
- EXPECT_EQ(ExpectStatelessReject(),
- time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
- if (ExpectStatelessReject()) {
- // The second packet will be processed on the time-wait list.
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _))
- .Times(1);
- } else {
- // The second packet will trigger a packet-validation
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .Times(1)
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- }
- ProcessPacket(client_address, connection_id, true, "data");
-}
-
-TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
- CreateTimeWaitListManager();
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = TestConnectionId(1);
- if (GetParam().enable_stateless_rejects_via_flag) {
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(connection_id, client_address, _, _))
- .Times(0);
- } else {
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("h2"), _))
- .WillOnce(testing::Return(
- CreateSessionBasedOnTestParams(connection_id, client_address)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- }
-
- QUIC_LOG(INFO) << "ExpectStatelessReject: " << ExpectStatelessReject();
- QUIC_LOG(INFO) << "Params: " << GetParam();
- // Process the first packet for the connection.
- CryptoHandshakeMessage client_hello =
- crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"COPT", "SREJ"},
- {"NONC", "1234567890123456789012"},
- {"ALPN", "h2"},
- {"VER\0", "Q025"}},
- kClientHelloMinimumSize);
-
- if (GetParam().enable_stateless_rejects_via_flag) {
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _))
- .Times(1);
- } else {
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id, _))
- .Times(1);
- }
- ProcessPacket(client_address, connection_id, true,
- std::string(client_hello.GetSerialized().AsStringPiece()));
-
- if (GetParam().enable_stateless_rejects_via_flag) {
- EXPECT_EQ(true,
- time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
- }
-}
-
-TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) {
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
- CreateTimeWaitListManager();
-
- const QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- const QuicConnectionId connection_id = TestConnectionId(1);
-
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id, _))
- .Times(1);
- ProcessPacket(client_address, connection_id, true, "NOT DATA FOR A CHLO");
-
- // Process the first packet for the connection.
- CryptoHandshakeMessage client_hello =
- crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
- {"KEXS", "C255"},
- {"NONC", "1234567890123456789012"},
- {"ALPN", "h3"},
- {"VER\0", "Q025"}},
- kClientHelloMinimumSize);
-
- // If stateless rejects are enabled then a connection will be created now
- // and the buffered packet will be processed
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("h3"), _))
- .WillOnce(testing::Return(
- CreateSessionBasedOnTestParams(connection_id, client_address)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_address, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })));
- // Expect both packets to be passed to ProcessUdpPacket(). And one of them
- // is already expected in CreateSessionBasedOnTestParams().
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_address, _))
- .WillOnce(WithArg<2>(
- Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(connection_id, packet);
- })))
- .RetiresOnSaturation();
- ProcessPacket(client_address, connection_id, true,
- std::string(client_hello.GetSerialized().AsStringPiece()));
- EXPECT_FALSE(
- time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
-}
-
// Verify the stopgap test: Packets with truncated connection IDs should be
// dropped.
class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {};
@@ -2190,666 +1934,6 @@
dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
}
-// Test which exercises the async GetProof codepaths, especially in the context
-// of stateless rejection.
-class AsyncGetProofTest : public QuicDispatcherTest {
- public:
- AsyncGetProofTest()
- : QuicDispatcherTest(
- std::unique_ptr<FakeProofSource>(new FakeProofSource())),
- client_addr_(QuicIpAddress::Loopback4(), 1234),
- client_addr_2_(QuicIpAddress::Loopback4(), 1357),
- crypto_config_peer_(&crypto_config_),
- server_addr_(QuicIpAddress::Any4(), 5),
- signed_config_(new QuicSignedServerConfig) {
- SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
- SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
- }
-
- void SetUp() override {
- QuicDispatcherTest::SetUp();
-
- clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
- QuicTransportVersion version = AllSupportedTransportVersions().front();
- chlo_ = crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
- &crypto_config_);
- chlo_.SetVector(kCOPT, QuicTagVector{kSREJ});
- chlo_.SetStringPiece(kALPN, "HTTP/1");
- // Pass an inchoate CHLO.
- crypto_test_utils::GenerateFullCHLO(
- chlo_, &crypto_config_, server_addr_, client_addr_, version, clock_,
- signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &full_chlo_);
-
- crypto_test_utils::GenerateFullCHLO(
- chlo_, &crypto_config_, server_addr_, client_addr_2_, version, clock_,
- signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- &full_chlo_2_);
-
- GetFakeProofSource()->Activate();
- }
-
- FakeProofSource* GetFakeProofSource() const {
- return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
- }
-
- std::string SerializeFullCHLO() {
- return std::string(full_chlo_.GetSerialized().AsStringPiece());
- }
-
- std::string SerializeFullCHLOForClient2() {
- return std::string(full_chlo_2_.GetSerialized().AsStringPiece());
- }
-
- std::string SerializeCHLO() {
- return std::string(chlo_.GetSerialized().AsStringPiece());
- }
-
- // Sets up a session, and crypto stream based on the test parameters.
- QuicServerSessionBase* GetSession(QuicConnectionId connection_id,
- QuicSocketAddress client_address) {
- auto it = sessions_.find(connection_id);
- if (it != sessions_.end()) {
- return it->second.session;
- }
-
- TestQuicSpdyServerSession* session;
- CreateSession(dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session);
-
- std::unique_ptr<MockQuicCryptoServerStream> crypto_stream(
- new MockQuicCryptoServerStream(
- crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
- session, session->stream_helper()));
- session->SetCryptoStream(crypto_stream.get());
- crypto_stream->SetPeerSupportsStatelessRejects(true);
- const bool ok =
- sessions_
- .insert(std::make_pair(
- connection_id, SessionInfo{session, std::move(crypto_stream)}))
- .second;
- CHECK(ok);
- return session;
- }
-
- protected:
- const QuicSocketAddress client_addr_;
- const QuicSocketAddress client_addr_2_;
- CryptoHandshakeMessage chlo_;
-
- private:
- QuicCryptoServerConfigPeer crypto_config_peer_;
- QuicSocketAddress server_addr_;
- QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
- const QuicClock* clock_;
- CryptoHandshakeMessage full_chlo_; // CHLO for client_addr_
- CryptoHandshakeMessage full_chlo_2_; // CHLO for client_addr_2_
-
- struct SessionInfo {
- TestQuicSpdyServerSession* session;
- std::unique_ptr<MockQuicCryptoServerStream> crypto_stream;
- };
- std::map<QuicConnectionId, SessionInfo> sessions_;
-};
-
-// Test a simple situation of connections which the StatelessRejector will
-// accept.
-TEST_F(AsyncGetProofTest, BasicAccept) {
- QuicConnectionId conn_id = TestConnectionId(1);
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
-
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id, _));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
- QuicStringPiece("HTTP/1"), _))
- .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- check.Call(1);
- // Complete the ProofSource::GetProof call and verify that a session is
- // created.
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-
- check.Call(2);
- // Verify that a data packet gets processed immediately.
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
-}
-
-TEST_F(AsyncGetProofTest, RestorePacketContext) {
- QuicConnectionId conn_id_1 = TestConnectionId(1);
- QuicConnectionId conn_id_2 = TestConnectionId(2);
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
-
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
- QuicStringPiece("HTTP/1"), _))
- .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_1, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_1, packet);
- })));
-
- EXPECT_CALL(check, Call(2));
-
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_2, _));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_2_,
- QuicStringPiece("HTTP/1"), _))
- .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_2_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2, client_addr_2_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_2, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- dispatcher_->custom_packet_context_ = "connection 1";
- ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Send another CHLO that the StatelessRejector will accept.
- dispatcher_->custom_packet_context_ = "connection 2";
- ProcessPacket(client_addr_2_, conn_id_2, true, SerializeFullCHLOForClient2());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the first ProofSource::GetProof call and verify that a session is
- // created.
- check.Call(1);
-
- EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
- EXPECT_EQ("connection 2", dispatcher_->custom_packet_context_);
-
- // Runs the async proof callback for conn_id_1 from client_addr_.
- GetFakeProofSource()->InvokePendingCallback(0);
-
- EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
- EXPECT_EQ("connection 1", dispatcher_->custom_packet_context_);
-
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Complete the second ProofSource::GetProof call and verify that a session is
- // created.
- check.Call(2);
-
- EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
- EXPECT_EQ("connection 1", dispatcher_->custom_packet_context_);
-
- // Runs the async proof callback for conn_id_2 from client_addr_2_.
- GetFakeProofSource()->InvokePendingCallback(0);
-
- EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
- EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
- EXPECT_EQ("connection 2", dispatcher_->custom_packet_context_);
-
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-}
-
-// Test a simple situation of connections which the StatelessRejector will
-// reject.
-TEST_F(AsyncGetProofTest, BasicReject) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id = TestConnectionId(1);
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id, _, _, _, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id, _, _));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
- QuicStringPiece("hq"), _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id, _, _));
- }
-
- // Send a CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Complete the ProofSource::GetProof call and verify that the connection and
- // packet are processed by the time wait list manager.
- check.Call(1);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-
- // Verify that a data packet is passed to the time wait list manager.
- check.Call(2);
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
-}
-
-// Test a situation with multiple interleaved connections which the
-// StatelessRejector will accept.
-TEST_F(AsyncGetProofTest, MultipleAccept) {
- QuicConnectionId conn_id_1 = TestConnectionId(1);
- QuicConnectionId conn_id_2 = TestConnectionId(2);
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_2, _));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_,
- QuicStringPiece("HTTP/1"), _))
- .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_2, packet);
- })));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_2, packet);
- })));
-
- EXPECT_CALL(check, Call(3));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
-
- EXPECT_CALL(check, Call(4));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
- QuicStringPiece("HTTP/1"), _))
- .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_1, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillRepeatedly(WithArg<2>(
- Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id_1, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Send another CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id_2, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the second ProofSource::GetProof call and verify that a session is
- // created.
- check.Call(1);
- GetFakeProofSource()->InvokePendingCallback(1);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Verify that a data packet on that connection gets processed immediately.
- check.Call(2);
- ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
-
- // Verify that a data packet on the other connection does not get processed
- // yet.
- check.Call(3);
- ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
-
- // Complete the first ProofSource::GetProof call and verify that a session is
- // created and the buffered packet is processed.
- check.Call(4);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-}
-
-// Test a situation with multiple interleaved connections which the
-// StatelessRejector will reject.
-TEST_F(AsyncGetProofTest, MultipleReject) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id_1 = TestConnectionId(1);
- QuicConnectionId conn_id_2 = TestConnectionId(2);
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
-
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_, _, _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_2, _, _, _, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_2, _, _));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_2, _, _));
-
- EXPECT_CALL(check, Call(3));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
-
- EXPECT_CALL(check, Call(4));
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_1, _, _, _, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_1, _, _));
- }
-
- // Send a CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Send another CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id_2, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the second ProofSource::GetProof call and verify that the
- // connection and packet are processed by the time wait manager.
- check.Call(1);
- GetFakeProofSource()->InvokePendingCallback(1);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Verify that a data packet on that connection gets processed immediately by
- // the time wait manager.
- check.Call(2);
- ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
-
- // Verify that a data packet on the first connection gets buffered.
- check.Call(3);
- ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
-
- // Complete the first ProofSource::GetProof call and verify that the CHLO is
- // processed by the time wait manager and the remaining packets are discarded.
- check.Call(4);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
-}
-
-// Test a situation with multiple identical CHLOs which the StatelessRejector
-// will reject.
-TEST_F(AsyncGetProofTest, MultipleIdenticalReject) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id_1 = TestConnectionId(1);
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
- QuicStringPiece(), _))
- .Times(0);
- EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_1, _, _, _, _));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id_1, _, _));
- }
-
- // Send a CHLO that the StatelessRejector will reject.
- ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
-
- // Send an identical CHLO which should get buffered.
- check.Call(1);
- ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
-
- // Complete the ProofSource::GetProof call and verify that the CHLO is
- // rejected and the copy is discarded.
- check.Call(2);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
-}
-
-// Test dispatcher behavior when packets time out of the buffer while CHLO
-// validation is still pending.
-TEST_F(AsyncGetProofTest, BufferTimeout) {
- CreateTimeWaitListManager();
-
- QuicConnectionId conn_id = TestConnectionId(1);
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id, _));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, client_addr_, conn_id, _, _));
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(conn_id, client_addr_, QuicStringPiece(), _))
- .Times(0);
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
-
- // Send a data packet that will get buffered
- check.Call(1);
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id));
-
- // Pretend that enough time has gone by for the packets to get expired out of
- // the buffer
- mock_helper_.AdvanceTime(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
- QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
- store->OnExpirationTimeout();
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-
- // Now allow the CHLO validation to complete, and verify that no connection
- // gets created.
- check.Call(2);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-}
-
-// Test behavior when packets time out of the buffer *and* the connection times
-// out of the time wait manager while CHLO validation is still pending. This
-// *should* be impossible, but anything can happen with timing conditions.
-TEST_F(AsyncGetProofTest, TimeWaitTimeout) {
- QuicConnectionId conn_id = TestConnectionId(1);
- QuicBufferedPacketStore* store =
- QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
- QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
- CreateTimeWaitListManager();
- QuicTimeWaitListManagerPeer::set_clock(time_wait_list_manager_,
- mock_helper_.GetClock());
-
- testing::MockFunction<void(int check_point)> check;
- {
- InSequence s;
- EXPECT_CALL(check, Call(1));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id, _));
-
- EXPECT_CALL(check, Call(2));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(conn_id, _));
- EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
- QuicStringPiece("HTTP/1"), _))
- .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id, client_addr_)->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(
- Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
- ValidatePacket(conn_id, packet);
- })));
- }
-
- // Send a CHLO that the StatelessRejector will accept.
- ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
-
- // Send a data packet that will get buffered
- check.Call(1);
- ProcessPacket(client_addr_, conn_id, true, "My name is Data");
- EXPECT_TRUE(store->HasBufferedPackets(conn_id));
-
- // Pretend that enough time has gone by for the packets to get expired out of
- // the buffer
- mock_helper_.AdvanceTime(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
- QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
- store->OnExpirationTimeout();
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-
- // Pretend that enough time has gone by for the connection ID to be removed
- // from the time wait manager
- mock_helper_.AdvanceTime(
- QuicTimeWaitListManagerPeer::time_wait_period(time_wait_list_manager_));
- QuicTimeWaitListManagerPeer::expiration_alarm(time_wait_list_manager_)
- ->Cancel();
- time_wait_list_manager_->CleanUpOldConnectionIds();
- EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-
- // Now allow the CHLO validation to complete. Expect that a connection is
- // indeed created, since QUIC has forgotten that this connection ever existed.
- // This is a miniscule corner case which should never happen in the wild, so
- // really we are just verifying that the dispatcher does not explode in this
- // situation.
- check.Call(2);
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
- EXPECT_FALSE(store->HasBufferedPackets(conn_id));
- EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-}
-
-// Regression test for
-// https://bugs.chromium.org/p/chromium/issues/detail?id=748289
-TEST_F(AsyncGetProofTest, DispatcherFailedToPickUpVersionForAsyncProof) {
- // This test mimics the scenario that dispatcher's framer can have different
- // version when async proof returns.
- // When dispatcher sends SREJ, the SREJ frame can be serialized in
- // different endianness which causes the client to close the connection
- // because of QUIC_INVALID_STREAM_DATA.
-
- SetQuicReloadableFlag(quic_disable_version_39, false);
- ParsedQuicVersion chlo_version(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
- chlo_.SetVersion(kVER, chlo_version);
- // Send a CHLO with v43. Dispatcher framer's version is set to v43.
- ProcessPacket(client_addr_, TestConnectionId(1), true, chlo_version,
- SerializeCHLO(), CONNECTION_ID_PRESENT,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Send another CHLO with v39. Dispatcher framer's version is set to v39.
- chlo_version.transport_version = QUIC_VERSION_39;
- chlo_.SetVersion(kVER, chlo_version);
- // Invalidate the cached serialized form.
- chlo_.MarkDirty();
- ProcessPacket(client_addr_, TestConnectionId(2), true, chlo_version,
- SerializeCHLO(), CONNECTION_ID_PRESENT,
- PACKET_4BYTE_PACKET_NUMBER, 1);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the ProofSource::GetProof call for v43. This would cause the
- // version mismatch between the CHLO packet and the dispatcher.
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-}
-
-// Regression test for b/116200989.
-TEST_F(AsyncGetProofTest, DispatcherHasWrongLastPacketIsIetfQuic) {
- // Process a packet of v44.
- ParsedQuicVersion chlo_version(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_44);
- chlo_.SetVersion(kVER, chlo_version);
- ProcessPacket(client_addr_, TestConnectionId(1), true, chlo_version,
- SerializeCHLO(), CONNECTION_ID_PRESENT,
- PACKET_4BYTE_PACKET_NUMBER, 1);
-
- // Process another packet of v43.
- chlo_version.transport_version = QUIC_VERSION_43;
- chlo_.SetVersion(kVER, chlo_version);
- // Invalidate the cached serialized form.
- chlo_.MarkDirty();
- ProcessPacket(client_addr_, TestConnectionId(2), true, chlo_version,
- SerializeCHLO(), CONNECTION_ID_PRESENT,
- PACKET_4BYTE_PACKET_NUMBER, 1);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
-
- // Complete the ProofSource::GetProof call for v44.
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
- // Complete the ProofSource::GetProof call for v43.
- GetFakeProofSource()->InvokePendingCallback(0);
- ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
-}
-
} // namespace
} // namespace test
} // namespace quic