| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/ssl/channel_id_service.h" | 5 #include "net/ssl/channel_id_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <memory> |
| 9 #include <utility> | 10 #include <utility> |
| 10 | 11 |
| 11 #include "base/atomic_sequence_num.h" | 12 #include "base/atomic_sequence_num.h" |
| 12 #include "base/bind.h" | 13 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
| 14 #include "base/callback_helpers.h" | 15 #include "base/callback_helpers.h" |
| 15 #include "base/compiler_specific.h" | 16 #include "base/compiler_specific.h" |
| 16 #include "base/location.h" | 17 #include "base/location.h" |
| 17 #include "base/logging.h" | 18 #include "base/logging.h" |
| 18 #include "base/macros.h" | 19 #include "base/macros.h" |
| 19 #include "base/memory/ref_counted.h" | 20 #include "base/memory/ref_counted.h" |
| 20 #include "base/memory/scoped_ptr.h" | |
| 21 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
| 22 #include "base/rand_util.h" | 22 #include "base/rand_util.h" |
| 23 #include "base/single_thread_task_runner.h" | 23 #include "base/single_thread_task_runner.h" |
| 24 #include "base/stl_util.h" | 24 #include "base/stl_util.h" |
| 25 #include "base/task_runner.h" | 25 #include "base/task_runner.h" |
| 26 #include "base/thread_task_runner_handle.h" | 26 #include "base/thread_task_runner_handle.h" |
| 27 #include "crypto/ec_private_key.h" | 27 #include "crypto/ec_private_key.h" |
| 28 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 29 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 29 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 30 #include "net/cert/x509_certificate.h" | 30 #include "net/cert/x509_certificate.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 request_time, | 79 request_time, |
| 80 base::TimeDelta::FromMilliseconds(1), | 80 base::TimeDelta::FromMilliseconds(1), |
| 81 base::TimeDelta::FromMinutes(5), | 81 base::TimeDelta::FromMinutes(5), |
| 82 50); | 82 50); |
| 83 } | 83 } |
| 84 | 84 |
| 85 // On success, returns a ChannelID object and sets |*error| to OK. | 85 // On success, returns a ChannelID object and sets |*error| to OK. |
| 86 // Otherwise, returns NULL, and |*error| will be set to a net error code. | 86 // Otherwise, returns NULL, and |*error| will be set to a net error code. |
| 87 // |serial_number| is passed in because base::RandInt cannot be called from an | 87 // |serial_number| is passed in because base::RandInt cannot be called from an |
| 88 // unjoined thread, due to relying on a non-leaked LazyInstance | 88 // unjoined thread, due to relying on a non-leaked LazyInstance |
| 89 scoped_ptr<ChannelIDStore::ChannelID> GenerateChannelID( | 89 std::unique_ptr<ChannelIDStore::ChannelID> GenerateChannelID( |
| 90 const std::string& server_identifier, | 90 const std::string& server_identifier, |
| 91 int* error) { | 91 int* error) { |
| 92 scoped_ptr<ChannelIDStore::ChannelID> result; | 92 std::unique_ptr<ChannelIDStore::ChannelID> result; |
| 93 | 93 |
| 94 base::TimeTicks start = base::TimeTicks::Now(); | 94 base::TimeTicks start = base::TimeTicks::Now(); |
| 95 base::Time creation_time = base::Time::Now(); | 95 base::Time creation_time = base::Time::Now(); |
| 96 scoped_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create()); | 96 std::unique_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create()); |
| 97 | 97 |
| 98 if (!key) { | 98 if (!key) { |
| 99 DLOG(ERROR) << "Unable to create channel ID key pair"; | 99 DLOG(ERROR) << "Unable to create channel ID key pair"; |
| 100 *error = ERR_KEY_GENERATION_FAILED; | 100 *error = ERR_KEY_GENERATION_FAILED; |
| 101 return result; | 101 return result; |
| 102 } | 102 } |
| 103 | 103 |
| 104 result.reset(new ChannelIDStore::ChannelID(server_identifier, creation_time, | 104 result.reset(new ChannelIDStore::ChannelID(server_identifier, creation_time, |
| 105 std::move(key))); | 105 std::move(key))); |
| 106 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.GenerateCertTime", | 106 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.GenerateCertTime", |
| 107 base::TimeTicks::Now() - start, | 107 base::TimeTicks::Now() - start, |
| 108 base::TimeDelta::FromMilliseconds(1), | 108 base::TimeDelta::FromMilliseconds(1), |
| 109 base::TimeDelta::FromMinutes(5), | 109 base::TimeDelta::FromMinutes(5), |
| 110 50); | 110 50); |
| 111 *error = OK; | 111 *error = OK; |
| 112 return result; | 112 return result; |
| 113 } | 113 } |
| 114 | 114 |
| 115 } // namespace | 115 } // namespace |
| 116 | 116 |
| 117 // ChannelIDServiceWorker runs on a worker thread and takes care of the | 117 // ChannelIDServiceWorker runs on a worker thread and takes care of the |
| 118 // blocking process of performing key generation. Will take care of deleting | 118 // blocking process of performing key generation. Will take care of deleting |
| 119 // itself once Start() is called. | 119 // itself once Start() is called. |
| 120 class ChannelIDServiceWorker { | 120 class ChannelIDServiceWorker { |
| 121 public: | 121 public: |
| 122 typedef base::Callback<void( | 122 typedef base::Callback< |
| 123 const std::string&, | 123 void(const std::string&, int, std::unique_ptr<ChannelIDStore::ChannelID>)> |
| 124 int, | 124 WorkerDoneCallback; |
| 125 scoped_ptr<ChannelIDStore::ChannelID>)> WorkerDoneCallback; | |
| 126 | 125 |
| 127 ChannelIDServiceWorker(const std::string& server_identifier, | 126 ChannelIDServiceWorker(const std::string& server_identifier, |
| 128 const WorkerDoneCallback& callback) | 127 const WorkerDoneCallback& callback) |
| 129 : server_identifier_(server_identifier), | 128 : server_identifier_(server_identifier), |
| 130 origin_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 129 origin_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 131 callback_(callback) {} | 130 callback_(callback) {} |
| 132 | 131 |
| 133 // Starts the worker on |task_runner|. If the worker fails to start, such as | 132 // Starts the worker on |task_runner|. If the worker fails to start, such as |
| 134 // if the task runner is shutting down, then it will take care of deleting | 133 // if the task runner is shutting down, then it will take care of deleting |
| 135 // itself. | 134 // itself. |
| 136 bool Start(const scoped_refptr<base::TaskRunner>& task_runner) { | 135 bool Start(const scoped_refptr<base::TaskRunner>& task_runner) { |
| 137 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); | 136 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); |
| 138 | 137 |
| 139 return task_runner->PostTask( | 138 return task_runner->PostTask( |
| 140 FROM_HERE, | 139 FROM_HERE, |
| 141 base::Bind(&ChannelIDServiceWorker::Run, base::Owned(this))); | 140 base::Bind(&ChannelIDServiceWorker::Run, base::Owned(this))); |
| 142 } | 141 } |
| 143 | 142 |
| 144 private: | 143 private: |
| 145 void Run() { | 144 void Run() { |
| 146 // Runs on a worker thread. | 145 // Runs on a worker thread. |
| 147 int error = ERR_FAILED; | 146 int error = ERR_FAILED; |
| 148 scoped_ptr<ChannelIDStore::ChannelID> channel_id = | 147 std::unique_ptr<ChannelIDStore::ChannelID> channel_id = |
| 149 GenerateChannelID(server_identifier_, &error); | 148 GenerateChannelID(server_identifier_, &error); |
| 150 #if !defined(USE_OPENSSL) | 149 #if !defined(USE_OPENSSL) |
| 151 // Detach the thread from NSPR. | 150 // Detach the thread from NSPR. |
| 152 // Calling NSS functions attaches the thread to NSPR, which stores | 151 // Calling NSS functions attaches the thread to NSPR, which stores |
| 153 // the NSPR thread ID in thread-specific data. | 152 // the NSPR thread ID in thread-specific data. |
| 154 // The threads in our thread pool terminate after we have called | 153 // The threads in our thread pool terminate after we have called |
| 155 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets | 154 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets |
| 156 // segfaults on shutdown when the threads' thread-specific data | 155 // segfaults on shutdown when the threads' thread-specific data |
| 157 // destructors run. | 156 // destructors run. |
| 158 PR_DetachThread(); | 157 PR_DetachThread(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 179 } | 178 } |
| 180 | 179 |
| 181 ~ChannelIDServiceJob() { DCHECK(requests_.empty()); } | 180 ~ChannelIDServiceJob() { DCHECK(requests_.empty()); } |
| 182 | 181 |
| 183 void AddRequest(ChannelIDService::Request* request, | 182 void AddRequest(ChannelIDService::Request* request, |
| 184 bool create_if_missing = false) { | 183 bool create_if_missing = false) { |
| 185 create_if_missing_ |= create_if_missing; | 184 create_if_missing_ |= create_if_missing; |
| 186 requests_.push_back(request); | 185 requests_.push_back(request); |
| 187 } | 186 } |
| 188 | 187 |
| 189 void HandleResult(int error, scoped_ptr<crypto::ECPrivateKey> key) { | 188 void HandleResult(int error, std::unique_ptr<crypto::ECPrivateKey> key) { |
| 190 PostAll(error, std::move(key)); | 189 PostAll(error, std::move(key)); |
| 191 } | 190 } |
| 192 | 191 |
| 193 bool CreateIfMissing() const { return create_if_missing_; } | 192 bool CreateIfMissing() const { return create_if_missing_; } |
| 194 | 193 |
| 195 void CancelRequest(ChannelIDService::Request* req) { | 194 void CancelRequest(ChannelIDService::Request* req) { |
| 196 auto it = std::find(requests_.begin(), requests_.end(), req); | 195 auto it = std::find(requests_.begin(), requests_.end(), req); |
| 197 if (it != requests_.end()) | 196 if (it != requests_.end()) |
| 198 requests_.erase(it); | 197 requests_.erase(it); |
| 199 } | 198 } |
| 200 | 199 |
| 201 private: | 200 private: |
| 202 void PostAll(int error, scoped_ptr<crypto::ECPrivateKey> key) { | 201 void PostAll(int error, std::unique_ptr<crypto::ECPrivateKey> key) { |
| 203 std::vector<ChannelIDService::Request*> requests; | 202 std::vector<ChannelIDService::Request*> requests; |
| 204 requests_.swap(requests); | 203 requests_.swap(requests); |
| 205 | 204 |
| 206 for (std::vector<ChannelIDService::Request*>::iterator i = requests.begin(); | 205 for (std::vector<ChannelIDService::Request*>::iterator i = requests.begin(); |
| 207 i != requests.end(); i++) { | 206 i != requests.end(); i++) { |
| 208 scoped_ptr<crypto::ECPrivateKey> key_copy; | 207 std::unique_ptr<crypto::ECPrivateKey> key_copy; |
| 209 if (key) | 208 if (key) |
| 210 key_copy.reset(key->Copy()); | 209 key_copy.reset(key->Copy()); |
| 211 (*i)->Post(error, std::move(key_copy)); | 210 (*i)->Post(error, std::move(key_copy)); |
| 212 } | 211 } |
| 213 } | 212 } |
| 214 | 213 |
| 215 std::vector<ChannelIDService::Request*> requests_; | 214 std::vector<ChannelIDService::Request*> requests_; |
| 216 bool create_if_missing_; | 215 bool create_if_missing_; |
| 217 }; | 216 }; |
| 218 | 217 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 233 job_->CancelRequest(this); | 232 job_->CancelRequest(this); |
| 234 | 233 |
| 235 service_ = NULL; | 234 service_ = NULL; |
| 236 } | 235 } |
| 237 } | 236 } |
| 238 | 237 |
| 239 void ChannelIDService::Request::RequestStarted( | 238 void ChannelIDService::Request::RequestStarted( |
| 240 ChannelIDService* service, | 239 ChannelIDService* service, |
| 241 base::TimeTicks request_start, | 240 base::TimeTicks request_start, |
| 242 const CompletionCallback& callback, | 241 const CompletionCallback& callback, |
| 243 scoped_ptr<crypto::ECPrivateKey>* key, | 242 std::unique_ptr<crypto::ECPrivateKey>* key, |
| 244 ChannelIDServiceJob* job) { | 243 ChannelIDServiceJob* job) { |
| 245 DCHECK(service_ == NULL); | 244 DCHECK(service_ == NULL); |
| 246 service_ = service; | 245 service_ = service; |
| 247 request_start_ = request_start; | 246 request_start_ = request_start; |
| 248 callback_ = callback; | 247 callback_ = callback; |
| 249 key_ = key; | 248 key_ = key; |
| 250 job_ = job; | 249 job_ = job; |
| 251 } | 250 } |
| 252 | 251 |
| 253 void ChannelIDService::Request::Post(int error, | 252 void ChannelIDService::Request::Post( |
| 254 scoped_ptr<crypto::ECPrivateKey> key) { | 253 int error, |
| 254 std::unique_ptr<crypto::ECPrivateKey> key) { |
| 255 switch (error) { | 255 switch (error) { |
| 256 case OK: { | 256 case OK: { |
| 257 base::TimeDelta request_time = base::TimeTicks::Now() - request_start_; | 257 base::TimeDelta request_time = base::TimeTicks::Now() - request_start_; |
| 258 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.GetCertTimeAsync", | 258 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.GetCertTimeAsync", |
| 259 request_time, | 259 request_time, |
| 260 base::TimeDelta::FromMilliseconds(1), | 260 base::TimeDelta::FromMilliseconds(1), |
| 261 base::TimeDelta::FromMinutes(5), 50); | 261 base::TimeDelta::FromMinutes(5), 50); |
| 262 RecordGetChannelIDTime(request_time); | 262 RecordGetChannelIDTime(request_time); |
| 263 RecordGetChannelIDResult(ASYNC_SUCCESS); | 263 RecordGetChannelIDResult(ASYNC_SUCCESS); |
| 264 break; | 264 break; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 std::string domain = | 307 std::string domain = |
| 308 registry_controlled_domains::GetDomainAndRegistry( | 308 registry_controlled_domains::GetDomainAndRegistry( |
| 309 host, registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); | 309 host, registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); |
| 310 if (domain.empty()) | 310 if (domain.empty()) |
| 311 return host; | 311 return host; |
| 312 return domain; | 312 return domain; |
| 313 } | 313 } |
| 314 | 314 |
| 315 int ChannelIDService::GetOrCreateChannelID( | 315 int ChannelIDService::GetOrCreateChannelID( |
| 316 const std::string& host, | 316 const std::string& host, |
| 317 scoped_ptr<crypto::ECPrivateKey>* key, | 317 std::unique_ptr<crypto::ECPrivateKey>* key, |
| 318 const CompletionCallback& callback, | 318 const CompletionCallback& callback, |
| 319 Request* out_req) { | 319 Request* out_req) { |
| 320 DVLOG(1) << __FUNCTION__ << " " << host; | 320 DVLOG(1) << __FUNCTION__ << " " << host; |
| 321 DCHECK(CalledOnValidThread()); | 321 DCHECK(CalledOnValidThread()); |
| 322 base::TimeTicks request_start = base::TimeTicks::Now(); | 322 base::TimeTicks request_start = base::TimeTicks::Now(); |
| 323 | 323 |
| 324 if (callback.is_null() || !key || host.empty()) { | 324 if (callback.is_null() || !key || host.empty()) { |
| 325 RecordGetChannelIDResult(INVALID_ARGUMENT); | 325 RecordGetChannelIDResult(INVALID_ARGUMENT); |
| 326 return ERR_INVALID_ARGUMENT; | 326 return ERR_INVALID_ARGUMENT; |
| 327 } | 327 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 | 362 |
| 363 job->AddRequest(out_req); | 363 job->AddRequest(out_req); |
| 364 out_req->RequestStarted(this, request_start, callback, key, job); | 364 out_req->RequestStarted(this, request_start, callback, key, job); |
| 365 return ERR_IO_PENDING; | 365 return ERR_IO_PENDING; |
| 366 } | 366 } |
| 367 | 367 |
| 368 return err; | 368 return err; |
| 369 } | 369 } |
| 370 | 370 |
| 371 int ChannelIDService::GetChannelID(const std::string& host, | 371 int ChannelIDService::GetChannelID(const std::string& host, |
| 372 scoped_ptr<crypto::ECPrivateKey>* key, | 372 std::unique_ptr<crypto::ECPrivateKey>* key, |
| 373 const CompletionCallback& callback, | 373 const CompletionCallback& callback, |
| 374 Request* out_req) { | 374 Request* out_req) { |
| 375 DVLOG(1) << __FUNCTION__ << " " << host; | 375 DVLOG(1) << __FUNCTION__ << " " << host; |
| 376 DCHECK(CalledOnValidThread()); | 376 DCHECK(CalledOnValidThread()); |
| 377 base::TimeTicks request_start = base::TimeTicks::Now(); | 377 base::TimeTicks request_start = base::TimeTicks::Now(); |
| 378 | 378 |
| 379 if (callback.is_null() || !key || host.empty()) { | 379 if (callback.is_null() || !key || host.empty()) { |
| 380 RecordGetChannelIDResult(INVALID_ARGUMENT); | 380 RecordGetChannelIDResult(INVALID_ARGUMENT); |
| 381 return ERR_INVALID_ARGUMENT; | 381 return ERR_INVALID_ARGUMENT; |
| 382 } | 382 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 396 return ERR_IO_PENDING; | 396 return ERR_IO_PENDING; |
| 397 } | 397 } |
| 398 | 398 |
| 399 int err = LookupChannelID(request_start, domain, key, create_if_missing, | 399 int err = LookupChannelID(request_start, domain, key, create_if_missing, |
| 400 callback, out_req); | 400 callback, out_req); |
| 401 return err; | 401 return err; |
| 402 } | 402 } |
| 403 | 403 |
| 404 void ChannelIDService::GotChannelID(int err, | 404 void ChannelIDService::GotChannelID(int err, |
| 405 const std::string& server_identifier, | 405 const std::string& server_identifier, |
| 406 scoped_ptr<crypto::ECPrivateKey> key) { | 406 std::unique_ptr<crypto::ECPrivateKey> key) { |
| 407 DCHECK(CalledOnValidThread()); | 407 DCHECK(CalledOnValidThread()); |
| 408 | 408 |
| 409 std::map<std::string, ChannelIDServiceJob*>::iterator j; | 409 std::map<std::string, ChannelIDServiceJob*>::iterator j; |
| 410 j = inflight_.find(server_identifier); | 410 j = inflight_.find(server_identifier); |
| 411 if (j == inflight_.end()) { | 411 if (j == inflight_.end()) { |
| 412 NOTREACHED(); | 412 NOTREACHED(); |
| 413 return; | 413 return; |
| 414 } | 414 } |
| 415 | 415 |
| 416 if (err == OK) { | 416 if (err == OK) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 441 } | 441 } |
| 442 } | 442 } |
| 443 | 443 |
| 444 ChannelIDStore* ChannelIDService::GetChannelIDStore() { | 444 ChannelIDStore* ChannelIDService::GetChannelIDStore() { |
| 445 return channel_id_store_.get(); | 445 return channel_id_store_.get(); |
| 446 } | 446 } |
| 447 | 447 |
| 448 void ChannelIDService::GeneratedChannelID( | 448 void ChannelIDService::GeneratedChannelID( |
| 449 const std::string& server_identifier, | 449 const std::string& server_identifier, |
| 450 int error, | 450 int error, |
| 451 scoped_ptr<ChannelIDStore::ChannelID> channel_id) { | 451 std::unique_ptr<ChannelIDStore::ChannelID> channel_id) { |
| 452 DCHECK(CalledOnValidThread()); | 452 DCHECK(CalledOnValidThread()); |
| 453 | 453 |
| 454 scoped_ptr<crypto::ECPrivateKey> key; | 454 std::unique_ptr<crypto::ECPrivateKey> key; |
| 455 if (error == OK) { | 455 if (error == OK) { |
| 456 key.reset(channel_id->key()->Copy()); | 456 key.reset(channel_id->key()->Copy()); |
| 457 channel_id_store_->SetChannelID(std::move(channel_id)); | 457 channel_id_store_->SetChannelID(std::move(channel_id)); |
| 458 } | 458 } |
| 459 HandleResult(error, server_identifier, std::move(key)); | 459 HandleResult(error, server_identifier, std::move(key)); |
| 460 } | 460 } |
| 461 | 461 |
| 462 void ChannelIDService::HandleResult(int error, | 462 void ChannelIDService::HandleResult(int error, |
| 463 const std::string& server_identifier, | 463 const std::string& server_identifier, |
| 464 scoped_ptr<crypto::ECPrivateKey> key) { | 464 std::unique_ptr<crypto::ECPrivateKey> key) { |
| 465 DCHECK(CalledOnValidThread()); | 465 DCHECK(CalledOnValidThread()); |
| 466 | 466 |
| 467 std::map<std::string, ChannelIDServiceJob*>::iterator j; | 467 std::map<std::string, ChannelIDServiceJob*>::iterator j; |
| 468 j = inflight_.find(server_identifier); | 468 j = inflight_.find(server_identifier); |
| 469 if (j == inflight_.end()) { | 469 if (j == inflight_.end()) { |
| 470 NOTREACHED(); | 470 NOTREACHED(); |
| 471 return; | 471 return; |
| 472 } | 472 } |
| 473 ChannelIDServiceJob* job = j->second; | 473 ChannelIDServiceJob* job = j->second; |
| 474 inflight_.erase(j); | 474 inflight_.erase(j); |
| 475 | 475 |
| 476 job->HandleResult(error, std::move(key)); | 476 job->HandleResult(error, std::move(key)); |
| 477 delete job; | 477 delete job; |
| 478 } | 478 } |
| 479 | 479 |
| 480 bool ChannelIDService::JoinToInFlightRequest( | 480 bool ChannelIDService::JoinToInFlightRequest( |
| 481 const base::TimeTicks& request_start, | 481 const base::TimeTicks& request_start, |
| 482 const std::string& domain, | 482 const std::string& domain, |
| 483 scoped_ptr<crypto::ECPrivateKey>* key, | 483 std::unique_ptr<crypto::ECPrivateKey>* key, |
| 484 bool create_if_missing, | 484 bool create_if_missing, |
| 485 const CompletionCallback& callback, | 485 const CompletionCallback& callback, |
| 486 Request* out_req) { | 486 Request* out_req) { |
| 487 ChannelIDServiceJob* job = NULL; | 487 ChannelIDServiceJob* job = NULL; |
| 488 std::map<std::string, ChannelIDServiceJob*>::const_iterator j = | 488 std::map<std::string, ChannelIDServiceJob*>::const_iterator j = |
| 489 inflight_.find(domain); | 489 inflight_.find(domain); |
| 490 if (j != inflight_.end()) { | 490 if (j != inflight_.end()) { |
| 491 // A request for the same domain is in flight already. We'll attach our | 491 // A request for the same domain is in flight already. We'll attach our |
| 492 // callback, but we'll also mark it as requiring a channel ID if one's | 492 // callback, but we'll also mark it as requiring a channel ID if one's |
| 493 // mising. | 493 // mising. |
| 494 job = j->second; | 494 job = j->second; |
| 495 inflight_joins_++; | 495 inflight_joins_++; |
| 496 | 496 |
| 497 job->AddRequest(out_req, create_if_missing); | 497 job->AddRequest(out_req, create_if_missing); |
| 498 out_req->RequestStarted(this, request_start, callback, key, job); | 498 out_req->RequestStarted(this, request_start, callback, key, job); |
| 499 return true; | 499 return true; |
| 500 } | 500 } |
| 501 return false; | 501 return false; |
| 502 } | 502 } |
| 503 | 503 |
| 504 int ChannelIDService::LookupChannelID(const base::TimeTicks& request_start, | 504 int ChannelIDService::LookupChannelID( |
| 505 const std::string& domain, | 505 const base::TimeTicks& request_start, |
| 506 scoped_ptr<crypto::ECPrivateKey>* key, | 506 const std::string& domain, |
| 507 bool create_if_missing, | 507 std::unique_ptr<crypto::ECPrivateKey>* key, |
| 508 const CompletionCallback& callback, | 508 bool create_if_missing, |
| 509 Request* out_req) { | 509 const CompletionCallback& callback, |
| 510 Request* out_req) { |
| 510 // Check if a channel ID key already exists for this domain. | 511 // Check if a channel ID key already exists for this domain. |
| 511 int err = channel_id_store_->GetChannelID( | 512 int err = channel_id_store_->GetChannelID( |
| 512 domain, key, base::Bind(&ChannelIDService::GotChannelID, | 513 domain, key, base::Bind(&ChannelIDService::GotChannelID, |
| 513 weak_ptr_factory_.GetWeakPtr())); | 514 weak_ptr_factory_.GetWeakPtr())); |
| 514 | 515 |
| 515 if (err == OK) { | 516 if (err == OK) { |
| 516 // Sync lookup found a valid channel ID. | 517 // Sync lookup found a valid channel ID. |
| 517 DVLOG(1) << "Channel ID store had valid key for " << domain; | 518 DVLOG(1) << "Channel ID store had valid key for " << domain; |
| 518 key_store_hits_++; | 519 key_store_hits_++; |
| 519 RecordGetChannelIDResult(SYNC_SUCCESS); | 520 RecordGetChannelIDResult(SYNC_SUCCESS); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 534 } | 535 } |
| 535 | 536 |
| 536 return err; | 537 return err; |
| 537 } | 538 } |
| 538 | 539 |
| 539 int ChannelIDService::channel_id_count() { | 540 int ChannelIDService::channel_id_count() { |
| 540 return channel_id_store_->GetChannelIDCount(); | 541 return channel_id_store_->GetChannelIDCount(); |
| 541 } | 542 } |
| 542 | 543 |
| 543 } // namespace net | 544 } // namespace net |
| OLD | NEW |