diff options
Diffstat (limited to 'net/base/host_resolver_impl.cc')
-rw-r--r-- | net/base/host_resolver_impl.cc | 236 |
1 files changed, 182 insertions, 54 deletions
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc index 11d9306..f4f7bbd 100644 --- a/net/base/host_resolver_impl.cc +++ b/net/base/host_resolver_impl.cc @@ -27,9 +27,11 @@ #include "base/values.h" #include "base/worker_pool.h" #include "net/base/address_list.h" +#include "net/base/address_list_net_log_param.h" +#include "net/base/host_port_pair.h" #include "net/base/host_resolver_proc.h" -#include "net/base/net_log.h" #include "net/base/net_errors.h" +#include "net/base/net_log.h" #include "net/base/net_util.h" #if defined(OS_WIN) @@ -53,7 +55,8 @@ HostCache* CreateDefaultCache() { } // anonymous namespace -HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves) { +HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, + NetLog* net_log) { // Maximum of 50 concurrent threads. // TODO(eroman): Adjust this, do some A/B experiments. static const size_t kDefaultMaxJobs = 50u; @@ -63,7 +66,7 @@ HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves) { HostResolverImpl* resolver = new HostResolverImpl(NULL, CreateDefaultCache(), - max_concurrent_resolves); + max_concurrent_resolves, net_log); return resolver; } @@ -88,16 +91,14 @@ static int ResolveAddrInfo(HostResolverProc* resolver_proc, // Extra parameters to attach to the NetLog when the resolve failed. class HostResolveFailedParams : public NetLog::EventParameters { public: - HostResolveFailedParams(int net_error, int os_error, bool was_from_cache) + HostResolveFailedParams(int net_error, int os_error) : net_error_(net_error), - os_error_(os_error), - was_from_cache_(was_from_cache) { + os_error_(os_error) { } virtual Value* ToValue() const { DictionaryValue* dict = new DictionaryValue(); dict->SetInteger("net_error", net_error_); - dict->SetBoolean("was_from_cache", was_from_cache_); if (os_error_) { dict->SetInteger("os_error", os_error_); @@ -125,7 +126,53 @@ class HostResolveFailedParams : public NetLog::EventParameters { private: const int net_error_; const int os_error_; - const bool was_from_cache_; +}; + +// Parameters representing the information in a RequestInfo object, along with +// the associated NetLog::Source. +class RequestInfoParameters : public NetLog::EventParameters { + public: + RequestInfoParameters(const HostResolver::RequestInfo& info, + const NetLog::Source& source) + : info_(info), source_(source) {} + + virtual Value* ToValue() const { + DictionaryValue* dict = new DictionaryValue(); + dict->SetString("host", HostPortPair(info_.hostname(), + info_.port()).ToString()); + dict->SetInteger("address_family", + static_cast<int>(info_.address_family())); + dict->SetBoolean("allow_cached_response", info_.allow_cached_response()); + dict->SetBoolean("is_speculative", info_.is_speculative()); + dict->SetInteger("priority", info_.priority()); + + if (source_.is_valid()) + dict->Set("source_dependency", source_.ToValue()); + + return dict; + } + + private: + const HostResolver::RequestInfo info_; + const NetLog::Source source_; +}; + +// Parameters associated with the creation of a HostResolveImpl::Job. +class JobCreationParameters : public NetLog::EventParameters { + public: + JobCreationParameters(const std::string& host, const NetLog::Source& source) + : host_(host), source_(source) {} + + virtual Value* ToValue() const { + DictionaryValue* dict = new DictionaryValue(); + dict->SetString("host", host_); + dict->Set("source_dependency", source_.ToValue()); + return dict; + } + + private: + const std::string host_; + const NetLog::Source source_; }; // Gets a list of the likely error codes that getaddrinfo() can return @@ -176,12 +223,14 @@ std::vector<int> GetAllGetAddrinfoOSErrors() { class HostResolverImpl::Request { public: - Request(const BoundNetLog& net_log, + Request(const BoundNetLog& source_net_log, + const BoundNetLog& request_net_log, int id, const RequestInfo& info, CompletionCallback* callback, AddressList* addresses) - : net_log_(net_log), + : source_net_log_(source_net_log), + request_net_log_(request_net_log), id_(id), info_(info), job_(NULL), @@ -220,8 +269,12 @@ class HostResolverImpl::Request { return job_; } - const BoundNetLog& net_log() { - return net_log_; + const BoundNetLog& source_net_log() { + return source_net_log_; + } + + const BoundNetLog& request_net_log() { + return request_net_log_; } int id() const { @@ -233,7 +286,8 @@ class HostResolverImpl::Request { } private: - BoundNetLog net_log_; + BoundNetLog source_net_log_; + BoundNetLog request_net_log_; // Unique ID for this request. Used by observers to identify requests. int id_; @@ -260,20 +314,33 @@ class HostResolverImpl::Request { class HostResolverImpl::Job : public base::RefCountedThreadSafe<HostResolverImpl::Job> { public: - Job(int id, HostResolverImpl* resolver, const Key& key) - : id_(id), - key_(key), - resolver_(resolver), - origin_loop_(MessageLoop::current()), - resolver_proc_(resolver->effective_resolver_proc()), - error_(OK), - os_error_(0), - had_non_speculative_request_(false) { + Job(int id, + HostResolverImpl* resolver, + const Key& key, + const BoundNetLog& source_net_log, + NetLog* net_log) + : id_(id), + key_(key), + resolver_(resolver), + origin_loop_(MessageLoop::current()), + resolver_proc_(resolver->effective_resolver_proc()), + error_(OK), + os_error_(0), + had_non_speculative_request_(false), + net_log_(BoundNetLog::Make(net_log, + NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { + net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, + new JobCreationParameters(key.hostname, + source_net_log.source())); } // Attaches a request to this job. The job takes ownership of |req| and will // take care to delete it. void AddRequest(Request* req) { + req->request_net_log().BeginEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, + new NetLogSourceParameter("source_dependency", net_log_.source())); + req->set_job(this); requests_.push_back(req); @@ -301,6 +368,8 @@ class HostResolverImpl::Job // Cancels the current job. Callable from origin thread. void Cancel() { + net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); + HostResolver* resolver = resolver_; resolver_ = NULL; @@ -311,6 +380,10 @@ class HostResolverImpl::Job origin_loop_ = NULL; } + // End here to prevent issues when a Job outlives the HostResolver that + // spawned it. + net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, NULL); + // We will call HostResolverImpl::CancelRequest(Request*) on each one // in order to notify any observers. for (RequestsList::const_iterator it = requests_.begin(); @@ -412,6 +485,17 @@ class HostResolverImpl::Job if (was_cancelled()) return; + scoped_refptr<NetLog::EventParameters> params; + if (error_ != OK) { + params = new HostResolveFailedParams(error_, os_error_); + } else { + params = new AddressListNetLogParam(results_); + } + + // End here to prevent issues when a Job outlives the HostResolver that + // spawned it. + net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, params); + DCHECK(!requests_.empty()); // Use the port number of the first request. @@ -456,6 +540,8 @@ class HostResolverImpl::Job // The time when the job was started. base::TimeTicks start_time_; + BoundNetLog net_log_; + DISALLOW_COPY_AND_ASSIGN(Job); }; @@ -608,6 +694,10 @@ class HostResolverImpl::JobPool { // evicted from the queue, and returned. Otherwise returns NULL. The caller // is responsible for freeing the evicted request. Request* InsertPendingRequest(Request* req) { + req->request_net_log().BeginEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, + NULL); + PendingRequestsQueue& q = pending_requests_[req->info().priority()]; q.push_back(req); @@ -620,6 +710,10 @@ class HostResolverImpl::JobPool { if (!q.empty()) { Request* req = q.front(); q.pop_front(); + req->request_net_log().AddEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE_EVICTED, NULL); + req->request_net_log().EndEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); return req; } } @@ -635,6 +729,8 @@ class HostResolverImpl::JobPool { PendingRequestsQueue::iterator it = std::find(q.begin(), q.end(), req); DCHECK(it != q.end()); q.erase(it); + req->request_net_log().EndEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); } // Removes and returns the highest priority pending request. @@ -646,6 +742,8 @@ class HostResolverImpl::JobPool { if (!q.empty()) { Request* req = q.front(); q.pop_front(); + req->request_net_log().EndEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); return req; } } @@ -709,7 +807,8 @@ class HostResolverImpl::JobPool { HostResolverImpl::HostResolverImpl( HostResolverProc* resolver_proc, HostCache* cache, - size_t max_jobs) + size_t max_jobs, + NetLog* net_log) : cache_(cache), max_jobs_(max_jobs), next_request_id_(0), @@ -718,7 +817,8 @@ HostResolverImpl::HostResolverImpl( default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), shutdown_(false), ipv6_probe_monitoring_(false), - additional_resolver_flags_(0) { + additional_resolver_flags_(0), + net_log_(net_log) { DCHECK_GT(max_jobs, 0u); // It is cumbersome to expose all of the constraints in the constructor, @@ -758,7 +858,7 @@ int HostResolverImpl::Resolve(const RequestInfo& info, AddressList* addresses, CompletionCallback* callback, RequestHandle* out_req, - const BoundNetLog& net_log) { + const BoundNetLog& source_net_log) { DCHECK(CalledOnValidThread()); if (shutdown_) @@ -767,8 +867,12 @@ int HostResolverImpl::Resolve(const RequestInfo& info, // Choose a unique ID number for observers to see. int request_id = next_request_id_++; + // Make a log item for the request. + BoundNetLog request_net_log = BoundNetLog::Make(net_log_, + NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); + // Update the net log and notify registered observers. - OnStartRequest(net_log, request_id, info); + OnStartRequest(source_net_log, request_net_log, request_id, info); // Check for IP literal. IPAddressNumber ip_number; @@ -781,9 +885,8 @@ int HostResolverImpl::Resolve(const RequestInfo& info, *addresses = result; // Update the net log and notify registered observers. - OnFinishRequest(net_log, request_id, info, OK, - 0, /* os_error (unknown since from cache) */ - false /* was_from_cache */); + OnFinishRequest(source_net_log, request_net_log, request_id, info, OK, + 0 /* os_error (unknown since from cache) */); return OK; } @@ -796,14 +899,15 @@ int HostResolverImpl::Resolve(const RequestInfo& info, const HostCache::Entry* cache_entry = cache_->Lookup( key, base::TimeTicks::Now()); if (cache_entry) { + request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); int net_error = cache_entry->error; if (net_error == OK) addresses->SetFrom(cache_entry->addrlist, info.port()); // Update the net log and notify registered observers. - OnFinishRequest(net_log, request_id, info, net_error, - 0, /* os_error (unknown since from cache) */ - true /* was_from_cache */); + OnFinishRequest(source_net_log, request_net_log, request_id, info, + net_error, + 0 /* os_error (unknown since from cache) */); return net_error; } @@ -826,15 +930,16 @@ int HostResolverImpl::Resolve(const RequestInfo& info, cache_->Set(key, error, addrlist, base::TimeTicks::Now()); // Update the net log and notify registered observers. - OnFinishRequest(net_log, request_id, info, error, os_error, - false /* was_from_cache */); + OnFinishRequest(source_net_log, request_net_log, request_id, info, error, + os_error); return error; } // Create a handle for this request, and pass it back to the user if they // asked for it (out_req != NULL). - Request* req = new Request(net_log, request_id, info, callback, addresses); + Request* req = new Request(source_net_log, request_net_log, request_id, info, + callback, addresses); if (out_req) *out_req = reinterpret_cast<RequestHandle>(req); @@ -885,11 +990,15 @@ void HostResolverImpl::CancelRequest(RequestHandle req_handle) { JobPool* pool = GetPoolForRequest(req); pool->RemovePendingRequest(req); request_deleter.reset(req); + } else { + req->request_net_log().EndEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, NULL); } // NULL out the fields of req, to mark it as cancelled. req->MarkAsCancelled(); - OnCancelRequest(req->net_log(), req->id(), req->info()); + OnCancelRequest(req->source_net_log(), req->request_net_log(), req->id(), + req->info()); } void HostResolverImpl::AddObserver(HostResolver::Observer* observer) { @@ -995,10 +1104,12 @@ void HostResolverImpl::OnJobComplete(Job* job, Request* req = *it; if (!req->was_cancelled()) { DCHECK_EQ(job, req->job()); + req->request_net_log().EndEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, NULL); // Update the net log and notify registered observers. - OnFinishRequest(req->net_log(), req->id(), req->info(), net_error, - os_error, false /* was_from_cache */); + OnFinishRequest(req->source_net_log(), req->request_net_log(), req->id(), + req->info(), net_error, os_error); req->OnComplete(net_error, addrlist); @@ -1012,10 +1123,17 @@ void HostResolverImpl::OnJobComplete(Job* job, cur_completing_job_ = NULL; } -void HostResolverImpl::OnStartRequest(const BoundNetLog& net_log, +void HostResolverImpl::OnStartRequest(const BoundNetLog& source_net_log, + const BoundNetLog& request_net_log, int request_id, const RequestInfo& info) { - net_log.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); + source_net_log.BeginEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL, + new NetLogSourceParameter("source_dependency", request_net_log.source())); + + request_net_log.BeginEvent( + NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, + new RequestInfoParameters(info, source_net_log.source())); // Notify the observers of the start. if (!observers_.empty()) { @@ -1026,12 +1144,12 @@ void HostResolverImpl::OnStartRequest(const BoundNetLog& net_log, } } -void HostResolverImpl::OnFinishRequest(const BoundNetLog& net_log, +void HostResolverImpl::OnFinishRequest(const BoundNetLog& source_net_log, + const BoundNetLog& request_net_log, int request_id, const RequestInfo& info, int net_error, - int os_error, - bool was_from_cache) { + int os_error) { bool was_resolved = net_error == OK; // Notify the observers of the completion. @@ -1042,18 +1160,21 @@ void HostResolverImpl::OnFinishRequest(const BoundNetLog& net_log, } } - // Log some extra parameters on failure. + // Log some extra parameters on failure for synchronous requests. scoped_refptr<NetLog::EventParameters> params; - if (!was_resolved) - params = new HostResolveFailedParams(net_error, os_error, was_from_cache); + if (!was_resolved) { + params = new HostResolveFailedParams(net_error, os_error); + } - net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, params); + request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, params); + source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); } -void HostResolverImpl::OnCancelRequest(const BoundNetLog& net_log, +void HostResolverImpl::OnCancelRequest(const BoundNetLog& source_net_log, + const BoundNetLog& request_net_log, int request_id, const RequestInfo& info) { - net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); + request_net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); // Notify the observers of the cancellation. if (!observers_.empty()) { @@ -1063,7 +1184,8 @@ void HostResolverImpl::OnCancelRequest(const BoundNetLog& net_log, } } - net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); + request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, NULL); + source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); } void HostResolverImpl::OnIPAddressChanged() { @@ -1160,10 +1282,16 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); Key key = GetEffectiveKeyForRequest(req->info()); - scoped_refptr<Job> job = new Job(next_job_id_++, this, key); + + req->request_net_log().AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, + NULL); + + scoped_refptr<Job> job = new Job(next_job_id_++, this, key, + req->request_net_log(), net_log_); job->AddRequest(req); AddOutstandingJob(job); job->Start(); + return job.get(); } @@ -1176,9 +1304,9 @@ int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) { Request* r = req_evicted_from_queue.get(); int error = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; - OnFinishRequest(r->net_log(), r->id(), r->info(), error, - 0, /* os_error (not applicable) */ - false /* was_from_cache */); + OnFinishRequest(r->source_net_log(), r->request_net_log(), r->id(), + r->info(), error, + 0 /* os_error (not applicable) */); if (r == req) return error; |