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

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

Issue 353713005: Implements new, more robust design for communicating between SSLConnectJobs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added checks to determine if false start connections fail, and moved location of enable_job_waiting… Created 6 years, 5 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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 return false; // Session has not yet been marked good. Treat as a miss. 229 return false; // Session has not yet been marked good. Treat as a miss.
230 230
231 // Move to front of MRU list. 231 // Move to front of MRU list.
232 ordering_.push_front(session); 232 ordering_.push_front(session);
233 ordering_.erase(it->second); 233 ordering_.erase(it->second);
234 it->second = ordering_.begin(); 234 it->second = ordering_.begin();
235 235
236 return SSL_set_session(ssl, session) == 1; 236 return SSL_set_session(ssl, session) == 1;
237 } 237 }
238 238
239 bool SSLSessionIsInCache(const std::string& cache_key) const {
240 base::AutoLock locked(lock_);
241 KeyIndex::const_iterator it = key_index_.find(cache_key);
242 if (it == key_index_.end())
243 return false;
244 return true;
245 }
246
247 void NotifyOnSessionAdded(SSL* ssl, const base::Closure& callback) {
248 // Add this SSL* to the SSLtoCallbackMap.
249 std::pair<const base::Closure&, int> temp(callback, 0);
250 ssl_to_callback_map_.insert(SSLToCallbackMap::value_type(ssl, temp));
wtc 2014/07/08 01:25:43 This can be written using the associative array no
mshelley 2014/07/09 19:51:02 I can't use this notation because the callback can
251 }
252
253 // Determines if the session for |ssl| is in the cache, and calls the
254 // appropriate callback if that is the case.
255 void CheckIfSessionAdded(SSL* ssl) {
256 SSLToCallbackMap::iterator it = ssl_to_callback_map_.find(ssl);
257 if (it == ssl_to_callback_map_.end())
258 return;
259 // Increment the session's completion count.
260 (it->second.second)++;
wtc 2014/07/08 01:25:43 Nit: you can omit the parentheses. I know it's not
mshelley 2014/07/09 19:51:02 Done.
261 if (it->second.second == 2) {
262 // The session has been MarkedAsGood and Added, so it can be used.
wtc 2014/07/08 01:25:43 Please document that these can occur in either ord
mshelley 2014/07/09 19:51:02 Done.
263 it->second.first.Run();
wtc 2014/07/08 01:25:43 Should we remove the entry for |ssl| from ssl_to_c
mshelley 2014/07/09 19:51:02 Done.
264 }
265 }
266
239 void MarkSSLSessionAsGood(SSL* ssl) { 267 void MarkSSLSessionAsGood(SSL* ssl) {
240 SSL_SESSION* session = SSL_get_session(ssl); 268 SSL_SESSION* session = SSL_get_session(ssl);
241 if (!session) 269 if (!session)
242 return; 270 return;
243 271
244 // Mark the session as good, allowing it to be used for future connections. 272 // Mark the session as good, allowing it to be used for future connections.
245 SSL_SESSION_set_ex_data( 273 SSL_SESSION_set_ex_data(
246 session, GetSSLSessionExIndex(), reinterpret_cast<void*>(1)); 274 session, GetSSLSessionExIndex(), reinterpret_cast<void*>(1));
275
276 CheckIfSessionAdded(ssl);
247 } 277 }
248 278
249 // Flush all entries from the cache. 279 // Flush all entries from the cache.
250 void Flush() { 280 void Flush() {
251 base::AutoLock lock(lock_); 281 base::AutoLock lock(lock_);
252 id_index_.clear(); 282 id_index_.clear();
253 key_index_.clear(); 283 key_index_.clear();
254 while (!ordering_.empty()) { 284 while (!ordering_.empty()) {
255 SSL_SESSION* session = ordering_.front(); 285 SSL_SESSION* session = ordering_.front();
256 ordering_.pop_front(); 286 ordering_.pop_front();
257 SSL_SESSION_free(session); 287 SSL_SESSION_free(session);
258 } 288 }
259 } 289 }
260 290
261 private: 291 private:
262 // Type for list of SSL_SESSION handles, ordered in MRU order. 292 // Type for list of SSL_SESSION handles, ordered in MRU order.
263 typedef std::list<SSL_SESSION*> MRUSessionList; 293 typedef std::list<SSL_SESSION*> MRUSessionList;
264 // Type for a dictionary from unique cache keys to session list nodes. 294 // Type for a dictionary from unique cache keys to session list nodes.
265 typedef base::hash_map<std::string, MRUSessionList::iterator> KeyIndex; 295 typedef base::hash_map<std::string, MRUSessionList::iterator> KeyIndex;
266 // Type for a dictionary from SessionId values to key index nodes. 296 // Type for a dictionary from SessionId values to key index nodes.
267 typedef base::hash_map<SessionId, KeyIndex::iterator> SessionIdIndex; 297 typedef base::hash_map<SessionId, KeyIndex::iterator> SessionIdIndex;
298 // Type for a map from SSL* to associated callbacks
299 typedef std::map<SSL*, std::pair<const base::Closure&, int> >
wtc 2014/07/08 01:25:43 I think we may need to use "base::Closure" instead
mshelley 2014/07/09 19:51:02 Done.
300 SSLToCallbackMap;
268 301
269 // Return the key associated with a given session, or the empty string if 302 // Return the key associated with a given session, or the empty string if
270 // none exist. This shall only be used for debugging. 303 // none exist. This shall only be used for debugging.
271 std::string SessionKey(SSL_SESSION* session) { 304 std::string SessionKey(SSL_SESSION* session) {
272 if (!session) 305 if (!session)
273 return std::string("<null-session>"); 306 return std::string("<null-session>");
274 307
275 if (session->session_id_length == 0) 308 if (session->session_id_length == 0)
276 return std::string("<empty-session-id>"); 309 return std::string("<empty-session-id>");
277 310
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 return reinterpret_cast<SSLSessionCacheOpenSSLImpl*>(result); 369 return reinterpret_cast<SSLSessionCacheOpenSSLImpl*>(result);
337 } 370 }
338 371
339 // Called by OpenSSL when a new |session| was created and added to a given 372 // Called by OpenSSL when a new |session| was created and added to a given
340 // |ssl| connection. Note that the session's reference count was already 373 // |ssl| connection. Note that the session's reference count was already
341 // incremented before the function is entered. The function must return 1 374 // incremented before the function is entered. The function must return 1
342 // to indicate that it took ownership of the session, i.e. that the caller 375 // to indicate that it took ownership of the session, i.e. that the caller
343 // should not decrement its reference count after completion. 376 // should not decrement its reference count after completion.
344 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) { 377 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) {
345 GetCache(ssl->ctx)->OnSessionAdded(ssl, session); 378 GetCache(ssl->ctx)->OnSessionAdded(ssl, session);
379 GetCache(ssl->ctx)->CheckIfSessionAdded(ssl);
346 return 1; 380 return 1;
347 } 381 }
348 382
349 // Called by OpenSSL to indicate that a session must be removed from the 383 // Called by OpenSSL to indicate that a session must be removed from the
350 // cache. This happens when SSL_CTX is destroyed. 384 // cache. This happens when SSL_CTX is destroyed.
351 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) { 385 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) {
wtc 2014/07/08 01:25:43 Should we decrement the session's completion count
mshelley 2014/07/09 19:51:02 My initial thought would be that it's best to just
352 GetCache(ctx)->OnSessionRemoved(session); 386 GetCache(ctx)->OnSessionRemoved(session);
353 } 387 }
354 388
355 // Called by OpenSSL to generate a new session ID. This happens during a 389 // Called by OpenSSL to generate a new session ID. This happens during a
356 // SSL connection operation, when the SSL object doesn't have a session yet. 390 // SSL connection operation, when the SSL object doesn't have a session yet.
357 // 391 //
358 // A session ID is a random string of bytes used to uniquely identify the 392 // A session ID is a random string of bytes used to uniquely identify the
359 // session between a client and a server. 393 // session between a client and a server.
360 // 394 //
361 // |ssl| is a SSL connection handle. Ignored here. 395 // |ssl| is a SSL connection handle. Ignored here.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 if (id_index_.find(SessionId(id, id_len)) == id_index_.end()) 493 if (id_index_.find(SessionId(id, id_len)) == id_index_.end())
460 return true; 494 return true;
461 } 495 }
462 DLOG(ERROR) << "Couldn't generate unique session ID of " << id_len 496 DLOG(ERROR) << "Couldn't generate unique session ID of " << id_len
463 << "bytes after " << kMaxTries << " tries."; 497 << "bytes after " << kMaxTries << " tries.";
464 return false; 498 return false;
465 } 499 }
466 500
467 SSL_CTX* ctx_; 501 SSL_CTX* ctx_;
468 SSLSessionCacheOpenSSL::Config config_; 502 SSLSessionCacheOpenSSL::Config config_;
503 SSLToCallbackMap ssl_to_callback_map_;
469 504
470 // method to get the index which can later be used with SSL_CTX_get_ex_data() 505 // method to get the index which can later be used with SSL_CTX_get_ex_data()
471 // or SSL_CTX_set_ex_data(). 506 // or SSL_CTX_set_ex_data().
472 base::Lock lock_; // Protects access to containers below. 507 mutable base::Lock lock_; // Protects access to containers below.
473 508
474 MRUSessionList ordering_; 509 MRUSessionList ordering_;
475 KeyIndex key_index_; 510 KeyIndex key_index_;
476 SessionIdIndex id_index_; 511 SessionIdIndex id_index_;
477 512
478 size_t expiration_check_; 513 size_t expiration_check_;
479 }; 514 };
480 515
481 SSLSessionCacheOpenSSL::~SSLSessionCacheOpenSSL() { delete impl_; } 516 SSLSessionCacheOpenSSL::~SSLSessionCacheOpenSSL() { delete impl_; }
482 517
483 size_t SSLSessionCacheOpenSSL::size() const { return impl_->size(); } 518 size_t SSLSessionCacheOpenSSL::size() const { return impl_->size(); }
484 519
485 void SSLSessionCacheOpenSSL::Reset(SSL_CTX* ctx, const Config& config) { 520 void SSLSessionCacheOpenSSL::Reset(SSL_CTX* ctx, const Config& config) {
486 if (impl_) 521 if (impl_)
487 delete impl_; 522 delete impl_;
488 523
489 impl_ = new SSLSessionCacheOpenSSLImpl(ctx, config); 524 impl_ = new SSLSessionCacheOpenSSLImpl(ctx, config);
490 } 525 }
491 526
492 bool SSLSessionCacheOpenSSL::SetSSLSession(SSL* ssl) { 527 bool SSLSessionCacheOpenSSL::SetSSLSession(SSL* ssl) {
493 return impl_->SetSSLSession(ssl); 528 return impl_->SetSSLSession(ssl);
494 } 529 }
495 530
496 bool SSLSessionCacheOpenSSL::SetSSLSessionWithKey( 531 bool SSLSessionCacheOpenSSL::SetSSLSessionWithKey(
497 SSL* ssl, 532 SSL* ssl,
498 const std::string& cache_key) { 533 const std::string& cache_key) {
499 return impl_->SetSSLSessionWithKey(ssl, cache_key); 534 return impl_->SetSSLSessionWithKey(ssl, cache_key);
500 } 535 }
501 536
537 bool SSLSessionCacheOpenSSL::SSLSessionIsInCache(
538 const std::string& cache_key) const {
539 return impl_->SSLSessionIsInCache(cache_key);
540 }
541
542 void SSLSessionCacheOpenSSL::NotifyOnSessionAdded(SSL* ssl,
543 const base::Closure& cb) {
544 impl_->NotifyOnSessionAdded(ssl, cb);
545 }
546
502 void SSLSessionCacheOpenSSL::MarkSSLSessionAsGood(SSL* ssl) { 547 void SSLSessionCacheOpenSSL::MarkSSLSessionAsGood(SSL* ssl) {
503 return impl_->MarkSSLSessionAsGood(ssl); 548 return impl_->MarkSSLSessionAsGood(ssl);
504 } 549 }
505 550
506 void SSLSessionCacheOpenSSL::Flush() { impl_->Flush(); } 551 void SSLSessionCacheOpenSSL::Flush() { impl_->Flush(); }
507 552
508 } // namespace net 553 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698