Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/cert/multi_threaded_cert_verifier.h" | 5 #include "net/cert/multi_threaded_cert_verifier.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 CertVerifyResult verify_result_; | 313 CertVerifyResult verify_result_; |
| 314 | 314 |
| 315 DISALLOW_COPY_AND_ASSIGN(CertVerifierWorker); | 315 DISALLOW_COPY_AND_ASSIGN(CertVerifierWorker); |
| 316 }; | 316 }; |
| 317 | 317 |
| 318 // A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It | 318 // A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It |
| 319 // lives only on the CertVerifier's origin message loop. | 319 // lives only on the CertVerifier's origin message loop. |
| 320 class CertVerifierJob { | 320 class CertVerifierJob { |
| 321 public: | 321 public: |
| 322 CertVerifierJob(CertVerifierWorker* worker, | 322 CertVerifierJob(CertVerifierWorker* worker, |
| 323 bool is_first_job, | |
| 323 const BoundNetLog& net_log) | 324 const BoundNetLog& net_log) |
| 324 : start_time_(base::TimeTicks::Now()), | 325 : start_time_(base::TimeTicks::Now()), |
| 325 worker_(worker), | 326 worker_(worker), |
| 327 is_first_job_(is_first_job), | |
| 326 net_log_(net_log) { | 328 net_log_(net_log) { |
| 327 net_log_.BeginEvent( | 329 net_log_.BeginEvent( |
| 328 NetLog::TYPE_CERT_VERIFIER_JOB, | 330 NetLog::TYPE_CERT_VERIFIER_JOB, |
| 329 base::Bind(&NetLogX509CertificateCallback, | 331 base::Bind(&NetLogX509CertificateCallback, |
| 330 base::Unretained(worker_->certificate()))); | 332 base::Unretained(worker_->certificate()))); |
| 331 } | 333 } |
| 332 | 334 |
| 333 ~CertVerifierJob() { | 335 ~CertVerifierJob() { |
| 334 if (worker_) { | 336 if (worker_) { |
| 335 net_log_.AddEvent(NetLog::TYPE_CANCELLED); | 337 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
| 336 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); | 338 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); |
| 337 worker_->Cancel(); | 339 worker_->Cancel(); |
| 338 DeleteAllCanceled(); | 340 DeleteAllCanceled(); |
| 339 } | 341 } |
| 340 } | 342 } |
| 341 | 343 |
| 342 void AddRequest(CertVerifierRequest* request) { | 344 void AddRequest(CertVerifierRequest* request) { |
| 343 request->net_log().AddEvent( | 345 request->net_log().AddEvent( |
| 344 NetLog::TYPE_CERT_VERIFIER_REQUEST_BOUND_TO_JOB, | 346 NetLog::TYPE_CERT_VERIFIER_REQUEST_BOUND_TO_JOB, |
| 345 net_log_.source().ToEventParametersCallback()); | 347 net_log_.source().ToEventParametersCallback()); |
| 346 | 348 |
| 347 requests_.push_back(request); | 349 requests_.push_back(request); |
| 348 } | 350 } |
| 349 | 351 |
| 350 void HandleResult( | 352 void HandleResult( |
| 351 const MultiThreadedCertVerifier::CachedResult& verify_result) { | 353 const MultiThreadedCertVerifier::CachedResult& verify_result) { |
| 352 worker_ = NULL; | 354 worker_ = NULL; |
| 353 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); | 355 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); |
| 356 base::TimeDelta latency = base::TimeTicks::Now() - start_time_; | |
| 354 UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency", | 357 UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency", |
| 355 base::TimeTicks::Now() - start_time_, | 358 latency, |
| 356 base::TimeDelta::FromMilliseconds(1), | 359 base::TimeDelta::FromMilliseconds(1), |
| 357 base::TimeDelta::FromMinutes(10), | 360 base::TimeDelta::FromMinutes(10), |
| 358 100); | 361 100); |
| 362 if (is_first_job_) { | |
| 363 UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_First_Job_Latency", | |
| 364 latency, | |
| 365 base::TimeDelta::FromMilliseconds(1), | |
| 366 base::TimeDelta::FromMinutes(10), | |
| 367 100); | |
| 368 } | |
| 359 PostAll(verify_result); | 369 PostAll(verify_result); |
| 360 } | 370 } |
| 361 | 371 |
| 362 private: | 372 private: |
| 363 void PostAll(const MultiThreadedCertVerifier::CachedResult& verify_result) { | 373 void PostAll(const MultiThreadedCertVerifier::CachedResult& verify_result) { |
| 364 std::vector<CertVerifierRequest*> requests; | 374 std::vector<CertVerifierRequest*> requests; |
| 365 requests_.swap(requests); | 375 requests_.swap(requests); |
| 366 | 376 |
| 367 for (std::vector<CertVerifierRequest*>::iterator | 377 for (std::vector<CertVerifierRequest*>::iterator |
| 368 i = requests.begin(); i != requests.end(); i++) { | 378 i = requests.begin(); i != requests.end(); i++) { |
| 369 (*i)->Post(verify_result); | 379 (*i)->Post(verify_result); |
| 370 // Post() causes the CertVerifierRequest to delete itself. | 380 // Post() causes the CertVerifierRequest to delete itself. |
| 371 } | 381 } |
| 372 } | 382 } |
| 373 | 383 |
| 374 void DeleteAllCanceled() { | 384 void DeleteAllCanceled() { |
| 375 for (std::vector<CertVerifierRequest*>::iterator | 385 for (std::vector<CertVerifierRequest*>::iterator |
| 376 i = requests_.begin(); i != requests_.end(); i++) { | 386 i = requests_.begin(); i != requests_.end(); i++) { |
| 377 if ((*i)->canceled()) { | 387 if ((*i)->canceled()) { |
| 378 delete *i; | 388 delete *i; |
| 379 } else { | 389 } else { |
| 380 LOG(DFATAL) << "CertVerifierRequest leaked!"; | 390 LOG(DFATAL) << "CertVerifierRequest leaked!"; |
| 381 } | 391 } |
| 382 } | 392 } |
| 383 } | 393 } |
| 384 | 394 |
| 385 const base::TimeTicks start_time_; | 395 const base::TimeTicks start_time_; |
| 386 std::vector<CertVerifierRequest*> requests_; | 396 std::vector<CertVerifierRequest*> requests_; |
| 387 CertVerifierWorker* worker_; | 397 CertVerifierWorker* worker_; |
| 398 bool is_first_job_; | |
| 388 const BoundNetLog net_log_; | 399 const BoundNetLog net_log_; |
| 389 }; | 400 }; |
| 390 | 401 |
| 391 MultiThreadedCertVerifier::MultiThreadedCertVerifier( | 402 MultiThreadedCertVerifier::MultiThreadedCertVerifier( |
| 392 CertVerifyProc* verify_proc) | 403 CertVerifyProc* verify_proc) |
| 393 : cache_(kMaxCacheEntries), | 404 : cache_(kMaxCacheEntries), |
| 394 requests_(0), | 405 requests_(0), |
| 395 cache_hits_(0), | 406 cache_hits_(0), |
| 396 inflight_joins_(0), | 407 inflight_joins_(0), |
| 397 verify_proc_(verify_proc), | 408 verify_proc_(verify_proc), |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 // Need to make a new request. | 467 // Need to make a new request. |
| 457 CertVerifierWorker* worker = | 468 CertVerifierWorker* worker = |
| 458 new CertVerifierWorker(verify_proc_.get(), | 469 new CertVerifierWorker(verify_proc_.get(), |
| 459 cert, | 470 cert, |
| 460 hostname, | 471 hostname, |
| 461 flags, | 472 flags, |
| 462 crl_set, | 473 crl_set, |
| 463 additional_trust_anchors, | 474 additional_trust_anchors, |
| 464 this); | 475 this); |
| 465 job = new CertVerifierJob( | 476 job = new CertVerifierJob( |
| 466 worker, | 477 worker, requests_ == 1, |
| 467 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); | 478 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); |
| 468 if (!worker->Start()) { | 479 if (!worker->Start()) { |
| 469 delete job; | 480 delete job; |
| 470 delete worker; | 481 delete worker; |
| 471 *out_req = NULL; | 482 *out_req = NULL; |
| 472 // TODO(wtc): log to the NetLog. | 483 // TODO(wtc): log to the NetLog. |
| 473 LOG(ERROR) << "CertVerifierWorker couldn't be started."; | 484 LOG(ERROR) << "CertVerifierWorker couldn't be started."; |
| 474 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. | 485 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. |
| 475 } | 486 } |
| 476 inflight_.insert(std::make_pair(key, job)); | 487 inflight_.insert(std::make_pair(key, job)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 cache_.Put( | 553 cache_.Put( |
| 543 key, cached_result, CacheValidityPeriod(now), | 554 key, cached_result, CacheValidityPeriod(now), |
| 544 CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs))); | 555 CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs))); |
| 545 | 556 |
| 546 std::map<RequestParams, CertVerifierJob*>::iterator j; | 557 std::map<RequestParams, CertVerifierJob*>::iterator j; |
| 547 j = inflight_.find(key); | 558 j = inflight_.find(key); |
| 548 if (j == inflight_.end()) { | 559 if (j == inflight_.end()) { |
| 549 NOTREACHED(); | 560 NOTREACHED(); |
| 550 return; | 561 return; |
| 551 } | 562 } |
| 552 CertVerifierJob* job = j->second; | 563 CertVerifierJob* job = j->second; |
|
Ryan Sleevi
2014/04/08 20:19:01
Rather than at a bool member to the CertVerifierJo
davidben
2014/04/08 23:33:21
Done.
| |
| 553 inflight_.erase(j); | 564 inflight_.erase(j); |
| 554 | 565 |
| 555 job->HandleResult(cached_result); | 566 job->HandleResult(cached_result); |
| 556 delete job; | 567 delete job; |
| 557 } | 568 } |
| 558 | 569 |
| 559 void MultiThreadedCertVerifier::OnCACertChanged( | 570 void MultiThreadedCertVerifier::OnCACertChanged( |
| 560 const X509Certificate* cert) { | 571 const X509Certificate* cert) { |
| 561 DCHECK(CalledOnValidThread()); | 572 DCHECK(CalledOnValidThread()); |
| 562 | 573 |
| 563 ClearCache(); | 574 ClearCache(); |
| 564 } | 575 } |
| 565 | 576 |
| 566 } // namespace net | 577 } // namespace net |
| OLD | NEW |