1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/dns/mojo_host_resolver_impl.h"
7 #include "base/basictypes.h"
8 #include "base/stl_util.h"
9 #include "net/base/address_list.h"
10 #include "net/base/net_errors.h"
11 #include "net/dns/host_resolver.h"
12 #include "net/dns/mojo_host_type_converters.h"
16 // Handles host resolution for a single request and sends a response when done.
17 // Also detects connection errors for HostResolverRequestClient and cancels the
18 // outstanding resolve request. Owned by MojoHostResolverImpl.
19 class MojoHostResolverImpl::Job
: public mojo::ErrorHandler
{
21 Job(MojoHostResolverImpl
* resolver_service
,
22 net::HostResolver
* resolver
,
23 const net::HostResolver::RequestInfo
& request_info
,
24 interfaces::HostResolverRequestClientPtr client
);
30 // Completion callback for the HostResolver::Resolve request.
31 void OnResolveDone(int result
);
33 // Overridden from mojo::ErrorHandler:
34 void OnConnectionError() override
;
36 MojoHostResolverImpl
* resolver_service_
;
37 net::HostResolver
* resolver_
;
38 net::HostResolver::RequestInfo request_info_
;
39 interfaces::HostResolverRequestClientPtr client_
;
40 net::HostResolver::RequestHandle handle_
;
42 base::ThreadChecker thread_checker_
;
45 MojoHostResolverImpl::MojoHostResolverImpl(net::HostResolver
* resolver
)
46 : resolver_(resolver
) {
49 MojoHostResolverImpl::~MojoHostResolverImpl() {
50 DCHECK(thread_checker_
.CalledOnValidThread());
51 STLDeleteElements(&pending_jobs_
);
54 void MojoHostResolverImpl::Resolve(
55 interfaces::HostResolverRequestInfoPtr request_info
,
56 interfaces::HostResolverRequestClientPtr client
) {
57 DCHECK(thread_checker_
.CalledOnValidThread());
58 Job
* job
= new Job(this, resolver_
,
59 request_info
->To
<net::HostResolver::RequestInfo
>(),
61 pending_jobs_
.insert(job
);
65 void MojoHostResolverImpl::DeleteJob(Job
* job
) {
66 DCHECK(thread_checker_
.CalledOnValidThread());
67 size_t num_erased
= pending_jobs_
.erase(job
);
72 MojoHostResolverImpl::Job::Job(
73 MojoHostResolverImpl
* resolver_service
,
74 net::HostResolver
* resolver
,
75 const net::HostResolver::RequestInfo
& request_info
,
76 interfaces::HostResolverRequestClientPtr client
)
77 : resolver_service_(resolver_service
),
79 request_info_(request_info
),
80 client_(client
.Pass()),
82 client_
.set_error_handler(this);
85 void MojoHostResolverImpl::Job::Start() {
86 DVLOG(1) << "Resolve " << request_info_
.host_port_pair().ToString();
89 resolver_
->Resolve(request_info_
, DEFAULT_PRIORITY
, &result_
,
90 base::Bind(&MojoHostResolverImpl::Job::OnResolveDone
,
91 base::Unretained(this)),
94 if (result
!= ERR_IO_PENDING
)
95 OnResolveDone(result
);
98 MojoHostResolverImpl::Job::~Job() {
99 DCHECK(thread_checker_
.CalledOnValidThread());
101 resolver_
->CancelRequest(handle_
);
104 void MojoHostResolverImpl::Job::OnResolveDone(int result
) {
105 DCHECK(thread_checker_
.CalledOnValidThread());
107 DVLOG(1) << "Resolved " << request_info_
.host_port_pair().ToString()
108 << " with error " << result
<< " and " << result_
.size()
110 for (const auto& address
: result_
) {
111 DVLOG(1) << address
.ToString();
114 client_
->ReportResult(result
, interfaces::AddressList::From(result_
));
116 client_
->ReportResult(result
, nullptr);
118 resolver_service_
->DeleteJob(this);
121 void MojoHostResolverImpl::Job::OnConnectionError() {
122 DCHECK(thread_checker_
.CalledOnValidThread());
123 // |resolver_service_| should always outlive us.
124 DCHECK(resolver_service_
);
125 DVLOG(1) << "Connection error on request for "
126 << request_info_
.host_port_pair().ToString();
127 resolver_service_
->DeleteJob(this);