Some additional network settings cleanup
[chromium-blink-merge.git] / chromeos / network / host_resolver_impl_chromeos.cc
blob57e0c442938fc604739662a256ca7ed36e6a7278
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
3 // found in the LICENSE file.
5 #include "chromeos/network/host_resolver_impl_chromeos.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "base/sys_info.h"
9 #include "base/values.h"
10 #include "chromeos/network/device_state.h"
11 #include "chromeos/network/network_handler.h"
12 #include "chromeos/network/network_state.h"
13 #include "chromeos/network/network_state_handler.h"
14 #include "chromeos/network/network_state_handler_observer.h"
15 #include "net/base/address_list.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/net_util.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
20 namespace chromeos {
22 // HostResolverImplChromeOS::NetworkStateHandlerObserver
24 // An instance of this class is created on the NetworkHandler (UI) thread and
25 // manages its own lifetime, destroying itself when NetworkStateHandlerObserver
26 // ::IsShuttingDown() gets called.
28 class HostResolverImplChromeOS::NetworkObserver
29 : public chromeos::NetworkStateHandlerObserver {
30 public:
31 static void Create(
32 const base::WeakPtr<HostResolverImplChromeOS>& resolver,
33 scoped_refptr<base::MessageLoopProxy> resolver_message_loop,
34 NetworkStateHandler* network_state_handler) {
35 new NetworkObserver(resolver, resolver_message_loop, network_state_handler);
38 NetworkObserver(const base::WeakPtr<HostResolverImplChromeOS>& resolver,
39 scoped_refptr<base::MessageLoopProxy> resolver_message_loop,
40 NetworkStateHandler* network_state_handler)
41 : resolver_(resolver),
42 resolver_message_loop_(resolver_message_loop),
43 network_state_handler_(network_state_handler),
44 weak_ptr_factory_resolver_thread_(this) {
45 network_state_handler_->AddObserver(this, FROM_HERE);
46 DefaultNetworkChanged(network_state_handler_->DefaultNetwork());
49 private:
50 virtual ~NetworkObserver() {
51 network_state_handler_->RemoveObserver(this, FROM_HERE);
54 // NetworkStateHandlerObserver
55 virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE {
56 if (!network) {
57 DVLOG(2) << "DefaultNetworkChanged: No Network.";
58 CallResolverSetIpAddress("", "");
59 return;
61 std::string ipv4_address, ipv6_address;
62 const DeviceState* device_state =
63 network_state_handler_->GetDeviceState(network->device_path());
64 if (!device_state) {
65 LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
66 << "DefaultNetworkChanged: Network missing device: "
67 << network->path();
68 CallResolverSetIpAddress("", "");
69 return;
71 for (base::DictionaryValue::Iterator iter(device_state->ip_configs());
72 !iter.IsAtEnd(); iter.Advance()) {
73 const base::DictionaryValue* ip_config;
74 if (!iter.value().GetAsDictionary(&ip_config)) {
75 LOG(ERROR) << "Badly formatted IPConfigs: " << network->path();
76 continue;
78 std::string method, address;
79 if (ip_config->GetString(shill::kMethodProperty, &method) &&
80 ip_config->GetString(shill::kAddressProperty, &address)) {
81 if (method == shill::kTypeIPv4 || method == shill::kTypeDHCP)
82 ipv4_address = address;
83 else if (method == shill::kTypeIPv6 || method == shill::kTypeDHCP6)
84 ipv6_address = address;
85 } else {
86 LOG(ERROR) << "DefaultNetworkChanged: IPConfigs missing properties: "
87 << network->path();
90 DVLOG(2) << "DefaultNetworkChanged: " << network->name()
91 << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
92 CallResolverSetIpAddress(ipv4_address, ipv6_address);
95 virtual void IsShuttingDown() OVERRIDE {
96 delete this;
99 void CallResolverSetIpAddress(const std::string& ipv4_address,
100 const std::string& ipv6_address) {
101 resolver_message_loop_->PostTask(
102 FROM_HERE,
103 base::Bind(&NetworkObserver::SetIpAddressOnResolverThread,
104 weak_ptr_factory_resolver_thread_.GetWeakPtr(),
105 ipv4_address, ipv6_address));
108 void SetIpAddressOnResolverThread(const std::string& ipv4_address,
109 const std::string& ipv6_address) {
110 if (resolver_)
111 resolver_->SetIPAddresses(ipv4_address, ipv6_address);
114 base::WeakPtr<HostResolverImplChromeOS> resolver_;
115 scoped_refptr<base::MessageLoopProxy> resolver_message_loop_;
116 NetworkStateHandler* network_state_handler_;
117 base::WeakPtrFactory<NetworkObserver> weak_ptr_factory_resolver_thread_;
119 DISALLOW_COPY_AND_ASSIGN(NetworkObserver);
122 // HostResolverImplChromeOS
124 HostResolverImplChromeOS::HostResolverImplChromeOS(
125 scoped_refptr<base::MessageLoopProxy> network_handler_message_loop,
126 NetworkStateHandler* network_state_handler,
127 const Options& options,
128 net::NetLog* net_log)
129 : HostResolverImpl(options, net_log),
130 network_handler_message_loop_(network_handler_message_loop),
131 weak_ptr_factory_(this) {
132 network_handler_message_loop->PostTask(
133 FROM_HERE,
134 base::Bind(&NetworkObserver::Create,
135 weak_ptr_factory_.GetWeakPtr(),
136 base::MessageLoopProxy::current(),
137 network_state_handler));
140 HostResolverImplChromeOS::~HostResolverImplChromeOS() {
143 int HostResolverImplChromeOS::Resolve(const RequestInfo& info,
144 net::RequestPriority priority,
145 net::AddressList* addresses,
146 const net::CompletionCallback& callback,
147 RequestHandle* out_req,
148 const net::BoundNetLog& source_net_log) {
149 DCHECK(thread_checker_.CalledOnValidThread());
150 if (ResolveLocalIPAddress(info, addresses))
151 return net::OK;
152 return net::HostResolverImpl::Resolve(
153 info, priority, addresses, callback, out_req, source_net_log);
156 void HostResolverImplChromeOS::SetIPAddresses(const std::string& ipv4_address,
157 const std::string& ipv6_address) {
158 DCHECK(thread_checker_.CalledOnValidThread());
159 ipv4_address_ = ipv4_address;
160 ipv6_address_ = ipv6_address;
163 bool HostResolverImplChromeOS::ResolveLocalIPAddress(
164 const RequestInfo& info,
165 net::AddressList* addresses) {
166 DCHECK(thread_checker_.CalledOnValidThread());
167 if (!info.is_my_ip_address() || ipv4_address_.empty())
168 return false;
170 // Use IPConfig data for localhost address lookup.
171 addresses->clear();
173 if (info.address_family() != net::ADDRESS_FAMILY_IPV4 &&
174 !ipv6_address_.empty()) {
175 net::IPAddressNumber ipv6;
176 if (net::ParseIPLiteralToNumber(ipv6_address_, &ipv6))
177 addresses->push_back(net::IPEndPoint(ipv6, 0));
180 net::IPAddressNumber ipv4;
181 if (net::ParseIPLiteralToNumber(ipv4_address_, &ipv4))
182 addresses->push_back(net::IPEndPoint(ipv4, 0));
184 DVLOG(2) << "ResolveLocalIPAddress("
185 << static_cast<int>(info.address_family()) << "): "
186 << addresses->size()
187 << " IPv4: " << ipv4_address_ << " IPv6: " << ipv6_address_;
188 addresses->SetDefaultCanonicalName();
189 return true;
192 // static
193 scoped_ptr<net::HostResolver> HostResolverImplChromeOS::CreateSystemResolver(
194 const Options& options,
195 net::NetLog* net_log) {
196 return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
197 NetworkHandler::Get()->message_loop(),
198 NetworkHandler::Get()->network_state_handler(),
199 options,
200 net_log));
203 // static
204 scoped_ptr<net::HostResolver>
205 HostResolverImplChromeOS::CreateHostResolverForTest(
206 scoped_refptr<base::MessageLoopProxy> network_handler_message_loop,
207 NetworkStateHandler* network_state_handler) {
208 Options options;
209 return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
210 network_handler_message_loop,
211 network_state_handler,
212 options,
213 NULL));
216 } // namespace chromeos