Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Side by Side Diff: net/socket/ssl_session_cache_openssl.cc

Issue 416683002: This CL corrects a bug in which the OnHandshakeComplete callback for an ssl session was never called (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@r2
Patch Set: Fixed typos & updated flag description Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/ssl_session_cache_openssl.h" 5 #include "net/socket/ssl_session_cache_openssl.h"
6 6
7 #include <list> 7 #include <list>
8 #include <map> 8 #include <map>
9 9
10 #include <openssl/rand.h> 10 #include <openssl/rand.h>
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 return false; // Session has not yet been marked good. Treat as a miss. 230 return false; // Session has not yet been marked good. Treat as a miss.
231 231
232 // Move to front of MRU list. 232 // Move to front of MRU list.
233 ordering_.push_front(session); 233 ordering_.push_front(session);
234 ordering_.erase(it->second); 234 ordering_.erase(it->second);
235 it->second = ordering_.begin(); 235 it->second = ordering_.begin();
236 236
237 return SSL_set_session(ssl, session) == 1; 237 return SSL_set_session(ssl, session) == 1;
238 } 238 }
239 239
240 // Return true iff a cached session was associated with the given |cache_key|.
wtc 2014/08/07 02:10:13 Did you remove this comment by mistake (a merge/re
241 bool SSLSessionIsInCache(const std::string& cache_key) const { 240 bool SSLSessionIsInCache(const std::string& cache_key) const {
242 base::AutoLock locked(lock_); 241 base::AutoLock locked(lock_);
243 KeyIndex::const_iterator it = key_index_.find(cache_key); 242 KeyIndex::const_iterator it = key_index_.find(cache_key);
244 if (it == key_index_.end()) 243 if (it == key_index_.end())
245 return false; 244 return false;
246 245
247 SSL_SESSION* session = *it->second; 246 SSL_SESSION* session = *it->second;
248 DCHECK(session); 247 DCHECK(session);
249 248
250 void* session_is_good = 249 void* session_is_good =
251 SSL_SESSION_get_ex_data(session, GetSSLSessionExIndex()); 250 SSL_SESSION_get_ex_data(session, GetSSLSessionExIndex());
252 251
253 return session_is_good; 252 return session_is_good;
254 } 253 }
255 254
256 void SetSessionAddedCallback(SSL* ssl, const base::Closure& callback) {
257 // Add |ssl| to the SSLToCallbackMap.
258 ssl_to_callback_map_.insert(SSLToCallbackMap::value_type(
259 ssl, CallbackAndCompletionCount(callback, 0)));
260 }
261
262 // Determines if the session for |ssl| is in the cache, and calls the
263 // appropriate callback if that is the case.
264 //
265 // The session must be both MarkedAsGood and Added in order for the
266 // callback to be run. These two events can occur in either order.
267 void CheckIfSessionFinished(SSL* ssl) {
268 SSLToCallbackMap::iterator it = ssl_to_callback_map_.find(ssl);
269 if (it == ssl_to_callback_map_.end())
270 return;
271 // Increment the session's completion count.
272 if (++it->second.count == 2) {
273 base::Closure callback = it->second.callback;
274 ssl_to_callback_map_.erase(it);
275 callback.Run();
276 }
277 }
278
279 void RemoveSessionAddedCallback(SSL* ssl) { ssl_to_callback_map_.erase(ssl); }
280
281 void MarkSSLSessionAsGood(SSL* ssl) { 255 void MarkSSLSessionAsGood(SSL* ssl) {
282 SSL_SESSION* session = SSL_get_session(ssl); 256 SSL_SESSION* session = SSL_get_session(ssl);
283 CHECK(session); 257 CHECK(session);
284 258
285 // Mark the session as good, allowing it to be used for future connections. 259 // Mark the session as good, allowing it to be used for future connections.
286 SSL_SESSION_set_ex_data( 260 SSL_SESSION_set_ex_data(
287 session, GetSSLSessionExIndex(), reinterpret_cast<void*>(1)); 261 session, GetSSLSessionExIndex(), reinterpret_cast<void*>(1));
262 }
288 263
289 CheckIfSessionFinished(ssl); 264 bool SessionIsGood(SSL* ssl) {
265 SSL_SESSION* session = SSL_get_session(ssl);
266 CHECK(session);
267 return SSL_SESSION_get_ex_data(session, GetSSLSessionExIndex());
290 } 268 }
291 269
292 // Flush all entries from the cache. 270 // Flush all entries from the cache.
293 void Flush() { 271 void Flush() {
294 base::AutoLock lock(lock_); 272 base::AutoLock lock(lock_);
295 id_index_.clear(); 273 id_index_.clear();
296 key_index_.clear(); 274 key_index_.clear();
297 while (!ordering_.empty()) { 275 while (!ordering_.empty()) {
298 SSL_SESSION* session = ordering_.front(); 276 SSL_SESSION* session = ordering_.front();
299 ordering_.pop_front(); 277 ordering_.pop_front();
300 SSL_SESSION_free(session); 278 SSL_SESSION_free(session);
301 } 279 }
302 } 280 }
303 281
304 private: 282 private:
305 // CallbackAndCompletionCounts are used to group a callback that should be
306 // run when a certain sesssion is added to the session cache with an integer
307 // indicating the status of that session.
308 struct CallbackAndCompletionCount {
309 CallbackAndCompletionCount(const base::Closure& completion_callback,
310 int completion_count)
311 : callback(completion_callback), count(completion_count) {}
312
313 const base::Closure callback;
314 // |count| < 2 means that the ssl session associated with this object
315 // has not been added to the session cache or has not been marked as good.
316 // |count| is incremented when a session is added to the cache or marked as
317 // good, thus |count| == 2 means that the session is ready for use.
318 int count;
319 };
320
321 // Type for list of SSL_SESSION handles, ordered in MRU order. 283 // Type for list of SSL_SESSION handles, ordered in MRU order.
322 typedef std::list<SSL_SESSION*> MRUSessionList; 284 typedef std::list<SSL_SESSION*> MRUSessionList;
323 // Type for a dictionary from unique cache keys to session list nodes. 285 // Type for a dictionary from unique cache keys to session list nodes.
324 typedef base::hash_map<std::string, MRUSessionList::iterator> KeyIndex; 286 typedef base::hash_map<std::string, MRUSessionList::iterator> KeyIndex;
325 // Type for a dictionary from SessionId values to key index nodes. 287 // Type for a dictionary from SessionId values to key index nodes.
326 typedef base::hash_map<SessionId, KeyIndex::iterator> SessionIdIndex; 288 typedef base::hash_map<SessionId, KeyIndex::iterator> SessionIdIndex;
327 // Type for a map from SSL* to associated callbacks
328 typedef std::map<SSL*, CallbackAndCompletionCount> SSLToCallbackMap;
329 289
330 // Return the key associated with a given session, or the empty string if 290 // Return the key associated with a given session, or the empty string if
331 // none exist. This shall only be used for debugging. 291 // none exist. This shall only be used for debugging.
332 std::string SessionKey(SSL_SESSION* session) { 292 std::string SessionKey(SSL_SESSION* session) {
333 if (!session) 293 if (!session)
334 return std::string("<null-session>"); 294 return std::string("<null-session>");
335 295
336 if (session->session_id_length == 0) 296 if (session->session_id_length == 0)
337 return std::string("<empty-session-id>"); 297 return std::string("<empty-session-id>");
338 298
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 358 }
399 359
400 // Called by OpenSSL when a new |session| was created and added to a given 360 // Called by OpenSSL when a new |session| was created and added to a given
401 // |ssl| connection. Note that the session's reference count was already 361 // |ssl| connection. Note that the session's reference count was already
402 // incremented before the function is entered. The function must return 1 362 // incremented before the function is entered. The function must return 1
403 // to indicate that it took ownership of the session, i.e. that the caller 363 // to indicate that it took ownership of the session, i.e. that the caller
404 // should not decrement its reference count after completion. 364 // should not decrement its reference count after completion.
405 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) { 365 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) {
406 SSLSessionCacheOpenSSLImpl* cache = GetCache(ssl->ctx); 366 SSLSessionCacheOpenSSLImpl* cache = GetCache(ssl->ctx);
407 cache->OnSessionAdded(ssl, session); 367 cache->OnSessionAdded(ssl, session);
408 cache->CheckIfSessionFinished(ssl);
409 return 1; 368 return 1;
410 } 369 }
411 370
412 // Called by OpenSSL to indicate that a session must be removed from the 371 // Called by OpenSSL to indicate that a session must be removed from the
413 // cache. This happens when SSL_CTX is destroyed. 372 // cache. This happens when SSL_CTX is destroyed.
414 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) { 373 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) {
415 GetCache(ctx)->OnSessionRemoved(session); 374 GetCache(ctx)->OnSessionRemoved(session);
416 } 375 }
417 376
418 // Called by OpenSSL to generate a new session ID. This happens during a 377 // Called by OpenSSL to generate a new session ID. This happens during a
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 if (id_index_.find(SessionId(id, id_len)) == id_index_.end()) 481 if (id_index_.find(SessionId(id, id_len)) == id_index_.end())
523 return true; 482 return true;
524 } 483 }
525 DLOG(ERROR) << "Couldn't generate unique session ID of " << id_len 484 DLOG(ERROR) << "Couldn't generate unique session ID of " << id_len
526 << "bytes after " << kMaxTries << " tries."; 485 << "bytes after " << kMaxTries << " tries.";
527 return false; 486 return false;
528 } 487 }
529 488
530 SSL_CTX* ctx_; 489 SSL_CTX* ctx_;
531 SSLSessionCacheOpenSSL::Config config_; 490 SSLSessionCacheOpenSSL::Config config_;
532 SSLToCallbackMap ssl_to_callback_map_;
533 491
534 // method to get the index which can later be used with SSL_CTX_get_ex_data() 492 // method to get the index which can later be used with SSL_CTX_get_ex_data()
535 // or SSL_CTX_set_ex_data(). 493 // or SSL_CTX_set_ex_data().
536 mutable base::Lock lock_; // Protects access to containers below. 494 mutable base::Lock lock_; // Protects access to containers below.
537 495
538 MRUSessionList ordering_; 496 MRUSessionList ordering_;
539 KeyIndex key_index_; 497 KeyIndex key_index_;
540 SessionIdIndex id_index_; 498 SessionIdIndex id_index_;
541 499
542 size_t expiration_check_; 500 size_t expiration_check_;
(...skipping 18 matching lines...) Expand all
561 SSL* ssl, 519 SSL* ssl,
562 const std::string& cache_key) { 520 const std::string& cache_key) {
563 return impl_->SetSSLSessionWithKey(ssl, cache_key); 521 return impl_->SetSSLSessionWithKey(ssl, cache_key);
564 } 522 }
565 523
566 bool SSLSessionCacheOpenSSL::SSLSessionIsInCache( 524 bool SSLSessionCacheOpenSSL::SSLSessionIsInCache(
567 const std::string& cache_key) const { 525 const std::string& cache_key) const {
568 return impl_->SSLSessionIsInCache(cache_key); 526 return impl_->SSLSessionIsInCache(cache_key);
569 } 527 }
570 528
571 void SSLSessionCacheOpenSSL::RemoveSessionAddedCallback(SSL* ssl) {
572 impl_->RemoveSessionAddedCallback(ssl);
573 }
574
575 void SSLSessionCacheOpenSSL::SetSessionAddedCallback(SSL* ssl,
576 const base::Closure& cb) {
577 impl_->SetSessionAddedCallback(ssl, cb);
578 }
579
580 void SSLSessionCacheOpenSSL::MarkSSLSessionAsGood(SSL* ssl) { 529 void SSLSessionCacheOpenSSL::MarkSSLSessionAsGood(SSL* ssl) {
581 return impl_->MarkSSLSessionAsGood(ssl); 530 return impl_->MarkSSLSessionAsGood(ssl);
582 } 531 }
583 532
533 bool SSLSessionCacheOpenSSL::SessionIsGood(SSL* ssl) {
534 return impl_->SessionIsGood(ssl);
535 }
536
584 void SSLSessionCacheOpenSSL::Flush() { impl_->Flush(); } 537 void SSLSessionCacheOpenSSL::Flush() { impl_->Flush(); }
585 538
586 } // namespace net 539 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698