| Index: net/socket/ssl_session_cache_openssl.cc
|
| diff --git a/net/socket/ssl_session_cache_openssl.cc b/net/socket/ssl_session_cache_openssl.cc
|
| index d16bb8d6325ec6b105da7219d4e9ea9e5f6f4828..3cea697cfa6cc06fae3dfac385c62637f4f39a52 100644
|
| --- a/net/socket/ssl_session_cache_openssl.cc
|
| +++ b/net/socket/ssl_session_cache_openssl.cc
|
| @@ -236,6 +236,38 @@ class SSLSessionCacheOpenSSLImpl {
|
| return SSL_set_session(ssl, session) == 1;
|
| }
|
|
|
| + bool SSLSessionIsInCache(const std::string& cache_key) const {
|
| + base::AutoLock locked(lock_);
|
| + KeyIndex::const_iterator it = key_index_.find(cache_key);
|
| + if (it == key_index_.end())
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + void RegisterSessionAddedCallback(SSL* ssl, const base::Closure& callback) {
|
| + // Add this SSL* to the SSLtoCallbackMap.
|
| + ssl_to_callback_map_.insert(SSLToCallbackMap::value_type(
|
| + ssl, CallbackAndCompletionCount(callback, 0)));
|
| + }
|
| +
|
| + // Determines if the session for |ssl| is in the cache, and calls the
|
| + // appropriate callback if that is the case.
|
| + void CheckIfSessionAdded(SSL* ssl) {
|
| + SSLToCallbackMap::iterator it = ssl_to_callback_map_.find(ssl);
|
| + if (it == ssl_to_callback_map_.end())
|
| + return;
|
| + // Increment the session's completion count.
|
| + it->second.count++;
|
| + if (it->second.count == 2) {
|
| + // The session has been MarkedAsGood and Added, so it can be used.
|
| + // These two events can occur in either order.
|
| + it->second.callback.Run();
|
| + RemoveFromSSLToCallbackMap(ssl);
|
| + }
|
| + }
|
| +
|
| + void RemoveFromSSLToCallbackMap(SSL* ssl) { ssl_to_callback_map_.erase(ssl); }
|
| +
|
| void MarkSSLSessionAsGood(SSL* ssl) {
|
| SSL_SESSION* session = SSL_get_session(ssl);
|
| if (!session)
|
| @@ -244,6 +276,8 @@ class SSLSessionCacheOpenSSLImpl {
|
| // Mark the session as good, allowing it to be used for future connections.
|
| SSL_SESSION_set_ex_data(
|
| session, GetSSLSessionExIndex(), reinterpret_cast<void*>(1));
|
| +
|
| + CheckIfSessionAdded(ssl);
|
| }
|
|
|
| // Flush all entries from the cache.
|
| @@ -259,12 +293,23 @@ class SSLSessionCacheOpenSSLImpl {
|
| }
|
|
|
| private:
|
| + struct CallbackAndCompletionCount {
|
| + base::Closure callback;
|
| + int count;
|
| +
|
| + CallbackAndCompletionCount(base::Closure completion_callback,
|
| + int completion_count)
|
| + : callback(completion_callback), count(completion_count) {}
|
| + };
|
| +
|
| // Type for list of SSL_SESSION handles, ordered in MRU order.
|
| typedef std::list<SSL_SESSION*> MRUSessionList;
|
| // Type for a dictionary from unique cache keys to session list nodes.
|
| typedef base::hash_map<std::string, MRUSessionList::iterator> KeyIndex;
|
| // Type for a dictionary from SessionId values to key index nodes.
|
| typedef base::hash_map<SessionId, KeyIndex::iterator> SessionIdIndex;
|
| + // Type for a map from SSL* to associated callbacks
|
| + typedef std::map<SSL*, CallbackAndCompletionCount> SSLToCallbackMap;
|
|
|
| // Return the key associated with a given session, or the empty string if
|
| // none exist. This shall only be used for debugging.
|
| @@ -343,6 +388,7 @@ class SSLSessionCacheOpenSSLImpl {
|
| // should not decrement its reference count after completion.
|
| static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) {
|
| GetCache(ssl->ctx)->OnSessionAdded(ssl, session);
|
| + GetCache(ssl->ctx)->CheckIfSessionAdded(ssl);
|
| return 1;
|
| }
|
|
|
| @@ -466,10 +512,11 @@ class SSLSessionCacheOpenSSLImpl {
|
|
|
| SSL_CTX* ctx_;
|
| SSLSessionCacheOpenSSL::Config config_;
|
| + SSLToCallbackMap ssl_to_callback_map_;
|
|
|
| // method to get the index which can later be used with SSL_CTX_get_ex_data()
|
| // or SSL_CTX_set_ex_data().
|
| - base::Lock lock_; // Protects access to containers below.
|
| + mutable base::Lock lock_; // Protects access to containers below.
|
|
|
| MRUSessionList ordering_;
|
| KeyIndex key_index_;
|
| @@ -499,6 +546,21 @@ bool SSLSessionCacheOpenSSL::SetSSLSessionWithKey(
|
| return impl_->SetSSLSessionWithKey(ssl, cache_key);
|
| }
|
|
|
| +bool SSLSessionCacheOpenSSL::SSLSessionIsInCache(
|
| + const std::string& cache_key) const {
|
| + return impl_->SSLSessionIsInCache(cache_key);
|
| +}
|
| +
|
| +void SSLSessionCacheOpenSSL::RemoveFromSSLToCallbackMap(SSL* ssl) {
|
| + impl_->RemoveFromSSLToCallbackMap(ssl);
|
| +}
|
| +
|
| +void SSLSessionCacheOpenSSL::RegisterSessionAddedCallback(
|
| + SSL* ssl,
|
| + const base::Closure& cb) {
|
| + impl_->RegisterSessionAddedCallback(ssl, cb);
|
| +}
|
| +
|
| void SSLSessionCacheOpenSSL::MarkSSLSessionAsGood(SSL* ssl) {
|
| return impl_->MarkSSLSessionAsGood(ssl);
|
| }
|
|
|