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 |