ssl_client_session_cache_unittest.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/ssl/ssl_client_session_cache.h"
  5. #include "base/run_loop.h"
  6. #include "base/strings/string_number_conversions.h"
  7. #include "base/test/simple_test_clock.h"
  8. #include "base/test/task_environment.h"
  9. #include "base/time/time.h"
  10. #include "base/trace_event/memory_allocator_dump.h"
  11. #include "base/trace_event/process_memory_dump.h"
  12. #include "base/trace_event/traced_value.h"
  13. #include "net/base/network_isolation_key.h"
  14. #include "net/base/schemeful_site.h"
  15. #include "testing/gmock/include/gmock/gmock.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. #include "third_party/boringssl/src/include/openssl/ssl.h"
  18. #include "url/gurl.h"
  19. using testing::ByRef;
  20. using testing::Contains;
  21. using testing::Eq;
  22. using testing::Field;
  23. namespace net {
  24. namespace {
  25. std::unique_ptr<base::SimpleTestClock> MakeTestClock() {
  26. std::unique_ptr<base::SimpleTestClock> clock =
  27. std::make_unique<base::SimpleTestClock>();
  28. // SimpleTestClock starts at the null base::Time which converts to and from
  29. // time_t confusingly.
  30. clock->SetNow(base::Time::FromTimeT(1000000000));
  31. return clock;
  32. }
  33. SSLClientSessionCache::Key MakeTestKey(const std::string& str) {
  34. SSLClientSessionCache::Key key;
  35. key.server = HostPortPair(str, 443);
  36. return key;
  37. }
  38. class SSLClientSessionCacheTest : public testing::Test {
  39. public:
  40. SSLClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {}
  41. protected:
  42. bssl::UniquePtr<SSL_SESSION> NewSSLSession(
  43. uint16_t version = TLS1_2_VERSION) {
  44. SSL_SESSION* session = SSL_SESSION_new(ssl_ctx_.get());
  45. if (!SSL_SESSION_set_protocol_version(session, version))
  46. return nullptr;
  47. return bssl::UniquePtr<SSL_SESSION>(session);
  48. }
  49. bssl::UniquePtr<SSL_SESSION> MakeTestSession(base::Time now,
  50. base::TimeDelta timeout) {
  51. bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
  52. SSL_SESSION_set_time(session.get(), now.ToTimeT());
  53. SSL_SESSION_set_timeout(session.get(), timeout.InSeconds());
  54. return session;
  55. }
  56. private:
  57. bssl::UniquePtr<SSL_CTX> ssl_ctx_;
  58. };
  59. } // namespace
  60. // These tests rely on memory corruption detectors to verify that
  61. // SSL_SESSION reference counts were correctly managed and no sessions
  62. // leaked or were accessed after free.
  63. // Test basic insertion and lookup operations.
  64. TEST_F(SSLClientSessionCacheTest, Basic) {
  65. SSLClientSessionCache::Config config;
  66. SSLClientSessionCache cache(config);
  67. bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
  68. bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
  69. bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();
  70. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  71. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  72. EXPECT_EQ(0u, cache.size());
  73. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  74. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  75. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  76. EXPECT_EQ(1u, cache.size());
  77. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  78. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  79. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  80. EXPECT_EQ(2u, cache.size());
  81. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session3));
  82. EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
  83. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  84. EXPECT_EQ(2u, cache.size());
  85. cache.Flush();
  86. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  87. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  88. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key3")).get());
  89. EXPECT_EQ(0u, cache.size());
  90. }
  91. // Test basic insertion and lookup operations with single-use sessions.
  92. TEST_F(SSLClientSessionCacheTest, BasicSingleUse) {
  93. SSLClientSessionCache::Config config;
  94. SSLClientSessionCache cache(config);
  95. bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession(TLS1_3_VERSION);
  96. bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession(TLS1_3_VERSION);
  97. bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession(TLS1_3_VERSION);
  98. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  99. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  100. EXPECT_EQ(0u, cache.size());
  101. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  102. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  103. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  104. EXPECT_EQ(0u, cache.size());
  105. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  106. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  107. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  108. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  109. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  110. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  111. EXPECT_EQ(1u, cache.size());
  112. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  113. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  114. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  115. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session3));
  116. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  117. EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
  118. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  119. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  120. EXPECT_EQ(0u, cache.size());
  121. cache.Flush();
  122. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  123. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  124. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key3")).get());
  125. EXPECT_EQ(0u, cache.size());
  126. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  127. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session2));
  128. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session3));
  129. EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
  130. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key1")).get());
  131. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  132. }
  133. // Test insertion and lookup operations with both single-use and reusable
  134. // sessions.
  135. TEST_F(SSLClientSessionCacheTest, MixedUse) {
  136. SSLClientSessionCache::Config config;
  137. SSLClientSessionCache cache(config);
  138. bssl::UniquePtr<SSL_SESSION> session_single = NewSSLSession(TLS1_3_VERSION);
  139. bssl::UniquePtr<SSL_SESSION> session_reuse = NewSSLSession(TLS1_2_VERSION);
  140. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  141. EXPECT_EQ(0u, cache.size());
  142. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session_reuse));
  143. EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key1")).get());
  144. EXPECT_EQ(1u, cache.size());
  145. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session_single));
  146. EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key1")).get());
  147. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  148. EXPECT_EQ(0u, cache.size());
  149. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  150. EXPECT_EQ(0u, cache.size());
  151. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_single));
  152. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_single));
  153. EXPECT_EQ(1u, cache.size());
  154. EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key2")).get());
  155. EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key2")).get());
  156. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  157. EXPECT_EQ(0u, cache.size());
  158. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_single));
  159. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_reuse));
  160. EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key2")).get());
  161. EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key2")).get());
  162. EXPECT_EQ(1u, cache.size());
  163. }
  164. // Test that a session may be inserted at two different keys. This should never
  165. // be necessary, but the API doesn't prohibit it.
  166. TEST_F(SSLClientSessionCacheTest, DoubleInsert) {
  167. SSLClientSessionCache::Config config;
  168. SSLClientSessionCache cache(config);
  169. bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
  170. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  171. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  172. EXPECT_EQ(0u, cache.size());
  173. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session));
  174. EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key1")).get());
  175. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  176. EXPECT_EQ(1u, cache.size());
  177. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session));
  178. EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key1")).get());
  179. EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key2")).get());
  180. EXPECT_EQ(2u, cache.size());
  181. cache.Flush();
  182. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  183. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  184. EXPECT_EQ(0u, cache.size());
  185. }
  186. // Tests that the session cache's size is correctly bounded.
  187. TEST_F(SSLClientSessionCacheTest, MaxEntries) {
  188. SSLClientSessionCache::Config config;
  189. config.max_entries = 3;
  190. SSLClientSessionCache cache(config);
  191. bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
  192. bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
  193. bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();
  194. bssl::UniquePtr<SSL_SESSION> session4 = NewSSLSession();
  195. // Insert three entries.
  196. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  197. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  198. cache.Insert(MakeTestKey("key3"), bssl::UpRef(session3));
  199. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  200. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  201. EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
  202. EXPECT_EQ(3u, cache.size());
  203. // On insertion of a fourth, the first is removed.
  204. cache.Insert(MakeTestKey("key4"), bssl::UpRef(session4));
  205. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  206. EXPECT_EQ(session4.get(), cache.Lookup(MakeTestKey("key4")).get());
  207. EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
  208. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  209. EXPECT_EQ(3u, cache.size());
  210. // Despite being newest, the next to be removed is session4 as it was accessed
  211. // least. recently.
  212. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  213. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  214. EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  215. EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
  216. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key4")).get());
  217. EXPECT_EQ(3u, cache.size());
  218. }
  219. // Tests that session expiration works properly.
  220. TEST_F(SSLClientSessionCacheTest, Expiration) {
  221. const size_t kNumEntries = 20;
  222. const size_t kExpirationCheckCount = 10;
  223. const base::TimeDelta kTimeout = base::Seconds(1000);
  224. SSLClientSessionCache::Config config;
  225. config.expiration_check_count = kExpirationCheckCount;
  226. SSLClientSessionCache cache(config);
  227. std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
  228. cache.SetClockForTesting(clock.get());
  229. // Add |kNumEntries - 1| entries.
  230. for (size_t i = 0; i < kNumEntries - 1; i++) {
  231. bssl::UniquePtr<SSL_SESSION> session =
  232. MakeTestSession(clock->Now(), kTimeout);
  233. cache.Insert(MakeTestKey(base::NumberToString(i)), bssl::UpRef(session));
  234. }
  235. EXPECT_EQ(kNumEntries - 1, cache.size());
  236. // Expire all the previous entries and insert one more entry.
  237. clock->Advance(kTimeout * 2);
  238. bssl::UniquePtr<SSL_SESSION> session =
  239. MakeTestSession(clock->Now(), kTimeout);
  240. cache.Insert(MakeTestKey("key"), bssl::UpRef(session));
  241. // All entries are still in the cache.
  242. EXPECT_EQ(kNumEntries, cache.size());
  243. // Perform one fewer lookup than needed to trigger the expiration check. This
  244. // shall not expire any session.
  245. for (size_t i = 0; i < kExpirationCheckCount - 1; i++)
  246. cache.Lookup(MakeTestKey("key"));
  247. // All entries are still in the cache.
  248. EXPECT_EQ(kNumEntries, cache.size());
  249. // Perform one more lookup. This will expire all sessions but the last one.
  250. cache.Lookup(MakeTestKey("key"));
  251. EXPECT_EQ(1u, cache.size());
  252. EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
  253. for (size_t i = 0; i < kNumEntries - 1; i++) {
  254. SCOPED_TRACE(i);
  255. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey(base::NumberToString(i))));
  256. }
  257. }
  258. // Tests that Lookup performs an expiration check before returning a cached
  259. // session.
  260. TEST_F(SSLClientSessionCacheTest, LookupExpirationCheck) {
  261. // kExpirationCheckCount is set to a suitably large number so the automated
  262. // pruning never triggers.
  263. const size_t kExpirationCheckCount = 1000;
  264. const base::TimeDelta kTimeout = base::Seconds(1000);
  265. SSLClientSessionCache::Config config;
  266. config.expiration_check_count = kExpirationCheckCount;
  267. SSLClientSessionCache cache(config);
  268. std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
  269. cache.SetClockForTesting(clock.get());
  270. // Insert an entry into the session cache.
  271. bssl::UniquePtr<SSL_SESSION> session =
  272. MakeTestSession(clock->Now(), kTimeout);
  273. cache.Insert(MakeTestKey("key"), bssl::UpRef(session));
  274. EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
  275. EXPECT_EQ(1u, cache.size());
  276. // Expire the session.
  277. clock->Advance(kTimeout * 2);
  278. // The entry has not been removed yet.
  279. EXPECT_EQ(1u, cache.size());
  280. // But it will not be returned on lookup and gets pruned at that point.
  281. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
  282. EXPECT_EQ(0u, cache.size());
  283. // Re-inserting a session does not refresh the lifetime. The expiration
  284. // information in the session is used.
  285. cache.Insert(MakeTestKey("key"), bssl::UpRef(session));
  286. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
  287. EXPECT_EQ(0u, cache.size());
  288. // Re-insert a fresh copy of the session.
  289. session = MakeTestSession(clock->Now(), kTimeout);
  290. cache.Insert(MakeTestKey("key"), bssl::UpRef(session));
  291. EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
  292. EXPECT_EQ(1u, cache.size());
  293. // Sessions also are treated as expired if the clock rewinds.
  294. clock->Advance(base::Seconds(-2));
  295. EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
  296. EXPECT_EQ(0u, cache.size());
  297. }
  298. // Test that SSL cache is flushed on low memory notifications
  299. TEST_F(SSLClientSessionCacheTest, TestFlushOnMemoryNotifications) {
  300. base::test::TaskEnvironment task_environment;
  301. // kExpirationCheckCount is set to a suitably large number so the automated
  302. // pruning never triggers.
  303. const size_t kExpirationCheckCount = 1000;
  304. const base::TimeDelta kTimeout = base::Seconds(1000);
  305. SSLClientSessionCache::Config config;
  306. config.expiration_check_count = kExpirationCheckCount;
  307. SSLClientSessionCache cache(config);
  308. std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
  309. cache.SetClockForTesting(clock.get());
  310. // Insert an entry into the session cache.
  311. bssl::UniquePtr<SSL_SESSION> session1 =
  312. MakeTestSession(clock->Now(), kTimeout);
  313. cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  314. EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  315. EXPECT_EQ(1u, cache.size());
  316. // Expire the session.
  317. clock->Advance(kTimeout * 2);
  318. // Add one more session.
  319. bssl::UniquePtr<SSL_SESSION> session2 =
  320. MakeTestSession(clock->Now(), kTimeout);
  321. cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  322. EXPECT_EQ(2u, cache.size());
  323. // Fire a notification that will flush expired sessions.
  324. base::MemoryPressureListener::NotifyMemoryPressure(
  325. base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
  326. base::RunLoop().RunUntilIdle();
  327. // Expired session's cache should be flushed.
  328. // Lookup returns nullptr, when cache entry not found.
  329. EXPECT_FALSE(cache.Lookup(MakeTestKey("key1")));
  330. EXPECT_TRUE(cache.Lookup(MakeTestKey("key2")));
  331. EXPECT_EQ(1u, cache.size());
  332. // Fire notification that will flush everything.
  333. base::MemoryPressureListener::NotifyMemoryPressure(
  334. base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
  335. base::RunLoop().RunUntilIdle();
  336. EXPECT_EQ(0u, cache.size());
  337. }
  338. TEST_F(SSLClientSessionCacheTest, FlushForServer) {
  339. SSLClientSessionCache::Config config;
  340. SSLClientSessionCache cache(config);
  341. const SchemefulSite kSiteA(GURL("https://a.test"));
  342. const SchemefulSite kSiteB(GURL("https://b.test"));
  343. // Insert a number of cache entries.
  344. SSLClientSessionCache::Key key1;
  345. key1.server = HostPortPair("a.test", 443);
  346. auto session1 = NewSSLSession();
  347. cache.Insert(key1, bssl::UpRef(session1));
  348. SSLClientSessionCache::Key key2;
  349. key2.server = HostPortPair("a.test", 443);
  350. key2.dest_ip_addr = IPAddress::IPv4Localhost();
  351. key2.network_isolation_key = NetworkIsolationKey(kSiteB, kSiteB);
  352. key2.privacy_mode = PRIVACY_MODE_ENABLED;
  353. auto session2 = NewSSLSession();
  354. cache.Insert(key2, bssl::UpRef(session2));
  355. SSLClientSessionCache::Key key3;
  356. key3.server = HostPortPair("a.test", 444);
  357. auto session3 = NewSSLSession();
  358. cache.Insert(key3, bssl::UpRef(session3));
  359. SSLClientSessionCache::Key key4;
  360. key4.server = HostPortPair("b.test", 443);
  361. auto session4 = NewSSLSession();
  362. cache.Insert(key4, bssl::UpRef(session4));
  363. SSLClientSessionCache::Key key5;
  364. key5.server = HostPortPair("b.test", 443);
  365. key5.network_isolation_key = NetworkIsolationKey(kSiteA, kSiteA);
  366. auto session5 = NewSSLSession();
  367. cache.Insert(key5, bssl::UpRef(session5));
  368. // Flush an unrelated server. The cache should be unaffected.
  369. cache.FlushForServer(HostPortPair("c.test", 443));
  370. EXPECT_EQ(5u, cache.size());
  371. EXPECT_EQ(session1.get(), cache.Lookup(key1).get());
  372. EXPECT_EQ(session2.get(), cache.Lookup(key2).get());
  373. EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
  374. EXPECT_EQ(session4.get(), cache.Lookup(key4).get());
  375. EXPECT_EQ(session5.get(), cache.Lookup(key5).get());
  376. // Flush a.test:443. |key1| and |key2| should match, but not the others.
  377. cache.FlushForServer(HostPortPair("a.test", 443));
  378. EXPECT_EQ(3u, cache.size());
  379. EXPECT_EQ(nullptr, cache.Lookup(key1).get());
  380. EXPECT_EQ(nullptr, cache.Lookup(key2).get());
  381. EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
  382. EXPECT_EQ(session4.get(), cache.Lookup(key4).get());
  383. EXPECT_EQ(session5.get(), cache.Lookup(key5).get());
  384. // Flush b.test:443. |key4| and |key5| match, but not |key3|.
  385. cache.FlushForServer(HostPortPair("b.test", 443));
  386. EXPECT_EQ(1u, cache.size());
  387. EXPECT_EQ(nullptr, cache.Lookup(key1).get());
  388. EXPECT_EQ(nullptr, cache.Lookup(key2).get());
  389. EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
  390. EXPECT_EQ(nullptr, cache.Lookup(key4).get());
  391. EXPECT_EQ(nullptr, cache.Lookup(key5).get());
  392. // Flush the last host, a.test:444.
  393. cache.FlushForServer(HostPortPair("a.test", 444));
  394. EXPECT_EQ(0u, cache.size());
  395. EXPECT_EQ(nullptr, cache.Lookup(key1).get());
  396. EXPECT_EQ(nullptr, cache.Lookup(key2).get());
  397. EXPECT_EQ(nullptr, cache.Lookup(key3).get());
  398. EXPECT_EQ(nullptr, cache.Lookup(key4).get());
  399. EXPECT_EQ(nullptr, cache.Lookup(key5).get());
  400. }
  401. } // namespace net