Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: chromeos/network/host_resolver_impl_chromeos.cc

Issue 238433003: Provide Shill IP Address to myIpAddress() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add unit test Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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.
4
5 #include "chromeos/network/host_resolver_impl_chromeos.h"
6
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "base/values.h"
9 #include "chromeos/network/device_state.h"
10 #include "chromeos/network/network_handler.h"
11 #include "chromeos/network/network_state.h"
12 #include "chromeos/network/network_state_handler.h"
13 #include "chromeos/network/network_state_handler_observer.h"
14 #include "net/base/address_list.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/net_util.h"
17 #include "third_party/cros_system_api/dbus/service_constants.h"
18
19 // HostResolverImplChromeOS::NetworkStateHandlerObserver
20
21 using chromeos::DeviceState;
22 using chromeos::NetworkState;
23
24 class net::HostResolverImplChromeOS::NetworkObserver
25 : public chromeos::NetworkStateHandlerObserver {
26 public:
27 NetworkObserver(scoped_refptr<base::MessageLoopProxy> owner_message_loop,
28 chromeos::NetworkStateHandler* network_state_handler)
29 : owner_message_loop_(owner_message_loop),
30 network_state_handler_(network_state_handler),
31 weak_ptr_factory_owner_thread_(this) {
32 network_state_handler_->AddObserver(this, FROM_HERE);
33 DefaultNetworkChanged(network_state_handler_->DefaultNetwork());
34 }
35
36 virtual ~NetworkObserver() {
37 network_state_handler_->RemoveObserver(this, FROM_HERE);
38 }
39
40 // NetworkStateHandlerObserver
41 virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE {
42 if (!network) {
43 DVLOG(2) << "DefaultNetworkChanged: No Network.";
44 CallSetIpAddressOnOwnerThread("", "");
45 return;
46 }
47 std::string ipv4_address, ipv6_address;
48 const DeviceState* device_state =
49 network_state_handler_->GetDeviceState(network->device_path());
50 if (!device_state) {
51 LOG(ERROR) << "DefaultNetworkChanged: Network missing device: "
52 << network->path();
53 CallSetIpAddressOnOwnerThread("", "");
54 return;
55 }
56 for (base::DictionaryValue::Iterator iter(device_state->ip_configs());
57 !iter.IsAtEnd(); iter.Advance()) {
58 const base::DictionaryValue* ip_config;
59 if (!iter.value().GetAsDictionary(&ip_config)) {
60 LOG(ERROR) << "Badly formatted IPConfigs: " << network->path();
61 continue;
62 }
63 std::string method, address;
64 if (ip_config->GetString(shill::kMethodProperty, &method) &&
65 ip_config->GetString(shill::kAddressProperty, &address)) {
66 if (method == shill::kTypeIPv4 || method == shill::kTypeDHCP)
67 ipv4_address = address;
68 else if (method == shill::kTypeIPv6 || method == shill::kTypeDHCP6)
69 ipv6_address = address;
70 } else {
71 LOG(ERROR) << "DefaultNetworkChanged: IPConfigs missing properties: "
72 << network->path();
73 }
74 }
75 DVLOG(2) << "DefaultNetworkChanged: " << network->name()
76 << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
77 CallSetIpAddressOnOwnerThread(ipv4_address, ipv6_address);
78 }
79
80 // These may be safely accessed by the owner thread.
81 std::string ipv4_address() const {
82 return ipv4_address_;
83 }
84 std::string ipv6_address() const {
85 return ipv6_address_;
86 }
87
88 private:
89 void CallSetIpAddressOnOwnerThread(const std::string& ipv4_address,
90 const std::string& ipv6_address) {
91 owner_message_loop_->PostTask(
92 FROM_HERE,
93 base::Bind(&NetworkObserver::SetIPAddresses,
94 weak_ptr_factory_owner_thread_.GetWeakPtr(),
95 ipv4_address, ipv6_address));
96 }
97
98 void SetIPAddresses(const std::string& ipv4_address,
99 const std::string& ipv6_address) {
100 ipv4_address_ = ipv4_address;
101 ipv6_address_ = ipv6_address;
102 }
103
104 std::string ipv4_address_;
105 std::string ipv6_address_;
106 scoped_refptr<base::MessageLoopProxy> owner_message_loop_;
107 chromeos::NetworkStateHandler* network_state_handler_;
108 base::WeakPtrFactory<NetworkObserver> weak_ptr_factory_owner_thread_;
109
110 DISALLOW_COPY_AND_ASSIGN(NetworkObserver);
111 };
112
113 namespace net {
114
115 // HostResolverImplChromeOS
116
117 // static
118 scoped_ptr<HostResolver> HostResolverImplChromeOS::CreateSystemResolver(
119 const Options& options,
120 NetLog* net_log) {
121 scoped_ptr<HostCache> cache;
122 if (options.enable_caching)
123 cache = HostCache::CreateDefaultCache();
124 return scoped_ptr<HostResolver>(new HostResolverImplChromeOS(
125 chromeos::NetworkHandler::Get()->message_loop(),
126 chromeos::NetworkHandler::Get()->network_state_handler(),
127 cache.Pass(),
128 options.GetDispatcherLimits(),
129 ProcTaskParams(NULL, options.max_retry_attempts),
eroman 2014/06/05 22:58:24 Can you use composition rather than inheritance, t
stevenjb 2014/06/06 16:06:03 The problem with that is that HostResolveImplChrom
130 net_log));
131 }
132
133 // static
134 scoped_ptr<HostResolver> HostResolverImplChromeOS::CreateHostResolverForTest(
135 scoped_refptr<base::MessageLoopProxy> ui_message_loop,
136 chromeos::NetworkStateHandler* network_state_handler) {
137 Options options;
138 scoped_ptr<HostCache> cache = HostCache::CreateDefaultCache();
139 return scoped_ptr<HostResolver>(new HostResolverImplChromeOS(
140 ui_message_loop,
141 network_state_handler,
142 cache.Pass(),
143 options.GetDispatcherLimits(),
144 ProcTaskParams(NULL, options.max_retry_attempts),
145 NULL));
146 }
147
148 HostResolverImplChromeOS::HostResolverImplChromeOS(
149 scoped_refptr<base::MessageLoopProxy> ui_message_loop,
150 chromeos::NetworkStateHandler* network_state_handler,
151 scoped_ptr<HostCache> cache,
152 const PrioritizedDispatcher::Limits& job_limits,
153 const ProcTaskParams& proc_params,
154 NetLog* net_log)
155 : HostResolverImpl(cache.Pass(), job_limits, proc_params, net_log),
156 ui_message_loop_(ui_message_loop),
157 weak_ptr_factory_ui_thread_(this) {
158 ui_message_loop_->PostTask(
159 FROM_HERE,
160 base::Bind(&HostResolverImplChromeOS::CreateNetworkObserver,
161 weak_ptr_factory_ui_thread_.GetWeakPtr(),
162 base::MessageLoopProxy::current(),
163 network_state_handler));
164 }
165
166 HostResolverImplChromeOS::~HostResolverImplChromeOS() {
167 ui_message_loop_->DeleteSoon(
eroman 2014/06/05 22:58:24 Note that this pattern can cause leaks during shut
stevenjb 2014/06/06 16:06:03 Ugh, I didn't realize that IOThread::globals_ was
stevenjb 2014/06/06 17:24:18 I realized quickly that a Shutdown message after t
168 FROM_HERE,
169 network_observer_.release());
170 }
171
172 void HostResolverImplChromeOS::CreateNetworkObserver(
173 scoped_refptr<base::MessageLoopProxy> io_message_loop,
174 chromeos::NetworkStateHandler* network_state_handler) {
175 network_observer_.reset(
176 new NetworkObserver(io_message_loop, network_state_handler));
177 }
178
179 int HostResolverImplChromeOS::Resolve(const RequestInfo& info,
180 RequestPriority priority,
181 AddressList* addresses,
182 const CompletionCallback& callback,
183 RequestHandle* out_req,
184 const BoundNetLog& source_net_log) {
185 DCHECK(thread_checker_.CalledOnValidThread());
186 if (ResolveLocalIPAddress(info, addresses))
187 return net::OK;
188 return HostResolverImpl::Resolve(
189 info, priority, addresses, callback, out_req, source_net_log);
190 }
191
192 bool HostResolverImplChromeOS::ResolveLocalIPAddress(const RequestInfo& info,
193 AddressList* addresses) {
194 if (info.hostname() != GetHostName() || !network_observer_)
eroman 2014/06/05 22:58:24 Is there going to be any other consequences of thi
stevenjb 2014/06/06 16:06:03 I'm not familiar enough with network internals to
stevenjb 2014/06/06 17:34:11 So, on systems other than Chrome OS, isn't a local
195 return false;
196
197 // Use IPConfig data for localhost address lookup.
198 addresses->clear();
199 std::string ipv6_address = network_observer_->ipv6_address();
200 if (info.address_family() != net::ADDRESS_FAMILY_IPV4 &&
201 !ipv6_address.empty()) {
202 IPAddressNumber ipv6;
203 if (ParseIPLiteralToNumber(ipv6_address, &ipv6))
204 addresses->push_back(IPEndPoint(ipv6, 0));
205 }
206 std::string ipv4_address = network_observer_->ipv4_address();
207 if (!ipv4_address.empty()) {
208 IPAddressNumber ipv4;
209 if (ParseIPLiteralToNumber(ipv4_address, &ipv4))
210 addresses->push_back(IPEndPoint(ipv4, 0));
211 }
212 DVLOG(2) << "ResolveLocalIPAddress("
213 << static_cast<int>(info.address_family()) << "): "
214 << addresses->size()
215 << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
216 if (addresses->empty())
217 return false;
218 addresses->SetDefaultCanonicalName();
219 return true;
220 }
221
222 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698