• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2021 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 
5 #include "quiche/quic/core/crypto/quic_client_session_cache.h"
6 
7 #include "quiche/quic/platform/api/quic_test.h"
8 #include "quiche/quic/test_tools/mock_clock.h"
9 #include "quiche/common/quiche_text_utils.h"
10 
11 namespace quic {
12 namespace test {
13 namespace {
14 
15 const QuicTime::Delta kTimeout = QuicTime::Delta::FromSeconds(1000);
16 const QuicVersionLabel kFakeVersionLabel = 0x01234567;
17 const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
18 const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
19 const uint8_t kFakeStatelessResetTokenData[16] = {
20     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
21     0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
22 const uint64_t kFakeMaxPacketSize = 9001;
23 const uint64_t kFakeInitialMaxData = 101;
24 const bool kFakeDisableMigration = true;
25 const auto kCustomParameter1 =
26     static_cast<TransportParameters::TransportParameterId>(0xffcd);
27 const char* kCustomParameter1Value = "foo";
28 const auto kCustomParameter2 =
29     static_cast<TransportParameters::TransportParameterId>(0xff34);
30 const char* kCustomParameter2Value = "bar";
31 
CreateFakeStatelessResetToken()32 std::vector<uint8_t> CreateFakeStatelessResetToken() {
33   return std::vector<uint8_t>(
34       kFakeStatelessResetTokenData,
35       kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData));
36 }
37 
38 TransportParameters::LegacyVersionInformation
CreateFakeLegacyVersionInformation()39 CreateFakeLegacyVersionInformation() {
40   TransportParameters::LegacyVersionInformation legacy_version_information;
41   legacy_version_information.version = kFakeVersionLabel;
42   legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
43   legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
44   return legacy_version_information;
45 }
46 
CreateFakeVersionInformation()47 TransportParameters::VersionInformation CreateFakeVersionInformation() {
48   TransportParameters::VersionInformation version_information;
49   version_information.chosen_version = kFakeVersionLabel;
50   version_information.other_versions.push_back(kFakeVersionLabel);
51   return version_information;
52 }
53 
54 // Make a TransportParameters that has a few fields set to help test comparison.
MakeFakeTransportParams()55 std::unique_ptr<TransportParameters> MakeFakeTransportParams() {
56   auto params = std::make_unique<TransportParameters>();
57   params->perspective = Perspective::IS_CLIENT;
58   params->legacy_version_information = CreateFakeLegacyVersionInformation();
59   params->version_information = CreateFakeVersionInformation();
60   params->max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
61   params->stateless_reset_token = CreateFakeStatelessResetToken();
62   params->max_udp_payload_size.set_value(kFakeMaxPacketSize);
63   params->initial_max_data.set_value(kFakeInitialMaxData);
64   params->disable_active_migration = kFakeDisableMigration;
65   params->custom_parameters[kCustomParameter1] = kCustomParameter1Value;
66   params->custom_parameters[kCustomParameter2] = kCustomParameter2Value;
67   return params;
68 }
69 
70 // Generated by running TlsClientHandshakerTest.ZeroRttResumption and in
71 // TlsClientHandshaker::InsertSession calling SSL_SESSION_to_bytes to serialize
72 // the received 0-RTT capable ticket.
73 static const char kCachedSession[] =
74     "30820ad7020101020203040402130104206594ce84e61a866b56163c4ba09079aebf1d4f"
75     "6cbcbd38dc9d7066a38a76c9cf0420ec9062063582a4cc0a44f9ff93256a195153ba6032"
76     "0cf3c9189990932d838adaa10602046196f7b9a205020302a300a382039f3082039b3082"
77     "0183a00302010202021001300d06092a864886f70d010105050030623111300f06035504"
78     "030c08426f677573204941310b300906035504080c024d41310b30090603550406130255"
79     "533121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d"
80     "3110300e060355040a0c07426f6775734941301e170d3231303132383136323030315a17"
81     "0d3331303132363136323030315a3069311d301b06035504030c14746573745f6563632e"
82     "6578616d706c652e636f6d310b300906035504080c024d41310b30090603550406130255"
83     "53311e301c06092a864886f70d010901160f626f67757340626f6775732e636f6d310e30"
84     "0c060355040a0c05426f6775733059301306072a8648ce3d020106082a8648ce3d030107"
85     "034200041ba5e2b6f24e64990b9f24ae6d23473d8c77fbcfb7f554f36559529a69a57170"
86     "a10a81b7fe4a36ebf37b0a8c5e467a8443d8b8c002892aa5c1194bd843f42c9aa31f301d"
87     "301b0603551d11041430128210746573742e6578616d706c652e636f6d300d06092a8648"
88     "86f70d0101050500038202010019921d54ac06948763d609215f64f5d6540e3da886c6c9"
89     "61bc737a437719b4621416ef1229f39282d7d3234e1a5d57535473066233bd246eec8e96"
90     "1e0633cf4fe014c800e62599981820ec33d92e74ded0fa2953db1d81e19cb6890b6305b6"
91     "3ede8d3e9fcf3c09f3f57283acf08aa57be4ee9a68d00bb3e2ded5920c619b5d83e5194a"
92     "adb77ae5d61ed3e0a5670f0ae61cc3197329f0e71e3364dcab0405e9e4a6646adef8f022"
93     "6415ec16c8046307b1769029fe780bd576114dde2fa9b4a32aa70bc436549a24ee4907a9"
94     "045f6457ce8dfd8d62cc65315afe798ae1a948eefd70b035d415e73569c48fb20085de1a"
95     "87de039e6b0b9a5fcb4069df27f3a7a1409e72d1ac739c72f29ef786134207e61c79855f"
96     "c22e3ee5f6ad59a7b1ff0f18d79776f1c95efaebbebe381664132a58a1e7ff689945b7e0"
97     "88634b0872feeefbf6be020884b994c6a7ff435f2b3f609077ff97cb509cfa17ff479b34"
98     "e633e4b5bc46b20c5f27c80a2e2943f795a928acd5a3fc43c3af8425ad600c048b41d87e"
99     "6361bc72fc4e5e44680a3d325674ba6ffa760d2fc7d9e4847a8e0dd9d35a543324e18b94"
100     "2d42af6391ed1dd54a39e3f4a4c6b32486eb4ba72815dbd89c56fc053743a0b0483ce676"
101     "15defce6800c629b99d0cbc56da162487f475b7c246099eaf1e6d10a022b2f49c6af1da3"
102     "e8ed66096f267c4a76976b9572db7456ef90278330a4020400aa81b60481b3494e534543"
103     "55524500f3439e548c21d2ad6e5634cc1cc0045730819702010102020304040213010400"
104     "0420ec9062063582a4cc0a44f9ff93256a195153ba60320cf3c9189990932d838adaa106"
105     "02046196f7b9a205020302a300a4020400b20302011db5060404130800cdb807020500ff"
106     "ffffffb9050203093a80ba0404026833bb030101ffbc23042100d27d985bfce04833f02d"
107     "38366b219f4def42bc4ba1b01844d1778db11731487dbd020400be020400b20302011db3"
108     "8205da308205d6308203bea00302010202021000300d06092a864886f70d010105050030"
109     "62310b3009060355040613025553310b300906035504080c024d413110300e060355040a"
110     "0c07426f67757343413111300f06035504030c08426f6775732043413121301f06092a86"
111     "4886f70d0109011612626f67757340626f6775732d63612e636f6d3020170d3231303132"
112     "383136313935385a180f32303730303531313136313935385a30623111300f0603550403"
113     "0c08426f677573204941310b300906035504080c024d41310b3009060355040613025553"
114     "3121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d31"
115     "10300e060355040a0c07426f677573494130820222300d06092a864886f70d0101010500"
116     "0382020f003082020a028202010096c03a0ffc61bcedcd5ec9bf6f848b8a066b43f08377"
117     "3af518a6a0044f22e666e24d2ae741954e344302c4be04612185bd53bcd848eb322bf900"
118     "724eb0848047d647033ffbddb00f01d1de7c1cdb684f83c9bf5fd18ff60afad5a53b0d7d"
119     "2c2a50abc38df019cd7f50194d05bc4597a1ef8570ea04069a2c36d74496af126573ca18"
120     "8e470009b56250fadf2a04e837ee3837b36b1f08b7a0cfe2533d05f26484ce4e30203d01"
121     "517fffd3da63d0341079ddce16e9ab4dbf9d4049e5cc52326031e645dd682fe6220d9e0e"
122     "95451f5a82f3e1720dc13e8499466426a0bdbea9f6a76b3c9228dd3c79ab4dcc4c145ef0"
123     "e78d1ee8bfd4650692d7e28a54bed809d8f7b37fe24c586be59cc46638531cb291c8c156"
124     "8f08d67e768e51563e95a639c1f138b275ffad6a6a2a042ba9e26ad63c2ce63b600013f0"
125     "a6f0703ee51c4f457f7bab0391c2fc4c5bb3213742c9cf9941bff68cc2e1cc96139d35ed"
126     "1885244ddde0bf658416c486701841b81f7b17503d08c59a4db08a2a80755e007aa3b6c7"
127     "eadcaa9e07c8325f3689f100de23970b12c9d9f6d0a8fb35ba0fd75c64410318db4a13ac"
128     "3972ad16cdf6408af37013c7bcd7c42f20d6d04c3e39436c7531e8dafa219dd04b784ef0"
129     "3c70ee5a4782b33cafa925aa3deca62a14aed704f179b932efabc2b0c5c15a8a99bfc9e6"
130     "189dce7da50ea303594b6af9c933dd54b6e9d17c472d0203010001a38193308190300f06"
131     "03551d130101ff040530030101ff301d0603551d0e041604141a98e80029a80992b7e5e0"
132     "068ab9b3486cd839d6301f0603551d23041830168014780beeefe2fa419c48a438bdb30b"
133     "e37ef0b7a94e300b0603551d0f0404030202a430130603551d25040c300a06082b060105"
134     "05070301301b0603551d11041430128207426f67757343418207426f6775734941300d06"
135     "092a864886f70d010105050003820201009e822ed8064b1aabaddf1340010ea147f68c06"
136     "5a5a599ea305349f1b0e545a00817d6e55c7bf85560fab429ca72186c4d520b52f5cc121"
137     "abd068b06f3111494431d2522efa54642f907059e7db80b73bb5ecf621377195b8700bba"
138     "df798cece8c67a9571548d0e6592e81ae5d934877cb170aef18d3b97f635600fe0890d98"
139     "f88b33fe3d1fd34c1c915beae4e5c0b133f476c40b21d220f16ce9cdd9e8f97a36a31723"
140     "68875f052c9271648d9cb54687c6fdc3ea96f2908003bc5e5e79de00a21da7b8429f8b08"
141     "af4c4d34641e386d72eabf5f01f106363f2ffd18969bf0bb9a4d17627c6427ff772c4308"
142     "83c276feef5fc6dba9582c22fdbe9df7e8dfca375695f028ed588df54f3c86462dbf4c07"
143     "91d80ca738988a1419c86bb4dd8d738b746921f01f39422e5ffd488b6f00195b996e6392"
144     "3a820a32cd78b5989f339c0fcf4f269103964a30a16347d0ffdc8df1f3653ddc1515fa09"
145     "22c7aef1af1fbcb23e93ae7622ab1ee11fcfa98319bad4c37c091cad46bd0337b3cc78b5"
146     "5b9f1ea7994acc1f89c49a0b4cb540d2137e266fd43e56a9b5b778217b6f77df530e1eaf"
147     "b3417262b5ddb86d3c6c5ac51e3f326c650dcc2434473973b7182c66220d1f3871bde7ee"
148     "47d3f359d3d4c5bdd61baa684c03db4c75f9d6690c9e6e3abe6eaf5fa2c33c4daf26b373"
149     "d85a1e8a7d671ac4a0a97b14e36e81280de4593bbb12da7695b5060404130800cdb60301"
150     "0100b70402020403b807020500ffffffffb9050203093a80ba0404026833bb030101ffbd"
151     "020400be020400";
152 
153 class QuicClientSessionCacheTest : public QuicTest {
154  public:
QuicClientSessionCacheTest()155   QuicClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {
156     clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
157   }
158 
159  protected:
NewSSLSession()160   bssl::UniquePtr<SSL_SESSION> NewSSLSession() {
161     std::string cached_session =
162         absl::HexStringToBytes(absl::string_view(kCachedSession));
163     SSL_SESSION* session = SSL_SESSION_from_bytes(
164         reinterpret_cast<const uint8_t*>(cached_session.data()),
165         cached_session.size(), ssl_ctx_.get());
166     QUICHE_DCHECK(session);
167     return bssl::UniquePtr<SSL_SESSION>(session);
168   }
169 
MakeTestSession(QuicTime::Delta timeout=kTimeout)170   bssl::UniquePtr<SSL_SESSION> MakeTestSession(
171       QuicTime::Delta timeout = kTimeout) {
172     bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
173     SSL_SESSION_set_time(session.get(), clock_.WallNow().ToUNIXSeconds());
174     SSL_SESSION_set_timeout(session.get(), timeout.ToSeconds());
175     return session;
176   }
177 
178   bssl::UniquePtr<SSL_CTX> ssl_ctx_;
179   MockClock clock_;
180 };
181 
182 // Tests that simple insertion and lookup work correctly.
TEST_F(QuicClientSessionCacheTest,SingleSession)183 TEST_F(QuicClientSessionCacheTest, SingleSession) {
184   QuicClientSessionCache cache;
185 
186   auto params = MakeFakeTransportParams();
187   auto session = MakeTestSession();
188   QuicServerId id1("a.com", 443);
189 
190   auto params2 = MakeFakeTransportParams();
191   auto session2 = MakeTestSession();
192   SSL_SESSION* unowned2 = session2.get();
193   QuicServerId id2("b.com", 443);
194 
195   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
196   EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
197   EXPECT_EQ(0u, cache.size());
198 
199   cache.Insert(id1, std::move(session), *params, nullptr);
200   EXPECT_EQ(1u, cache.size());
201   EXPECT_EQ(
202       *params,
203       *(cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->transport_params));
204   EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
205   // No session is available for id1, even though the entry exists.
206   EXPECT_EQ(1u, cache.size());
207   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
208   // Lookup() will trigger a deletion of invalid entry.
209   EXPECT_EQ(0u, cache.size());
210 
211   auto session3 = MakeTestSession();
212   SSL_SESSION* unowned3 = session3.get();
213   QuicServerId id3("c.com", 443);
214   cache.Insert(id3, std::move(session3), *params, nullptr);
215   cache.Insert(id2, std::move(session2), *params2, nullptr);
216   EXPECT_EQ(2u, cache.size());
217   EXPECT_EQ(
218       unowned2,
219       cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
220   EXPECT_EQ(
221       unowned3,
222       cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
223 
224   // Verify that the cache is cleared after Lookups.
225   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
226   EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
227   EXPECT_EQ(nullptr, cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get()));
228   EXPECT_EQ(0u, cache.size());
229 }
230 
TEST_F(QuicClientSessionCacheTest,MultipleSessions)231 TEST_F(QuicClientSessionCacheTest, MultipleSessions) {
232   QuicClientSessionCache cache;
233 
234   auto params = MakeFakeTransportParams();
235   auto session = MakeTestSession();
236   QuicServerId id1("a.com", 443);
237   auto session2 = MakeTestSession();
238   SSL_SESSION* unowned2 = session2.get();
239   auto session3 = MakeTestSession();
240   SSL_SESSION* unowned3 = session3.get();
241 
242   cache.Insert(id1, std::move(session), *params, nullptr);
243   cache.Insert(id1, std::move(session2), *params, nullptr);
244   cache.Insert(id1, std::move(session3), *params, nullptr);
245   // The latest session is popped first.
246   EXPECT_EQ(
247       unowned3,
248       cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
249   EXPECT_EQ(
250       unowned2,
251       cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
252   // Only two sessions are cached.
253   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
254 }
255 
256 // Test that when a different TransportParameter is inserted for
257 // the same server id, the existing entry is removed.
TEST_F(QuicClientSessionCacheTest,DifferentTransportParams)258 TEST_F(QuicClientSessionCacheTest, DifferentTransportParams) {
259   QuicClientSessionCache cache;
260 
261   auto params = MakeFakeTransportParams();
262   auto session = MakeTestSession();
263   QuicServerId id1("a.com", 443);
264   auto session2 = MakeTestSession();
265   auto session3 = MakeTestSession();
266   SSL_SESSION* unowned3 = session3.get();
267 
268   cache.Insert(id1, std::move(session), *params, nullptr);
269   cache.Insert(id1, std::move(session2), *params, nullptr);
270   // tweak the transport parameters a little bit.
271   params->perspective = Perspective::IS_SERVER;
272   cache.Insert(id1, std::move(session3), *params, nullptr);
273   auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
274   EXPECT_EQ(unowned3, resumption_state->tls_session.get());
275   EXPECT_EQ(*params.get(), *resumption_state->transport_params);
276   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
277 }
278 
TEST_F(QuicClientSessionCacheTest,DifferentApplicationState)279 TEST_F(QuicClientSessionCacheTest, DifferentApplicationState) {
280   QuicClientSessionCache cache;
281 
282   auto params = MakeFakeTransportParams();
283   auto session = MakeTestSession();
284   QuicServerId id1("a.com", 443);
285   auto session2 = MakeTestSession();
286   auto session3 = MakeTestSession();
287   SSL_SESSION* unowned3 = session3.get();
288   ApplicationState state;
289   state.push_back('a');
290 
291   cache.Insert(id1, std::move(session), *params, &state);
292   cache.Insert(id1, std::move(session2), *params, &state);
293   cache.Insert(id1, std::move(session3), *params, nullptr);
294   auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
295   EXPECT_EQ(unowned3, resumption_state->tls_session.get());
296   EXPECT_EQ(nullptr, resumption_state->application_state);
297   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
298 }
299 
TEST_F(QuicClientSessionCacheTest,BothStatesDifferent)300 TEST_F(QuicClientSessionCacheTest, BothStatesDifferent) {
301   QuicClientSessionCache cache;
302 
303   auto params = MakeFakeTransportParams();
304   auto session = MakeTestSession();
305   QuicServerId id1("a.com", 443);
306   auto session2 = MakeTestSession();
307   auto session3 = MakeTestSession();
308   SSL_SESSION* unowned3 = session3.get();
309   ApplicationState state;
310   state.push_back('a');
311 
312   cache.Insert(id1, std::move(session), *params, &state);
313   cache.Insert(id1, std::move(session2), *params, &state);
314   params->perspective = Perspective::IS_SERVER;
315   cache.Insert(id1, std::move(session3), *params, nullptr);
316   auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
317   EXPECT_EQ(unowned3, resumption_state->tls_session.get());
318   EXPECT_EQ(*params.get(), *resumption_state->transport_params);
319   EXPECT_EQ(nullptr, resumption_state->application_state);
320   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
321 }
322 
323 // When the size limit is exceeded, the oldest entry should be erased.
TEST_F(QuicClientSessionCacheTest,SizeLimit)324 TEST_F(QuicClientSessionCacheTest, SizeLimit) {
325   QuicClientSessionCache cache(2);
326 
327   auto params = MakeFakeTransportParams();
328   auto session = MakeTestSession();
329   QuicServerId id1("a.com", 443);
330 
331   auto session2 = MakeTestSession();
332   SSL_SESSION* unowned2 = session2.get();
333   QuicServerId id2("b.com", 443);
334 
335   auto session3 = MakeTestSession();
336   SSL_SESSION* unowned3 = session3.get();
337   QuicServerId id3("c.com", 443);
338 
339   cache.Insert(id1, std::move(session), *params, nullptr);
340   cache.Insert(id2, std::move(session2), *params, nullptr);
341   cache.Insert(id3, std::move(session3), *params, nullptr);
342 
343   EXPECT_EQ(2u, cache.size());
344   EXPECT_EQ(
345       unowned2,
346       cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
347   EXPECT_EQ(
348       unowned3,
349       cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
350   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
351 }
352 
TEST_F(QuicClientSessionCacheTest,ClearEarlyData)353 TEST_F(QuicClientSessionCacheTest, ClearEarlyData) {
354   QuicClientSessionCache cache;
355   SSL_CTX_set_early_data_enabled(ssl_ctx_.get(), 1);
356   auto params = MakeFakeTransportParams();
357   auto session = MakeTestSession();
358   QuicServerId id1("a.com", 443);
359   auto session2 = MakeTestSession();
360 
361   EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
362   EXPECT_TRUE(SSL_SESSION_early_data_capable(session2.get()));
363 
364   cache.Insert(id1, std::move(session), *params, nullptr);
365   cache.Insert(id1, std::move(session2), *params, nullptr);
366 
367   cache.ClearEarlyData(id1);
368 
369   auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
370   EXPECT_FALSE(
371       SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
372   resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
373   EXPECT_FALSE(
374       SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
375   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
376 }
377 
378 // Expired session isn't considered valid and nullptr will be returned upon
379 // Lookup.
TEST_F(QuicClientSessionCacheTest,Expiration)380 TEST_F(QuicClientSessionCacheTest, Expiration) {
381   QuicClientSessionCache cache;
382 
383   auto params = MakeFakeTransportParams();
384   auto session = MakeTestSession();
385   QuicServerId id1("a.com", 443);
386 
387   auto session2 = MakeTestSession(3 * kTimeout);
388   SSL_SESSION* unowned2 = session2.get();
389   QuicServerId id2("b.com", 443);
390 
391   cache.Insert(id1, std::move(session), *params, nullptr);
392   cache.Insert(id2, std::move(session2), *params, nullptr);
393 
394   EXPECT_EQ(2u, cache.size());
395   // Expire the session.
396   clock_.AdvanceTime(kTimeout * 2);
397   // The entry has not been removed yet.
398   EXPECT_EQ(2u, cache.size());
399 
400   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
401   EXPECT_EQ(1u, cache.size());
402   EXPECT_EQ(
403       unowned2,
404       cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
405   EXPECT_EQ(1u, cache.size());
406 }
407 
TEST_F(QuicClientSessionCacheTest,RemoveExpiredEntriesAndClear)408 TEST_F(QuicClientSessionCacheTest, RemoveExpiredEntriesAndClear) {
409   QuicClientSessionCache cache;
410 
411   auto params = MakeFakeTransportParams();
412   auto session = MakeTestSession();
413   quic::QuicServerId id1("a.com", 443);
414 
415   auto session2 = MakeTestSession(3 * kTimeout);
416   quic::QuicServerId id2("b.com", 443);
417 
418   cache.Insert(id1, std::move(session), *params, nullptr);
419   cache.Insert(id2, std::move(session2), *params, nullptr);
420 
421   EXPECT_EQ(2u, cache.size());
422   // Expire the session.
423   clock_.AdvanceTime(kTimeout * 2);
424   // The entry has not been removed yet.
425   EXPECT_EQ(2u, cache.size());
426 
427   // Flush expired sessions.
428   cache.RemoveExpiredEntries(clock_.WallNow());
429 
430   // session is expired and should be flushed.
431   EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
432   EXPECT_EQ(1u, cache.size());
433 
434   cache.Clear();
435   EXPECT_EQ(0u, cache.size());
436 }
437 
438 }  // namespace
439 }  // namespace test
440 }  // namespace quic
441