| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "mojo/services/network/host_resolver_impl.h" |
| |
| #include "mojo/services/network/net_adapters.h" |
| #include "mojo/services/network/net_address_type_converters.h" |
| #include "net/base/address_family.h" |
| #include "net/base/address_list.h" |
| #include "net/base/host_port_pair.h" |
| #include "net/base/net_errors.h" |
| #include "net/dns/host_resolver.h" |
| #include "third_party/mojo/src/mojo/public/cpp/bindings/array.h" |
| |
| namespace mojo { |
| namespace { |
| |
| class HostResolverImplJob { |
| public: |
| // After creating a HostResolverImplJob, |Start| must be called. |
| HostResolverImplJob(net::HostResolver::RequestInfo request_info, |
| const HostResolver::GetHostAddressesCallback& callback) |
| : callback_(callback), |
| request_info_(request_info) { |
| } |
| |
| // You are required to call |Start|. The object will automatically be deleted |
| // when OnResolveDone is called. |
| void Start(net::HostResolver* resolver) { |
| DCHECK(resolver); |
| net::BoundNetLog net_log; |
| int result = resolver->Resolve( |
| request_info_, |
| net::DEFAULT_PRIORITY, |
| &addresses_, |
| base::Bind(&HostResolverImplJob::OnResolveDone, base::Unretained(this)), |
| &handle_, |
| net_log); |
| if (result == net::ERR_IO_PENDING) { |
| return; |
| } |
| // Synchronous result. |
| OnResolveDone(result); |
| } |
| |
| private: |
| ~HostResolverImplJob() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| } |
| |
| void OnResolveDone(int result) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| Array<NetAddressPtr> net_addresses; |
| if (result == net::OK) { |
| for (size_t i = 0; i < addresses_.size(); i++) { |
| net_addresses.push_back(NetAddress::From(addresses_[i])); |
| } |
| } |
| callback_.Run(MakeNetworkError(result), net_addresses.Pass()); |
| delete this; |
| } |
| |
| HostResolver::GetHostAddressesCallback callback_; |
| |
| net::HostResolver::RequestInfo request_info_; |
| net::HostResolver::RequestHandle handle_; |
| net::AddressList addresses_; |
| base::ThreadChecker thread_checker_; |
| |
| DISALLOW_COPY_AND_ASSIGN(HostResolverImplJob); |
| }; |
| |
| } // namespace |
| |
| HostResolverImpl::HostResolverImpl(InterfaceRequest<HostResolver> request) |
| : binding_(this, request.Pass()), |
| resolver_(net::HostResolver::CreateDefaultResolver(nullptr).Pass()) { |
| DCHECK(resolver_); |
| } |
| |
| HostResolverImpl::~HostResolverImpl() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| } |
| |
| static net::AddressFamily ConvertFamily(NetAddressFamily family) { |
| switch (family) { |
| case NetAddressFamily::UNSPECIFIED: |
| return net::ADDRESS_FAMILY_UNSPECIFIED; |
| case NetAddressFamily::IPV4: |
| return net::ADDRESS_FAMILY_IPV4; |
| case NetAddressFamily::IPV6: |
| return net::ADDRESS_FAMILY_IPV6; |
| default: |
| NOTREACHED(); |
| return net::ADDRESS_FAMILY_UNSPECIFIED; |
| } |
| } |
| |
| void HostResolverImpl::GetHostAddresses(const mojo::String& host, |
| NetAddressFamily family, |
| const GetHostAddressesCallback& callback) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| net::HostPortPair host_port_pair(host, 0); |
| net::HostResolver::RequestInfo request_info(host_port_pair); |
| request_info.set_address_family(ConvertFamily(family)); |
| HostResolverImplJob* job = new HostResolverImplJob(request_info, callback); |
| job->Start(resolver_.get()); |
| } |
| |
| } // namespace mojo |