#include "net/ssl/ssl_client_session_cache.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/schemeful_site.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "url/gurl.h"
using testing::ByRef;
using testing::Contains;
using testing::Eq;
using testing::Field;
namespace net {
namespace {
std::unique_ptr<base::SimpleTestClock> MakeTestClock() {
std::unique_ptr<base::SimpleTestClock> clock =
std::make_unique<base::SimpleTestClock>();
clock->SetNow(base::Time::FromTimeT(1000000000));
return clock;
}
SSLClientSessionCache::Key MakeTestKey(const std::string& str) {
SSLClientSessionCache::Key key;
key.server = HostPortPair(str, 443);
return key;
}
SSLClientSessionCache::Key AddProxyChain(SSLClientSessionCache::Key key) {
key.proxy_chain = ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS,
"proxy", 999);
key.proxy_chain_index = 0;
return key;
}
SSLClientSessionCache::Key WithProxyUsage(SSLClientSessionCache::Key key) {
key.session_usage = SessionUsage::kProxy;
return key;
}
class SSLClientSessionCacheTest : public testing::Test {
public:
SSLClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {}
protected:
bssl::UniquePtr<SSL_SESSION> NewSSLSession(
uint16_t version = TLS1_2_VERSION) {
SSL_SESSION* session = SSL_SESSION_new(ssl_ctx_.get());
if (!SSL_SESSION_set_protocol_version(session, version))
return nullptr;
return bssl::UniquePtr<SSL_SESSION>(session);
}
bssl::UniquePtr<SSL_SESSION> MakeTestSession(base::Time now,
base::TimeDelta timeout) {
bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
SSL_SESSION_set_time(session.get(), now.ToTimeT());
SSL_SESSION_set_timeout(session.get(), timeout.InSeconds());
return session;
}
private:
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
};
}
TEST_F(SSLClientSessionCacheTest, Basic) {
SSLClientSessionCache::Config config;
SSLClientSessionCache cache(config);
bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session4 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session5 = NewSSLSession();
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(1u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session2));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(2u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session3));
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(2u, cache.size());
cache.Insert(cache.generation_number(), AddProxyChain(MakeTestKey("key1")),
bssl::UpRef(session4));
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session4.get(),
cache.Lookup(AddProxyChain(MakeTestKey("key1"))).get());
EXPECT_EQ(3u, cache.size());
cache.Insert(cache.generation_number(), WithProxyUsage(MakeTestKey("key1")),
bssl::UpRef(session5));
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session5.get(),
cache.Lookup(WithProxyUsage(MakeTestKey("key1"))).get());
EXPECT_EQ(4u, cache.size());
cache.Flush();
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key3")).get());
EXPECT_EQ(nullptr, cache.Lookup(AddProxyChain(MakeTestKey("key1"))).get());
EXPECT_EQ(nullptr, cache.Lookup(WithProxyUsage(MakeTestKey("key1"))).get());
EXPECT_EQ(0u, cache.size());
}
TEST_F(SSLClientSessionCacheTest, BasicSingleUse) {
SSLClientSessionCache::Config config;
SSLClientSessionCache cache(config);
bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession(TLS1_3_VERSION);
bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession(TLS1_3_VERSION);
bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession(TLS1_3_VERSION);
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session2));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(1u, cache.size());
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session3));
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session2));
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
cache.Flush();
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key3")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session2));
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session3));
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
}
TEST_F(SSLClientSessionCacheTest, MixedUse) {
SSLClientSessionCache::Config config;
SSLClientSessionCache cache(config);
bssl::UniquePtr<SSL_SESSION> session_single = NewSSLSession(TLS1_3_VERSION);
bssl::UniquePtr<SSL_SESSION> session_reuse = NewSSLSession(TLS1_2_VERSION);
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session_reuse));
EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(1u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session_single));
EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(0u, cache.size());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session_single));
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session_single));
EXPECT_EQ(1u, cache.size());
EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session_single));
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session_reuse));
EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(1u, cache.size());
}
TEST_F(SSLClientSessionCacheTest, DoubleInsert) {
SSLClientSessionCache::Config config;
SSLClientSessionCache cache(config);
bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session));
EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(1u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session));
EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(2u, cache.size());
cache.Flush();
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(0u, cache.size());
}
TEST_F(SSLClientSessionCacheTest, MaxEntries) {
SSLClientSessionCache::Config config;
config.max_entries = 3;
SSLClientSessionCache cache(config);
bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session4 = NewSSLSession();
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session2));
cache.Insert(cache.generation_number(), MakeTestKey("key3"),
bssl::UpRef(session3));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
EXPECT_EQ(3u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key4"),
bssl::UpRef(session4));
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session4.get(), cache.Lookup(MakeTestKey("key4")).get());
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(3u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key4")).get());
EXPECT_EQ(3u, cache.size());
}
TEST_F(SSLClientSessionCacheTest, Expiration) {
const size_t kNumEntries = 20;
const size_t kExpirationCheckCount = 10;
const base::TimeDelta kTimeout = base::Seconds(1000);
SSLClientSessionCache::Config config;
config.expiration_check_count = kExpirationCheckCount;
std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
SSLClientSessionCache cache(config);
cache.SetClockForTesting(clock.get());
for (size_t i = 0; i < kNumEntries - 1; i++) {
bssl::UniquePtr<SSL_SESSION> session =
MakeTestSession(clock->Now(), kTimeout);
cache.Insert(cache.generation_number(),
MakeTestKey(base::NumberToString(i)), bssl::UpRef(session));
}
EXPECT_EQ(kNumEntries - 1, cache.size());
clock->Advance(kTimeout * 2);
bssl::UniquePtr<SSL_SESSION> session =
MakeTestSession(clock->Now(), kTimeout);
cache.Insert(cache.generation_number(), MakeTestKey("key"),
bssl::UpRef(session));
EXPECT_EQ(kNumEntries, cache.size());
for (size_t i = 0; i < kExpirationCheckCount - 1; i++)
cache.Lookup(MakeTestKey("key"));
EXPECT_EQ(kNumEntries, cache.size());
cache.Lookup(MakeTestKey("key"));
EXPECT_EQ(1u, cache.size());
EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
for (size_t i = 0; i < kNumEntries - 1; i++) {
SCOPED_TRACE(i);
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey(base::NumberToString(i))));
}
}
TEST_F(SSLClientSessionCacheTest, LookupExpirationCheck) {
const size_t kExpirationCheckCount = 1000;
const base::TimeDelta kTimeout = base::Seconds(1000);
SSLClientSessionCache::Config config;
config.expiration_check_count = kExpirationCheckCount;
std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
SSLClientSessionCache cache(config);
cache.SetClockForTesting(clock.get());
bssl::UniquePtr<SSL_SESSION> session =
MakeTestSession(clock->Now(), kTimeout);
cache.Insert(cache.generation_number(), MakeTestKey("key"),
bssl::UpRef(session));
EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
EXPECT_EQ(1u, cache.size());
clock->Advance(kTimeout * 2);
EXPECT_EQ(1u, cache.size());
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(cache.generation_number(), MakeTestKey("key"),
bssl::UpRef(session));
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
EXPECT_EQ(0u, cache.size());
session = MakeTestSession(clock->Now(), kTimeout);
cache.Insert(cache.generation_number(), MakeTestKey("key"),
bssl::UpRef(session));
EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
EXPECT_EQ(1u, cache.size());
clock->Advance(base::Seconds(-2));
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
EXPECT_EQ(0u, cache.size());
}
TEST_F(SSLClientSessionCacheTest, TestFlushOnMemoryNotifications) {
base::test::TaskEnvironment task_environment;
const size_t kExpirationCheckCount = 1000;
const base::TimeDelta kTimeout = base::Seconds(1000);
SSLClientSessionCache::Config config;
config.expiration_check_count = kExpirationCheckCount;
std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
SSLClientSessionCache cache(config);
cache.SetClockForTesting(clock.get());
bssl::UniquePtr<SSL_SESSION> session1 =
MakeTestSession(clock->Now(), kTimeout);
cache.Insert(cache.generation_number(), MakeTestKey("key1"),
bssl::UpRef(session1));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(1u, cache.size());
clock->Advance(kTimeout * 2);
bssl::UniquePtr<SSL_SESSION> session2 =
MakeTestSession(clock->Now(), kTimeout);
cache.Insert(cache.generation_number(), MakeTestKey("key2"),
bssl::UpRef(session2));
EXPECT_EQ(2u, cache.size());
base::MemoryPressureListener::NotifyMemoryPressure(
base::MEMORY_PRESSURE_LEVEL_MODERATE);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(cache.Lookup(MakeTestKey("key1")));
EXPECT_TRUE(cache.Lookup(MakeTestKey("key2")));
EXPECT_EQ(1u, cache.size());
base::MemoryPressureListener::NotifyMemoryPressure(
base::MEMORY_PRESSURE_LEVEL_CRITICAL);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, cache.size());
}
TEST_F(SSLClientSessionCacheTest, FlushForServer) {
SSLClientSessionCache::Config config;
SSLClientSessionCache cache(config);
const SchemefulSite kSiteA(GURL("https://a.test"));
const SchemefulSite kSiteB(GURL("https://b.test"));
SSLClientSessionCache::Key key1;
key1.server = HostPortPair("a.test", 443);
auto session1 = NewSSLSession();
cache.Insert(cache.generation_number(), key1, bssl::UpRef(session1));
SSLClientSessionCache::Key key2;
key2.server = HostPortPair("a.test", 443);
key2.dest_ip_addr = IPAddress::IPv4Localhost();
key2.network_anonymization_key =
NetworkAnonymizationKey::CreateSameSite(kSiteB);
key2.privacy_mode = PRIVACY_MODE_ENABLED;
auto session2 = NewSSLSession();
cache.Insert(cache.generation_number(), key2, bssl::UpRef(session2));
SSLClientSessionCache::Key key3;
key3.server = HostPortPair("a.test", 444);
auto session3 = NewSSLSession();
cache.Insert(cache.generation_number(), key3, bssl::UpRef(session3));
SSLClientSessionCache::Key key4;
key4.server = HostPortPair("b.test", 443);
auto session4 = NewSSLSession();
cache.Insert(cache.generation_number(), key4, bssl::UpRef(session4));
SSLClientSessionCache::Key key5;
key5.server = HostPortPair("b.test", 443);
key5.network_anonymization_key =
NetworkAnonymizationKey::CreateSameSite(kSiteA);
auto session5 = NewSSLSession();
cache.Insert(cache.generation_number(), key5, bssl::UpRef(session5));
cache.FlushForServers({HostPortPair("c.test", 443)});
EXPECT_EQ(5u, cache.size());
EXPECT_EQ(session1.get(), cache.Lookup(key1).get());
EXPECT_EQ(session2.get(), cache.Lookup(key2).get());
EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
EXPECT_EQ(session4.get(), cache.Lookup(key4).get());
EXPECT_EQ(session5.get(), cache.Lookup(key5).get());
cache.FlushForServers({HostPortPair("a.test", 443)});
EXPECT_EQ(3u, cache.size());
EXPECT_EQ(nullptr, cache.Lookup(key1).get());
EXPECT_EQ(nullptr, cache.Lookup(key2).get());
EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
EXPECT_EQ(session4.get(), cache.Lookup(key4).get());
EXPECT_EQ(session5.get(), cache.Lookup(key5).get());
cache.FlushForServers({HostPortPair("b.test", 443)});
EXPECT_EQ(1u, cache.size());
EXPECT_EQ(nullptr, cache.Lookup(key1).get());
EXPECT_EQ(nullptr, cache.Lookup(key2).get());
EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
EXPECT_EQ(nullptr, cache.Lookup(key4).get());
EXPECT_EQ(nullptr, cache.Lookup(key5).get());
cache.FlushForServers({HostPortPair("a.test", 444)});
EXPECT_EQ(0u, cache.size());
EXPECT_EQ(nullptr, cache.Lookup(key1).get());
EXPECT_EQ(nullptr, cache.Lookup(key2).get());
EXPECT_EQ(nullptr, cache.Lookup(key3).get());
EXPECT_EQ(nullptr, cache.Lookup(key4).get());
EXPECT_EQ(nullptr, cache.Lookup(key5).get());
}
TEST_F(SSLClientSessionCacheTest, FlushForServers) {
SSLClientSessionCache::Config config;
SSLClientSessionCache cache(config);
const SchemefulSite kSiteA(GURL("https://a.test"));
const SchemefulSite kSiteB(GURL("https://b.test"));
SSLClientSessionCache::Key key1;
key1.server = HostPortPair("a.test", 443);
auto session1 = NewSSLSession();
cache.Insert(cache.generation_number(), key1, bssl::UpRef(session1));
SSLClientSessionCache::Key key2;
key2.server = HostPortPair("a.test", 443);
key2.dest_ip_addr = IPAddress::IPv4Localhost();
key2.network_anonymization_key =
NetworkAnonymizationKey::CreateSameSite(kSiteB);
key2.privacy_mode = PRIVACY_MODE_ENABLED;
auto session2 = NewSSLSession();
cache.Insert(cache.generation_number(), key2, bssl::UpRef(session2));
SSLClientSessionCache::Key key3;
key3.server = HostPortPair("a.test", 444);
auto session3 = NewSSLSession();
cache.Insert(cache.generation_number(), key3, bssl::UpRef(session3));
SSLClientSessionCache::Key key4;
key4.server = HostPortPair("b.test", 443);
auto session4 = NewSSLSession();
cache.Insert(cache.generation_number(), key4, bssl::UpRef(session4));
SSLClientSessionCache::Key key5;
key5.server = HostPortPair("b.test", 443);
key5.network_anonymization_key =
NetworkAnonymizationKey::CreateSameSite(kSiteA);
auto session5 = NewSSLSession();
cache.Insert(cache.generation_number(), key5, bssl::UpRef(session5));
cache.FlushForServers({
HostPortPair("c.test", 443),
HostPortPair("a.test", 443),
HostPortPair("b.test", 443),
});
EXPECT_EQ(1u, cache.size());
EXPECT_EQ(nullptr, cache.Lookup(key1).get());
EXPECT_EQ(nullptr, cache.Lookup(key2).get());
EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
EXPECT_EQ(nullptr, cache.Lookup(key4).get());
EXPECT_EQ(nullptr, cache.Lookup(key5).get());
}
TEST_F(SSLClientSessionCacheTest, InsertStaleConfigId) {
SSLClientSessionCache::Config config;
SSLClientSessionCache cache(config);
bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session4 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session5 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session6 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session7 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session8 = NewSSLSession();
bssl::UniquePtr<SSL_SESSION> session9 = NewSSLSession();
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(0u, cache.size());
const uint64_t generation_number_0 = cache.generation_number();
cache.Insert(generation_number_0, MakeTestKey("key1"), bssl::UpRef(session1));
EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(1u, cache.size());
cache.Flush();
EXPECT_EQ(0u, cache.size());
cache.Insert(generation_number_0, MakeTestKey("key1"), bssl::UpRef(session2));
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(0u, cache.size());
const uint64_t generation_number_1 = cache.generation_number();
cache.Insert(generation_number_1, MakeTestKey("key1"), bssl::UpRef(session3));
EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(1u, cache.size());
cache.Flush();
EXPECT_EQ(0u, cache.size());
cache.Insert(generation_number_0, MakeTestKey("key1"), bssl::UpRef(session4));
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(0u, cache.size());
cache.Insert(generation_number_1, MakeTestKey("key1"), bssl::UpRef(session5));
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(0u, cache.size());
const uint64_t generation_number_2 = cache.generation_number();
cache.Insert(generation_number_2, MakeTestKey("key1"), bssl::UpRef(session6));
EXPECT_EQ(session6.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(1u, cache.size());
cache.Insert(generation_number_2, MakeTestKey("key2"), bssl::UpRef(session7));
EXPECT_EQ(session7.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(2u, cache.size());
cache.FlushForServers({HostPortPair("key2", 443)});
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(session6.get(), cache.Lookup(MakeTestKey("key1")).get());
EXPECT_EQ(1u, cache.size());
cache.Insert(generation_number_2, MakeTestKey("key2"), bssl::UpRef(session8));
EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(1u, cache.size());
const uint64_t generation_number_3 = cache.generation_number();
cache.Insert(generation_number_3, MakeTestKey("key2"), bssl::UpRef(session9));
EXPECT_EQ(session9.get(), cache.Lookup(MakeTestKey("key2")).get());
EXPECT_EQ(2u, cache.size());
}
}