1 // Copyright 2015 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_SSL_SSL_CLIENT_SESSION_CACHE_H_ 6 #define NET_SSL_SSL_CLIENT_SESSION_CACHE_H_ 7 8 #include <stddef.h> 9 #include <time.h> 10 11 #include <memory> 12 #include <optional> 13 #include <string> 14 15 #include "base/containers/flat_set.h" 16 #include "base/containers/lru_cache.h" 17 #include "base/functional/bind.h" 18 #include "base/memory/memory_pressure_monitor.h" 19 #include "base/memory/raw_ptr.h" 20 #include "net/base/host_port_pair.h" 21 #include "net/base/ip_address.h" 22 #include "net/base/net_export.h" 23 #include "net/base/network_anonymization_key.h" 24 #include "net/base/privacy_mode.h" 25 #include "third_party/boringssl/src/include/openssl/base.h" 26 27 namespace base { 28 class Clock; 29 } 30 31 namespace net { 32 33 class NET_EXPORT SSLClientSessionCache { 34 public: 35 struct Config { 36 // The maximum number of entries in the cache. 37 size_t max_entries = 1024; 38 // The number of calls to Lookup before a new check for expired sessions. 39 size_t expiration_check_count = 256; 40 }; 41 42 struct NET_EXPORT Key { 43 Key(); 44 Key(const Key& other); 45 Key(Key&& other); 46 ~Key(); 47 Key& operator=(const Key& other); 48 Key& operator=(Key&& other); 49 50 bool operator==(const Key& other) const; 51 bool operator<(const Key& other) const; 52 53 HostPortPair server; 54 std::optional<IPAddress> dest_ip_addr; 55 NetworkAnonymizationKey network_anonymization_key; 56 PrivacyMode privacy_mode = PRIVACY_MODE_DISABLED; 57 }; 58 59 explicit SSLClientSessionCache(const Config& config); 60 61 SSLClientSessionCache(const SSLClientSessionCache&) = delete; 62 SSLClientSessionCache& operator=(const SSLClientSessionCache&) = delete; 63 64 ~SSLClientSessionCache(); 65 66 // Returns true if |entry| is expired as of |now|. 67 static bool IsExpired(SSL_SESSION* session, time_t now); 68 69 size_t size() const; 70 71 // Returns the session associated with |cache_key| and moves it to the front 72 // of the MRU list. Returns nullptr if there is none. 73 bssl::UniquePtr<SSL_SESSION> Lookup(const Key& cache_key); 74 75 // Inserts |session| into the cache at |cache_key|. If there is an existing 76 // one, it is released. Every |expiration_check_count| calls, the cache is 77 // checked for stale entries. 78 void Insert(const Key& cache_key, bssl::UniquePtr<SSL_SESSION> session); 79 80 // Clears early data support for all current sessions associated with 81 // |cache_key|. This may be used after a 0-RTT reject to avoid unnecessarily 82 // offering 0-RTT data on retries. See https://crbug.com/1066623. 83 void ClearEarlyData(const Key& cache_key); 84 85 // Removes all entries associated with items in |servers|. 86 void FlushForServers(const base::flat_set<HostPortPair>& servers); 87 88 // Removes all entries from the cache. 89 void Flush(); 90 91 void SetClockForTesting(base::Clock* clock); 92 93 private: 94 struct Entry { 95 Entry(); 96 Entry(Entry&&); 97 ~Entry(); 98 99 // Adds a new session onto this entry, dropping the oldest one if two are 100 // already stored. 101 void Push(bssl::UniquePtr<SSL_SESSION> session); 102 103 // Retrieves the latest session from the entry, removing it if its 104 // single-use. 105 bssl::UniquePtr<SSL_SESSION> Pop(); 106 107 // Removes any expired sessions, returning true if this entry can be 108 // deleted. 109 bool ExpireSessions(time_t now); 110 111 bssl::UniquePtr<SSL_SESSION> sessions[2]; 112 }; 113 114 // Removes all expired sessions from the cache. 115 void FlushExpiredSessions(); 116 117 // Clear cache on low memory notifications callback. 118 void OnMemoryPressure( 119 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); 120 121 raw_ptr<base::Clock> clock_; 122 Config config_; 123 base::LRUCache<Key, Entry> cache_; 124 size_t lookups_since_flush_ = 0; 125 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; 126 }; 127 128 } // namespace net 129 130 #endif // NET_SSL_SSL_CLIENT_SESSION_CACHE_H_ 131