| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/base/host_resolver_impl.h" | 5 #include "net/base/host_resolver_impl.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <ws2tcpip.h> | 8 #include <ws2tcpip.h> |
| 9 #include <wspiapi.h> // Needed for Win2k compat. | 9 #include <wspiapi.h> // Needed for Win2k compat. |
| 10 #elif defined(OS_POSIX) | 10 #elif defined(OS_POSIX) |
| 11 #include <netdb.h> | 11 #include <netdb.h> |
| 12 #include <sys/socket.h> | 12 #include <sys/socket.h> |
| 13 #endif | 13 #endif |
| 14 #if defined(OS_LINUX) | 14 #if defined(OS_LINUX) |
| 15 #include <resolv.h> | 15 #include <resolv.h> |
| 16 #endif | 16 #endif |
| 17 | 17 |
| 18 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
| 19 #include "base/debug_util.h" | 19 #include "base/debug_util.h" |
| 20 #include "base/message_loop.h" | 20 #include "base/message_loop.h" |
| 21 #include "base/stl_util-inl.h" | 21 #include "base/stl_util-inl.h" |
| 22 #include "base/string_util.h" | 22 #include "base/string_util.h" |
| 23 #include "base/time.h" | 23 #include "base/time.h" |
| 24 #include "base/worker_pool.h" | 24 #include "base/worker_pool.h" |
| 25 #include "net/base/address_list.h" | 25 #include "net/base/address_list.h" |
| 26 #include "net/base/host_resolver_proc.h" | 26 #include "net/base/host_resolver_proc.h" |
| 27 #include "net/base/load_log.h" |
| 27 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 28 | 29 |
| 29 #if defined(OS_WIN) | 30 #if defined(OS_WIN) |
| 30 #include "net/base/winsock_init.h" | 31 #include "net/base/winsock_init.h" |
| 31 #endif | 32 #endif |
| 32 | 33 |
| 33 namespace net { | 34 namespace net { |
| 34 | 35 |
| 35 HostResolver* CreateSystemHostResolver() { | 36 HostResolver* CreateSystemHostResolver() { |
| 36 static const size_t kMaxHostCacheEntries = 100; | 37 static const size_t kMaxHostCacheEntries = 100; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 47 } else { | 48 } else { |
| 48 // Use the system procedure (getaddrinfo). | 49 // Use the system procedure (getaddrinfo). |
| 49 return SystemHostResolverProc(host, out); | 50 return SystemHostResolverProc(host, out); |
| 50 } | 51 } |
| 51 } | 52 } |
| 52 | 53 |
| 53 //----------------------------------------------------------------------------- | 54 //----------------------------------------------------------------------------- |
| 54 | 55 |
| 55 class HostResolverImpl::Request { | 56 class HostResolverImpl::Request { |
| 56 public: | 57 public: |
| 57 Request(int id, const RequestInfo& info, CompletionCallback* callback, | 58 Request(LoadLog* load_log, |
| 59 int id, |
| 60 const RequestInfo& info, |
| 61 CompletionCallback* callback, |
| 58 AddressList* addresses) | 62 AddressList* addresses) |
| 59 : id_(id), info_(info), job_(NULL), callback_(callback), | 63 : load_log_(load_log), |
| 60 addresses_(addresses) {} | 64 id_(id), |
| 65 info_(info), |
| 66 job_(NULL), |
| 67 callback_(callback), |
| 68 addresses_(addresses) { |
| 69 } |
| 61 | 70 |
| 62 // Mark the request as cancelled. | 71 // Mark the request as cancelled. |
| 63 void MarkAsCancelled() { | 72 void MarkAsCancelled() { |
| 64 job_ = NULL; | 73 job_ = NULL; |
| 65 callback_ = NULL; | 74 callback_ = NULL; |
| 66 addresses_ = NULL; | 75 addresses_ = NULL; |
| 67 } | 76 } |
| 68 | 77 |
| 69 bool was_cancelled() const { | 78 bool was_cancelled() const { |
| 70 return callback_ == NULL; | 79 return callback_ == NULL; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 83 } | 92 } |
| 84 | 93 |
| 85 int port() const { | 94 int port() const { |
| 86 return info_.port(); | 95 return info_.port(); |
| 87 } | 96 } |
| 88 | 97 |
| 89 Job* job() const { | 98 Job* job() const { |
| 90 return job_; | 99 return job_; |
| 91 } | 100 } |
| 92 | 101 |
| 102 LoadLog* load_log() const { |
| 103 return load_log_; |
| 104 } |
| 105 |
| 93 int id() const { | 106 int id() const { |
| 94 return id_; | 107 return id_; |
| 95 } | 108 } |
| 96 | 109 |
| 97 const RequestInfo& info() const { | 110 const RequestInfo& info() const { |
| 98 return info_; | 111 return info_; |
| 99 } | 112 } |
| 100 | 113 |
| 101 private: | 114 private: |
| 115 scoped_refptr<LoadLog> load_log_; |
| 116 |
| 102 // Unique ID for this request. Used by observers to identify requests. | 117 // Unique ID for this request. Used by observers to identify requests. |
| 103 int id_; | 118 int id_; |
| 104 | 119 |
| 105 // The request info that started the request. | 120 // The request info that started the request. |
| 106 RequestInfo info_; | 121 RequestInfo info_; |
| 107 | 122 |
| 108 // The resolve job (running in worker pool) that this request is dependent on. | 123 // The resolve job (running in worker pool) that this request is dependent on. |
| 109 Job* job_; | 124 Job* job_; |
| 110 | 125 |
| 111 // The user's callback to invoke when the request completes. | 126 // The user's callback to invoke when the request completes. |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 const RequestInfo& info, | 308 const RequestInfo& info, |
| 294 AddressList* addresses, | 309 AddressList* addresses, |
| 295 CompletionCallback* callback, | 310 CompletionCallback* callback, |
| 296 RequestHandle* out_req) { | 311 RequestHandle* out_req) { |
| 297 if (shutdown_) | 312 if (shutdown_) |
| 298 return ERR_UNEXPECTED; | 313 return ERR_UNEXPECTED; |
| 299 | 314 |
| 300 // Choose a unique ID number for observers to see. | 315 // Choose a unique ID number for observers to see. |
| 301 int request_id = next_request_id_++; | 316 int request_id = next_request_id_++; |
| 302 | 317 |
| 303 // Notify registered observers. | 318 // Update the load log and notify registered observers. |
| 304 NotifyObserversStartRequest(request_id, info); | 319 OnStartRequest(load_log, request_id, info); |
| 305 | 320 |
| 306 // If we have an unexpired cache entry, use it. | 321 // If we have an unexpired cache entry, use it. |
| 307 if (info.allow_cached_response()) { | 322 if (info.allow_cached_response()) { |
| 308 const HostCache::Entry* cache_entry = cache_.Lookup( | 323 const HostCache::Entry* cache_entry = cache_.Lookup( |
| 309 info.hostname(), base::TimeTicks::Now()); | 324 info.hostname(), base::TimeTicks::Now()); |
| 310 if (cache_entry) { | 325 if (cache_entry) { |
| 311 addresses->SetFrom(cache_entry->addrlist, info.port()); | 326 addresses->SetFrom(cache_entry->addrlist, info.port()); |
| 312 int error = cache_entry->error; | 327 int error = cache_entry->error; |
| 313 | 328 |
| 314 // Notify registered observers. | 329 // Update the load log and notify registered observers. |
| 315 NotifyObserversFinishRequest(request_id, info, error); | 330 OnFinishRequest(load_log, request_id, info, error); |
| 316 | 331 |
| 317 return error; | 332 return error; |
| 318 } | 333 } |
| 319 } | 334 } |
| 320 | 335 |
| 321 // If no callback was specified, do a synchronous resolution. | 336 // If no callback was specified, do a synchronous resolution. |
| 322 if (!callback) { | 337 if (!callback) { |
| 323 AddressList addrlist; | 338 AddressList addrlist; |
| 324 int error = ResolveAddrInfo( | 339 int error = ResolveAddrInfo( |
| 325 effective_resolver_proc(), info.hostname(), &addrlist); | 340 effective_resolver_proc(), info.hostname(), &addrlist); |
| 326 if (error == OK) { | 341 if (error == OK) { |
| 327 addrlist.SetPort(info.port()); | 342 addrlist.SetPort(info.port()); |
| 328 *addresses = addrlist; | 343 *addresses = addrlist; |
| 329 } | 344 } |
| 330 | 345 |
| 331 // Write to cache. | 346 // Write to cache. |
| 332 cache_.Set(info.hostname(), error, addrlist, base::TimeTicks::Now()); | 347 cache_.Set(info.hostname(), error, addrlist, base::TimeTicks::Now()); |
| 333 | 348 |
| 334 // Notify registered observers. | 349 // Update the load log and notify registered observers. |
| 335 NotifyObserversFinishRequest(request_id, info, error); | 350 OnFinishRequest(load_log, request_id, info, error); |
| 336 | 351 |
| 337 return error; | 352 return error; |
| 338 } | 353 } |
| 339 | 354 |
| 340 // Create a handle for this request, and pass it back to the user if they | 355 // Create a handle for this request, and pass it back to the user if they |
| 341 // asked for it (out_req != NULL). | 356 // asked for it (out_req != NULL). |
| 342 Request* req = new Request(request_id, info, callback, addresses); | 357 Request* req = new Request(load_log, request_id, info, callback, addresses); |
| 343 if (out_req) | 358 if (out_req) |
| 344 *out_req = reinterpret_cast<RequestHandle>(req); | 359 *out_req = reinterpret_cast<RequestHandle>(req); |
| 345 | 360 |
| 346 // Next we need to attach our request to a "job". This job is responsible for | 361 // Next we need to attach our request to a "job". This job is responsible for |
| 347 // calling "getaddrinfo(hostname)" on a worker thread. | 362 // calling "getaddrinfo(hostname)" on a worker thread. |
| 348 scoped_refptr<Job> job; | 363 scoped_refptr<Job> job; |
| 349 | 364 |
| 350 // If there is already an outstanding job to resolve |info.hostname()|, use | 365 // If there is already an outstanding job to resolve |info.hostname()|, use |
| 351 // it. This prevents starting concurrent resolves for the same hostname. | 366 // it. This prevents starting concurrent resolves for the same hostname. |
| 352 job = FindOutstandingJob(info.hostname()); | 367 job = FindOutstandingJob(info.hostname()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 375 // |req_handle| is already cancelled. | 390 // |req_handle| is already cancelled. |
| 376 LOG(ERROR) << "Called HostResolverImpl::CancelRequest() after Shutdown()."; | 391 LOG(ERROR) << "Called HostResolverImpl::CancelRequest() after Shutdown()."; |
| 377 StackTrace().PrintBacktrace(); | 392 StackTrace().PrintBacktrace(); |
| 378 return; | 393 return; |
| 379 } | 394 } |
| 380 Request* req = reinterpret_cast<Request*>(req_handle); | 395 Request* req = reinterpret_cast<Request*>(req_handle); |
| 381 DCHECK(req); | 396 DCHECK(req); |
| 382 DCHECK(req->job()); | 397 DCHECK(req->job()); |
| 383 // NULL out the fields of req, to mark it as cancelled. | 398 // NULL out the fields of req, to mark it as cancelled. |
| 384 req->MarkAsCancelled(); | 399 req->MarkAsCancelled(); |
| 385 NotifyObserversCancelRequest(req->id(), req->info()); | 400 OnCancelRequest(req->load_log(), req->id(), req->info()); |
| 386 } | 401 } |
| 387 | 402 |
| 388 void HostResolverImpl::AddObserver(Observer* observer) { | 403 void HostResolverImpl::AddObserver(Observer* observer) { |
| 389 observers_.push_back(observer); | 404 observers_.push_back(observer); |
| 390 } | 405 } |
| 391 | 406 |
| 392 void HostResolverImpl::RemoveObserver(Observer* observer) { | 407 void HostResolverImpl::RemoveObserver(Observer* observer) { |
| 393 ObserversList::iterator it = | 408 ObserversList::iterator it = |
| 394 std::find(observers_.begin(), observers_.end(), observer); | 409 std::find(observers_.begin(), observers_.end(), observer); |
| 395 | 410 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 DCHECK(!cur_completing_job_); | 457 DCHECK(!cur_completing_job_); |
| 443 cur_completing_job_ = job; | 458 cur_completing_job_ = job; |
| 444 | 459 |
| 445 // Complete all of the requests that were attached to the job. | 460 // Complete all of the requests that were attached to the job. |
| 446 for (RequestsList::const_iterator it = job->requests().begin(); | 461 for (RequestsList::const_iterator it = job->requests().begin(); |
| 447 it != job->requests().end(); ++it) { | 462 it != job->requests().end(); ++it) { |
| 448 Request* req = *it; | 463 Request* req = *it; |
| 449 if (!req->was_cancelled()) { | 464 if (!req->was_cancelled()) { |
| 450 DCHECK_EQ(job, req->job()); | 465 DCHECK_EQ(job, req->job()); |
| 451 | 466 |
| 452 // Notify registered observers. | 467 // Update the load log and notify registered observers. |
| 453 NotifyObserversFinishRequest(req->id(), req->info(), error); | 468 OnFinishRequest(req->load_log(), req->id(), req->info(), error); |
| 454 | 469 |
| 455 req->OnComplete(error, addrlist); | 470 req->OnComplete(error, addrlist); |
| 456 | 471 |
| 457 // Check if the job was cancelled as a result of running the callback. | 472 // Check if the job was cancelled as a result of running the callback. |
| 458 // (Meaning that |this| was deleted). | 473 // (Meaning that |this| was deleted). |
| 459 if (job->was_cancelled()) | 474 if (job->was_cancelled()) |
| 460 return; | 475 return; |
| 461 } | 476 } |
| 462 } | 477 } |
| 463 | 478 |
| 464 cur_completing_job_ = NULL; | 479 cur_completing_job_ = NULL; |
| 465 } | 480 } |
| 466 | 481 |
| 467 void HostResolverImpl::NotifyObserversStartRequest(int request_id, | 482 void HostResolverImpl::OnStartRequest(LoadLog* load_log, |
| 468 const RequestInfo& info) { | 483 int request_id, |
| 469 for (ObserversList::iterator it = observers_.begin(); | 484 const RequestInfo& info) { |
| 470 it != observers_.end(); ++it) { | 485 LoadLog::BeginEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); |
| 471 (*it)->OnStartResolution(request_id, info); | 486 |
| 487 // Notify the observers of the start. |
| 488 if (!observers_.empty()) { |
| 489 LoadLog::BeginEvent( |
| 490 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART); |
| 491 |
| 492 for (ObserversList::iterator it = observers_.begin(); |
| 493 it != observers_.end(); ++it) { |
| 494 (*it)->OnStartResolution(request_id, info); |
| 495 } |
| 496 |
| 497 LoadLog::EndEvent( |
| 498 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART); |
| 472 } | 499 } |
| 473 } | 500 } |
| 474 | 501 |
| 475 void HostResolverImpl::NotifyObserversFinishRequest(int request_id, | 502 void HostResolverImpl::OnFinishRequest(LoadLog* load_log, |
| 476 const RequestInfo& info, | 503 int request_id, |
| 477 int error) { | 504 const RequestInfo& info, |
| 478 bool was_resolved = error == OK; | 505 int error) { |
| 479 for (ObserversList::iterator it = observers_.begin(); | 506 // Notify the observers of the completion. |
| 480 it != observers_.end(); ++it) { | 507 if (!observers_.empty()) { |
| 481 (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info); | 508 LoadLog::BeginEvent( |
| 509 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH); |
| 510 |
| 511 bool was_resolved = error == OK; |
| 512 for (ObserversList::iterator it = observers_.begin(); |
| 513 it != observers_.end(); ++it) { |
| 514 (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info); |
| 515 } |
| 516 |
| 517 LoadLog::EndEvent( |
| 518 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH); |
| 482 } | 519 } |
| 520 |
| 521 LoadLog::EndEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); |
| 483 } | 522 } |
| 484 | 523 |
| 485 void HostResolverImpl::NotifyObserversCancelRequest(int request_id, | 524 void HostResolverImpl::OnCancelRequest(LoadLog* load_log, |
| 486 const RequestInfo& info) { | 525 int request_id, |
| 487 for (ObserversList::iterator it = observers_.begin(); | 526 const RequestInfo& info) { |
| 488 it != observers_.end(); ++it) { | 527 LoadLog::AddEvent(load_log, LoadLog::TYPE_CANCELLED); |
| 489 (*it)->OnCancelResolution(request_id, info); | 528 |
| 529 // Notify the observers of the cancellation. |
| 530 if (!observers_.empty()) { |
| 531 LoadLog::BeginEvent( |
| 532 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL); |
| 533 |
| 534 for (ObserversList::iterator it = observers_.begin(); |
| 535 it != observers_.end(); ++it) { |
| 536 (*it)->OnCancelResolution(request_id, info); |
| 537 } |
| 538 |
| 539 LoadLog::EndEvent( |
| 540 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL); |
| 490 } | 541 } |
| 542 |
| 543 LoadLog::EndEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); |
| 491 } | 544 } |
| 492 | 545 |
| 493 } // namespace net | 546 } // namespace net |
| OLD | NEW |