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

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: Shut down correctly in unittest. 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 namespace chromeos {
22
23 class HostResolverImplChromeOS::NetworkObserver
24 : public chromeos::NetworkStateHandlerObserver {
25 public:
26 NetworkObserver(scoped_refptr<base::MessageLoopProxy> owner_message_loop,
27 NetworkStateHandler* network_state_handler)
28 : owner_message_loop_(owner_message_loop),
29 network_state_handler_(network_state_handler),
30 weak_ptr_factory_owner_thread_(this) {
31 network_state_handler_->AddObserver(this, FROM_HERE);
32 DefaultNetworkChanged(network_state_handler_->DefaultNetwork());
33 }
34
35 virtual ~NetworkObserver() {
36 network_state_handler_->RemoveObserver(this, FROM_HERE);
37 }
38
39 // NetworkStateHandlerObserver
40 virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE {
41 if (!network) {
42 DVLOG(2) << "DefaultNetworkChanged: No Network.";
43 CallSetIpAddressOnOwnerThread("", "");
44 return;
45 }
46 std::string ipv4_address, ipv6_address;
47 const DeviceState* device_state =
48 network_state_handler_->GetDeviceState(network->device_path());
49 if (!device_state) {
50 LOG(ERROR) << "DefaultNetworkChanged: Network missing device: "
51 << network->path();
52 CallSetIpAddressOnOwnerThread("", "");
53 return;
54 }
55 for (base::DictionaryValue::Iterator iter(device_state->ip_configs());
56 !iter.IsAtEnd(); iter.Advance()) {
57 const base::DictionaryValue* ip_config;
58 if (!iter.value().GetAsDictionary(&ip_config)) {
59 LOG(ERROR) << "Badly formatted IPConfigs: " << network->path();
60 continue;
61 }
62 std::string method, address;
63 if (ip_config->GetString(shill::kMethodProperty, &method) &&
64 ip_config->GetString(shill::kAddressProperty, &address)) {
65 if (method == shill::kTypeIPv4 || method == shill::kTypeDHCP)
66 ipv4_address = address;
67 else if (method == shill::kTypeIPv6 || method == shill::kTypeDHCP6)
68 ipv6_address = address;
69 } else {
70 LOG(ERROR) << "DefaultNetworkChanged: IPConfigs missing properties: "
71 << network->path();
72 }
73 }
74 DVLOG(2) << "DefaultNetworkChanged: " << network->name()
75 << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
76 CallSetIpAddressOnOwnerThread(ipv4_address, ipv6_address);
77 }
78
79 // These may be safely accessed by the owner thread.
80 std::string ipv4_address() const {
81 return ipv4_address_;
82 }
83 std::string ipv6_address() const {
84 return ipv6_address_;
85 }
86
87 private:
88 void CallSetIpAddressOnOwnerThread(const std::string& ipv4_address,
89 const std::string& ipv6_address) {
90 owner_message_loop_->PostTask(
91 FROM_HERE,
92 base::Bind(&NetworkObserver::SetIPAddresses,
93 weak_ptr_factory_owner_thread_.GetWeakPtr(),
94 ipv4_address, ipv6_address));
95 }
96
97 void SetIPAddresses(const std::string& ipv4_address,
98 const std::string& ipv6_address) {
99 ipv4_address_ = ipv4_address;
100 ipv6_address_ = ipv6_address;
101 }
102
103 std::string ipv4_address_;
104 std::string ipv6_address_;
105 scoped_refptr<base::MessageLoopProxy> owner_message_loop_;
106 NetworkStateHandler* network_state_handler_;
107 base::WeakPtrFactory<NetworkObserver> weak_ptr_factory_owner_thread_;
108
109 DISALLOW_COPY_AND_ASSIGN(NetworkObserver);
110 };
111
112 // HostResolverImplChromeOS
113
114 // TODO(stevenjb)/eroman: Consider re-factoring the HostResolverImpl
115 // construction to reduce duplicate code.
eroman 2014/06/09 22:37:11 I still think the right abstraction is to compose.
stevenjb 2014/06/10 22:04:55 While I understand your concern, I think compositi
116 // static
117 scoped_ptr<net::HostResolver> HostResolverImplChromeOS::CreateSystemResolver(
118 const Options& options,
119 net::NetLog* net_log) {
120 scoped_ptr<net::HostCache> cache;
121 if (options.enable_caching)
122 cache = net::HostCache::CreateDefaultCache();
123 return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
124 NetworkHandler::Get()->message_loop(),
125 NetworkHandler::Get()->network_state_handler(),
126 cache.Pass(),
127 options.GetDispatcherLimits(),
128 ProcTaskParams(NULL, options.max_retry_attempts),
129 net_log));
130 }
131
132 // static
133 scoped_ptr<net::HostResolver>
134 HostResolverImplChromeOS::CreateHostResolverForTest(
135 scoped_refptr<base::MessageLoopProxy> network_handler_message_loop,
136 NetworkStateHandler* network_state_handler) {
137 Options options;
138 scoped_ptr<net::HostCache> cache = net::HostCache::CreateDefaultCache();
139 return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
140 network_handler_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> network_handler_message_loop,
150 NetworkStateHandler* network_state_handler,
151 scoped_ptr<net::HostCache> cache,
152 const net::PrioritizedDispatcher::Limits& job_limits,
153 const ProcTaskParams& proc_params,
154 net::NetLog* net_log)
155 : HostResolverImpl(cache.Pass(), job_limits, proc_params, net_log),
156 network_handler_message_loop_(network_handler_message_loop),
157 weak_ptr_factory_ui_thread_(this) {
158 network_handler_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 NetworkObserver* network_observer = network_observer_.release();
168 if (!network_handler_message_loop_->DeleteSoon(FROM_HERE, network_observer))
169 delete network_observer;
eroman 2014/06/09 22:37:11 I don't think this is correct. Deleting network_ob
stevenjb 2014/06/10 22:04:55 This will only occur if the message loops were no
eroman 2014/06/12 04:13:37 This is still a problem, let me lay out my concern
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 net::RequestPriority priority,
181 net::AddressList* addresses,
182 const net::CompletionCallback& callback,
183 RequestHandle* out_req,
184 const net::BoundNetLog& source_net_log) {
185 DCHECK(thread_checker_.CalledOnValidThread());
186 if (ResolveLocalIPAddress(info, addresses))
187 return net::OK;
188 return net::HostResolverImpl::Resolve(
189 info, priority, addresses, callback, out_req, source_net_log);
190 }
191
192 bool HostResolverImplChromeOS::ResolveLocalIPAddress(
193 const RequestInfo& info,
194 net::AddressList* addresses) {
195 if (info.hostname() != net::GetHostName() || !network_observer_)
196 return false;
197
198 // Use IPConfig data for localhost address lookup.
199 addresses->clear();
200 std::string ipv6_address = network_observer_->ipv6_address();
201 if (info.address_family() != net::ADDRESS_FAMILY_IPV4 &&
202 !ipv6_address.empty()) {
203 net::IPAddressNumber ipv6;
204 if (net::ParseIPLiteralToNumber(ipv6_address, &ipv6))
205 addresses->push_back(net::IPEndPoint(ipv6, 0));
206 }
207 std::string ipv4_address = network_observer_->ipv4_address();
208 if (!ipv4_address.empty()) {
209 net::IPAddressNumber ipv4;
210 if (net::ParseIPLiteralToNumber(ipv4_address, &ipv4))
211 addresses->push_back(net::IPEndPoint(ipv4, 0));
212 }
213 DVLOG(2) << "ResolveLocalIPAddress("
214 << static_cast<int>(info.address_family()) << "): "
215 << addresses->size()
216 << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
217 if (addresses->empty())
218 return false;
219 addresses->SetDefaultCanonicalName();
220 return true;
221 }
222
223 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/network/host_resolver_impl_chromeos.h ('k') | chromeos/network/host_resolver_impl_chromeos_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698