gfe-relnote: Add SessionCache to TlsClientHandshaker, protected by reloadable flag quic_supports_tls_handshake PiperOrigin-RevId: 279800830 Change-Id: Ib7b49726c14208f63c5b3a8c552cff36cb5d89bf
diff --git a/quic/core/crypto/quic_crypto_client_config.cc b/quic/core/crypto/quic_crypto_client_config.cc index 6813f7c..6b00c4c 100644 --- a/quic/core/crypto/quic_crypto_client_config.cc +++ b/quic/core/crypto/quic_crypto_client_config.cc
@@ -61,7 +61,13 @@ QuicCryptoClientConfig::QuicCryptoClientConfig( std::unique_ptr<ProofVerifier> proof_verifier) + : QuicCryptoClientConfig(std::move(proof_verifier), nullptr) {} + +QuicCryptoClientConfig::QuicCryptoClientConfig( + std::unique_ptr<ProofVerifier> proof_verifier, + std::unique_ptr<SessionCache> session_cache) : proof_verifier_(std::move(proof_verifier)), + session_cache_(std::move(session_cache)), ssl_ctx_(TlsClientConnection::CreateSslCtx()) { DCHECK(proof_verifier_.get()); SetDefaults(); @@ -850,6 +856,10 @@ return proof_verifier_.get(); } +SessionCache* QuicCryptoClientConfig::session_cache() const { + return session_cache_.get(); +} + SSL_CTX* QuicCryptoClientConfig::ssl_ctx() const { return ssl_ctx_.get(); }
diff --git a/quic/core/crypto/quic_crypto_client_config.h b/quic/core/crypto/quic_crypto_client_config.h index d3e627d..a3e1bcd 100644 --- a/quic/core/crypto/quic_crypto_client_config.h +++ b/quic/core/crypto/quic_crypto_client_config.h
@@ -12,8 +12,10 @@ #include <vector> #include "third_party/boringssl/src/include/openssl/base.h" +#include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" +#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" @@ -27,6 +29,53 @@ class ProofVerifyDetails; class QuicRandom; +// QuicResumptionState stores the state a client needs for performing connection +// resumption. +struct QUIC_EXPORT_PRIVATE QuicResumptionState { + // |tls_session| holds the cryptographic state necessary for a resumption. It + // includes the ALPN negotiated on the connection where the ticket was + // received. + bssl::UniquePtr<SSL_SESSION> tls_session; + + // If the application using QUIC doesn't support 0-RTT handshakes or the + // client didn't receive a 0-RTT capable session ticket from the server, + // |transport_params| will be null. Otherwise, it will contain the transport + // parameters received from the server on the original connection. + std::unique_ptr<TransportParameters> transport_params; + + // If |transport_params| is null, then |application_state| is ignored and + // should be empty. |application_state| contains serialized state that the + // client received from the server at the application layer that the client + // needs to remember when performing a 0-RTT handshake. + std::vector<uint8_t> application_state; +}; + +// SessionCache is an interface for managing storing and retrieving +// QuicResumptionState structs. +class QUIC_EXPORT_PRIVATE SessionCache { + public: + virtual ~SessionCache() {} + + // Inserts |state| into the cache, keyed by |server_id|. Insert is called + // after a session ticket is received. If the session ticket is valid for + // 0-RTT, there may be a delay between its receipt and the call to Insert + // while waiting for application state for |state|. + // + // Insert may be called multiple times per connection. SessionCache + // implementations should support storing multiple entries per server ID. + virtual void Insert(const QuicServerId& server_id, + std::unique_ptr<QuicResumptionState> state) = 0; + + // Lookup is called once at the beginning of each TLS handshake to potentially + // provide the saved state both for the TLS handshake and for sending 0-RTT + // data (if supported). Lookup may return a nullptr. Implementations should + // delete cache entries after returning them in Lookup so that session tickets + // are used only once. + virtual std::unique_ptr<QuicResumptionState> Lookup( + const QuicServerId& server_id, + const SSL_CTX* ctx) = 0; +}; + // QuicCryptoClientConfig contains crypto-related configuration settings for a // client. Note that this object isn't thread-safe. It's designed to be used on // a single thread at a time. @@ -203,8 +252,11 @@ virtual bool Matches(const QuicServerId& server_id) const = 0; }; + // DEPRECATED: Use the constructor below instead. explicit QuicCryptoClientConfig( std::unique_ptr<ProofVerifier> proof_verifier); + QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier, + std::unique_ptr<SessionCache> session_cache); QuicCryptoClientConfig(const QuicCryptoClientConfig&) = delete; QuicCryptoClientConfig& operator=(const QuicCryptoClientConfig&) = delete; ~QuicCryptoClientConfig(); @@ -309,7 +361,7 @@ std::string* error_details); ProofVerifier* proof_verifier() const; - + SessionCache* session_cache() const; SSL_CTX* ssl_ctx() const; // Initialize the CachedState from |canonical_crypto_config| for the @@ -388,6 +440,7 @@ std::vector<std::string> canonical_suffixes_; std::unique_ptr<ProofVerifier> proof_verifier_; + std::unique_ptr<SessionCache> session_cache_; bssl::UniquePtr<SSL_CTX> ssl_ctx_; // The |user_agent_id_| passed in QUIC's CHLO message.
diff --git a/quic/core/crypto/tls_client_connection.cc b/quic/core/crypto/tls_client_connection.cc index f28af66..98aa6e7 100644 --- a/quic/core/crypto/tls_client_connection.cc +++ b/quic/core/crypto/tls_client_connection.cc
@@ -19,6 +19,11 @@ // certificate after the connection is complete. We need to re-verify on // resumption in case of expiration or revocation/distrust. SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback); + + // Configure session caching. + SSL_CTX_set_session_cache_mode( + ssl_ctx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); + SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback); return ssl_ctx; } @@ -30,4 +35,11 @@ ->delegate_->VerifyCert(out_alert); } +// static +int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) { + static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl)) + ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session)); + return 1; +} + } // namespace quic
diff --git a/quic/core/crypto/tls_client_connection.h b/quic/core/crypto/tls_client_connection.h index 6660343..035f420 100644 --- a/quic/core/crypto/tls_client_connection.h +++ b/quic/core/crypto/tls_client_connection.h
@@ -26,6 +26,9 @@ // or ssl_verify_retry if verification is happening asynchronously. virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0; + // Called when a NewSessionTicket is received from the server. + virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0; + // Provides the delegate for callbacks that are shared between client and // server. virtual TlsConnection::Delegate* ConnectionDelegate() = 0; @@ -43,6 +46,10 @@ // implementation is delegated to Delegate::VerifyCert. static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert); + // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls + // Delegate::InsertSession. + static int NewSessionCallback(SSL* ssl, SSL_SESSION* session); + Delegate* delegate_; };
diff --git a/quic/core/crypto/tls_server_connection.cc b/quic/core/crypto/tls_server_connection.cc index 927c75a..f539a08 100644 --- a/quic/core/crypto/tls_server_connection.cc +++ b/quic/core/crypto/tls_server_connection.cc
@@ -16,6 +16,7 @@ SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(), &SelectCertificateCallback); SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr); + SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_NO_TICKET); return ssl_ctx; }
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc index d5b186c..200024f 100644 --- a/quic/core/http/quic_spdy_client_session_test.cc +++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -166,8 +166,10 @@ config.SetMaxIncomingBidirectionalStreamsToSend( server_max_incoming_streams); } + QuicCryptoServerConfig crypto_config = + crypto_test_utils::CryptoServerConfigForTesting(); crypto_test_utils::HandshakeWithFakeServer( - &config, &helper_, &alarm_factory_, connection_, stream, + &config, &crypto_config, &helper_, &alarm_factory_, connection_, stream, AlpnForVersion(connection_->version())); }
diff --git a/quic/core/quic_crypto_client_stream.cc b/quic/core/quic_crypto_client_stream.cc index 354debb..b30cd3a 100644 --- a/quic/core/quic_crypto_client_stream.cc +++ b/quic/core/quic_crypto_client_stream.cc
@@ -43,9 +43,8 @@ break; case PROTOCOL_TLS1_3: handshaker_ = std::make_unique<TlsClientHandshaker>( - this, session, server_id, crypto_config->proof_verifier(), - crypto_config->ssl_ctx(), std::move(verify_context), proof_handler, - crypto_config->user_agent_id()); + server_id, this, session, std::move(verify_context), crypto_config, + proof_handler); break; case PROTOCOL_UNSUPPORTED: QUIC_BUG << "Attempting to create QuicCryptoClientStream for unknown "
diff --git a/quic/core/quic_crypto_client_stream_test.cc b/quic/core/quic_crypto_client_stream_test.cc index 2622439..675dc20 100644 --- a/quic/core/quic_crypto_client_stream_test.cc +++ b/quic/core/quic_crypto_client_stream_test.cc
@@ -22,6 +22,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h" +#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" using testing::_; @@ -37,7 +38,10 @@ QuicCryptoClientStreamTest() : supported_versions_(AllSupportedVersions()), server_id_(kServerHostname, kServerPort, false), - crypto_config_(crypto_test_utils::ProofVerifierForTesting()) { + crypto_config_(crypto_test_utils::ProofVerifierForTesting(), + std::make_unique<test::SimpleSessionCache>()), + server_crypto_config_( + crypto_test_utils::CryptoServerConfigForTesting()) { CreateConnection(); } @@ -56,6 +60,17 @@ {AlpnForVersion(connection_->version())}))); } + void UseTlsHandshake() { + SetQuicReloadableFlag(quic_supports_tls_handshake, true); + supported_versions_.clear(); + for (ParsedQuicVersion version : AllSupportedVersions()) { + if (version.handshake_protocol != PROTOCOL_TLS1_3) { + continue; + } + supported_versions_.push_back(version); + } + } + void CompleteCryptoHandshake() { if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) { EXPECT_CALL(*session_, OnProofValid(testing::_)); @@ -65,8 +80,8 @@ stream()->CryptoConnect(); QuicConfig config; crypto_test_utils::HandshakeWithFakeServer( - &config, &server_helper_, &alarm_factory_, connection_, stream(), - AlpnForVersion(connection_->version())); + &config, &server_crypto_config_, &server_helper_, &alarm_factory_, + connection_, stream(), AlpnForVersion(connection_->version())); } QuicCryptoClientStream* stream() { @@ -82,6 +97,7 @@ QuicServerId server_id_; CryptoHandshakeMessage message_; QuicCryptoClientConfig crypto_config_; + QuicCryptoServerConfig server_crypto_config_; }; TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) { @@ -97,14 +113,7 @@ } TEST_F(QuicCryptoClientStreamTest, ConnectedAfterTlsHandshake) { - SetQuicReloadableFlag(quic_supports_tls_handshake, true); - supported_versions_.clear(); - for (ParsedQuicVersion version : AllSupportedVersions()) { - if (version.handshake_protocol != PROTOCOL_TLS1_3) { - continue; - } - supported_versions_.push_back(version); - } + UseTlsHandshake(); CreateConnection(); CompleteCryptoHandshake(); EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol()); @@ -115,27 +124,44 @@ TEST_F(QuicCryptoClientStreamTest, ProofVerifyDetailsAvailableAfterTlsHandshake) { - SetQuicReloadableFlag(quic_supports_tls_handshake, true); - supported_versions_.clear(); - for (ParsedQuicVersion version : AllSupportedVersions()) { - if (version.handshake_protocol != PROTOCOL_TLS1_3) { - continue; - } - supported_versions_.push_back(version); - } + UseTlsHandshake(); CreateConnection(); EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_)); stream()->CryptoConnect(); QuicConfig config; crypto_test_utils::HandshakeWithFakeServer( - &config, &server_helper_, &alarm_factory_, connection_, stream(), - AlpnForVersion(connection_->version())); + &config, &server_crypto_config_, &server_helper_, &alarm_factory_, + connection_, stream(), AlpnForVersion(connection_->version())); EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol()); EXPECT_TRUE(stream()->encryption_established()); EXPECT_TRUE(stream()->handshake_confirmed()); } +TEST_F(QuicCryptoClientStreamTest, TlsResumption) { + UseTlsHandshake(); + // Enable resumption on the server: + SSL_CTX_clear_options(server_crypto_config_.ssl_ctx(), SSL_OP_NO_TICKET); + CreateConnection(); + + // Finish establishing the first connection: + CompleteCryptoHandshake(); + + EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol()); + EXPECT_TRUE(stream()->encryption_established()); + EXPECT_TRUE(stream()->handshake_confirmed()); + EXPECT_FALSE(stream()->IsResumption()); + + // Create a second connection + CreateConnection(); + CompleteCryptoHandshake(); + + EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol()); + EXPECT_TRUE(stream()->encryption_established()); + EXPECT_TRUE(stream()->handshake_confirmed()); + EXPECT_TRUE(stream()->IsResumption()); +} + TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) { CompleteCryptoHandshake();
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc index 2056953..85a278c 100644 --- a/quic/core/tls_client_handshaker.cc +++ b/quic/core/tls_client_handshaker.cc
@@ -43,22 +43,21 @@ } TlsClientHandshaker::TlsClientHandshaker( + const QuicServerId& server_id, QuicCryptoStream* stream, QuicSession* session, - const QuicServerId& server_id, - ProofVerifier* proof_verifier, - SSL_CTX* ssl_ctx, std::unique_ptr<ProofVerifyContext> verify_context, - QuicCryptoClientStream::ProofHandler* proof_handler, - const std::string& user_agent_id) - : TlsHandshaker(stream, session, ssl_ctx), + QuicCryptoClientConfig* crypto_config, + QuicCryptoClientStream::ProofHandler* proof_handler) + : TlsHandshaker(stream, session, crypto_config->ssl_ctx()), server_id_(server_id), - proof_verifier_(proof_verifier), + proof_verifier_(crypto_config->proof_verifier()), verify_context_(std::move(verify_context)), proof_handler_(proof_handler), - user_agent_id_(user_agent_id), + session_cache_(crypto_config->session_cache()), + user_agent_id_(crypto_config->user_agent_id()), crypto_negotiated_params_(new QuicCryptoNegotiatedParameters), - tls_connection_(ssl_ctx, this) {} + tls_connection_(crypto_config->ssl_ctx(), this) {} TlsClientHandshaker::~TlsClientHandshaker() { if (proof_verify_callback_) { @@ -87,6 +86,15 @@ return false; } + // Set a session to resume, if there is one. + if (session_cache_) { + std::unique_ptr<QuicResumptionState> cached_state = + session_cache_->Lookup(server_id_, SSL_get_SSL_CTX(ssl())); + if (cached_state) { + SSL_set_session(ssl(), cached_state->tls_session.get()); + } + } + // Start the handshake. AdvanceHandshake(); return session()->connection()->connected(); @@ -199,8 +207,7 @@ bool TlsClientHandshaker::IsResumption() const { QUIC_BUG_IF(!handshake_confirmed_); - // We don't support resumption (yet). - return false; + return SSL_session_reused(ssl()) == 1; } int TlsClientHandshaker::num_scup_messages_received() const { @@ -246,7 +253,10 @@ return; } if (state_ == STATE_HANDSHAKE_COMPLETE) { - // TODO(nharper): Handle post-handshake messages. + int rv = SSL_process_quic_post_handshake(ssl()); + if (rv != 1) { + CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data"); + } return; } @@ -394,4 +404,14 @@ } } +void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) { + if (session_cache_ == nullptr) { + QUIC_DVLOG(1) << "No session cache, not inserting a session"; + return; + } + auto cache_state = std::make_unique<QuicResumptionState>(); + cache_state->tls_session = std::move(session); + session_cache_->Insert(server_id_, std::move(cache_state)); +} + } // namespace quic
diff --git a/quic/core/tls_client_handshaker.h b/quic/core/tls_client_handshaker.h index 17b529e..0b473a3 100644 --- a/quic/core/tls_client_handshaker.h +++ b/quic/core/tls_client_handshaker.h
@@ -24,14 +24,12 @@ public QuicCryptoClientStream::HandshakerDelegate, public TlsClientConnection::Delegate { public: - TlsClientHandshaker(QuicCryptoStream* stream, + TlsClientHandshaker(const QuicServerId& server_id, + QuicCryptoStream* stream, QuicSession* session, - const QuicServerId& server_id, - ProofVerifier* proof_verifier, - SSL_CTX* ssl_ctx, std::unique_ptr<ProofVerifyContext> verify_context, - QuicCryptoClientStream::ProofHandler* proof_handler, - const std::string& user_agent_id); + QuicCryptoClientConfig* crypto_config, + QuicCryptoClientStream::ProofHandler* proof_handler); TlsClientHandshaker(const TlsClientHandshaker&) = delete; TlsClientHandshaker& operator=(const TlsClientHandshaker&) = delete; @@ -101,6 +99,8 @@ bool ProcessTransportParameters(std::string* error_details); void FinishHandshake(); + void InsertSession(bssl::UniquePtr<SSL_SESSION> session) override; + QuicServerId server_id_; // Objects used for verifying the server's certificate chain. @@ -113,6 +113,10 @@ // certificate verification. QuicCryptoClientStream::ProofHandler* proof_handler_; + // Used for session resumption. |session_cache_| is owned by the + // QuicCryptoClientConfig passed into TlsClientHandshaker's constructor. + SessionCache* session_cache_; + std::string user_agent_id_; // ProofVerifierCallback used for async certificate verification. This object
diff --git a/quic/core/tls_handshaker_test.cc b/quic/core/tls_handshaker_test.cc index 96691fa..d3463a8 100644 --- a/quic/core/tls_handshaker_test.cc +++ b/quic/core/tls_handshaker_test.cc
@@ -223,17 +223,15 @@ public: explicit TestQuicCryptoClientStream(QuicSession* session) : TestQuicCryptoStream(session), - proof_verifier_(new FakeProofVerifier), - ssl_ctx_(TlsClientConnection::CreateSslCtx()), + crypto_config_(std::make_unique<FakeProofVerifier>(), + /*session_cache*/ nullptr), handshaker_(new TlsClientHandshaker( + QuicServerId("test.example.com", 443, false), this, session, - QuicServerId("test.example.com", 443, false), - proof_verifier_.get(), - ssl_ctx_.get(), crypto_test_utils::ProofVerifyContextForTesting(), - &proof_handler_, - "quic-tester")) {} + &crypto_config_, + &proof_handler_)) {} ~TestQuicCryptoClientStream() override = default; @@ -244,13 +242,12 @@ bool CryptoConnect() { return handshaker_->CryptoConnect(); } FakeProofVerifier* GetFakeProofVerifier() const { - return proof_verifier_.get(); + return static_cast<FakeProofVerifier*>(crypto_config_.proof_verifier()); } private: - std::unique_ptr<FakeProofVerifier> proof_verifier_; MockProofHandler proof_handler_; - bssl::UniquePtr<SSL_CTX> ssl_ctx_; + QuicCryptoClientConfig crypto_config_; std::unique_ptr<TlsClientHandshaker> handshaker_; };
diff --git a/quic/quic_transport/quic_transport_client_session_test.cc b/quic/quic_transport/quic_transport_client_session_test.cc index 1d9f05e..91aecdb 100644 --- a/quic/quic_transport/quic_transport_client_session_test.cc +++ b/quic/quic_transport/quic_transport_client_session_test.cc
@@ -76,9 +76,11 @@ void Connect() { session_->CryptoConnect(); QuicConfig server_config = DefaultQuicConfig(); + QuicCryptoServerConfig crypto_config = + crypto_test_utils::CryptoServerConfigForTesting(); crypto_test_utils::HandshakeWithFakeServer( - &server_config, &helper_, &alarm_factory_, &connection_, crypto_stream_, - QuicTransportAlpn()); + &server_config, &crypto_config, &helper_, &alarm_factory_, &connection_, + crypto_stream_, QuicTransportAlpn()); } MockAlarmFactory alarm_factory_;
diff --git a/quic/test_tools/crypto_test_utils.cc b/quic/test_tools/crypto_test_utils.cc index f38ea81..e2dc56c 100644 --- a/quic/test_tools/crypto_test_utils.cc +++ b/quic/test_tools/crypto_test_utils.cc
@@ -209,7 +209,14 @@ } // namespace +QuicCryptoServerConfig CryptoServerConfigForTesting() { + return QuicCryptoServerConfig( + QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), + ProofSourceForTesting(), KeyExchangeSource::Default()); +} + int HandshakeWithFakeServer(QuicConfig* server_quic_config, + QuicCryptoServerConfig* crypto_config, MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory, PacketSavingConnection* client_conn, @@ -219,17 +226,14 @@ helper, alarm_factory, Perspective::IS_SERVER, ParsedVersionOfIndex(client_conn->supported_versions(), 0)); - QuicCryptoServerConfig crypto_config( - QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), - ProofSourceForTesting(), KeyExchangeSource::Default()); QuicCompressedCertsCache compressed_certs_cache( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize); SetupCryptoServerConfigForTest( - server_conn->clock(), server_conn->random_generator(), &crypto_config); + server_conn->clock(), server_conn->random_generator(), crypto_config); TestQuicSpdyServerSession server_session( server_conn, *server_quic_config, client_conn->supported_versions(), - &crypto_config, &compressed_certs_cache); + crypto_config, &compressed_certs_cache); server_session.OnSuccessfulVersionNegotiation( client_conn->supported_versions().front()); EXPECT_CALL(*server_session.helper(), @@ -346,7 +350,8 @@ MovePackets(client_conn, &client_i, server, server_conn, Perspective::IS_SERVER); - if (client->handshake_confirmed() && server->handshake_confirmed()) { + if (client->handshake_confirmed() && server->handshake_confirmed() && + server_conn->encrypted_packets_.size() == server_i) { break; } ASSERT_GT(server_conn->encrypted_packets_.size(), server_i);
diff --git a/quic/test_tools/crypto_test_utils.h b/quic/test_tools/crypto_test_utils.h index 6f87e90..2071614 100644 --- a/quic/test_tools/crypto_test_utils.h +++ b/quic/test_tools/crypto_test_utils.h
@@ -64,8 +64,13 @@ bool only_tls_versions = false; }; +// Returns a QuicCryptoServerConfig that is in a reasonable configuration to +// pass into HandshakeWithFakeServer. +QuicCryptoServerConfig CryptoServerConfigForTesting(); + // returns: the number of client hellos that the client sent. int HandshakeWithFakeServer(QuicConfig* server_quic_config, + QuicCryptoServerConfig* crypto_config, MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory, PacketSavingConnection* client_conn,
diff --git a/quic/test_tools/simple_session_cache.cc b/quic/test_tools/simple_session_cache.cc new file mode 100644 index 0000000..7787fbe --- /dev/null +++ b/quic/test_tools/simple_session_cache.cc
@@ -0,0 +1,28 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" + +namespace quic { +namespace test { + +void SimpleSessionCache::Insert(const QuicServerId& server_id, + std::unique_ptr<QuicResumptionState> state) { + cache_entries_.insert(std::make_pair(server_id, std::move(state))); +} + +std::unique_ptr<QuicResumptionState> SimpleSessionCache::Lookup( + const QuicServerId& server_id, + const SSL_CTX* /*ctx*/) { + auto it = cache_entries_.find(server_id); + if (it == cache_entries_.end()) { + return nullptr; + } + std::unique_ptr<QuicResumptionState> state = std::move(it->second); + cache_entries_.erase(it); + return state; +} + +} // namespace test +} // namespace quic
diff --git a/quic/test_tools/simple_session_cache.h b/quic/test_tools/simple_session_cache.h new file mode 100644 index 0000000..40a6946 --- /dev/null +++ b/quic/test_tools/simple_session_cache.h
@@ -0,0 +1,35 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_ +#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_ + +#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" + +namespace quic { +namespace test { + +// SimpleSessionCache provides a simple implementation of SessionCache that +// stores only one QuicResumptionState per QuicServerId. No limit is placed on +// the total number of entries in the cache. When Lookup is called, if a cache +// entry exists for the provided QuicServerId, the entry will be removed from +// the cached when it is returned. +class SimpleSessionCache : public SessionCache { + public: + SimpleSessionCache() = default; + ~SimpleSessionCache() override = default; + + void Insert(const QuicServerId& server_id, + std::unique_ptr<QuicResumptionState> state) override; + std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id, + const SSL_CTX* ctx) override; + + private: + std::map<QuicServerId, std::unique_ptr<QuicResumptionState>> cache_entries_; +}; + +} // namespace test +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_