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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chromeos/network/host_resolver_impl_chromeos.cc
diff --git a/chromeos/network/host_resolver_impl_chromeos.cc b/chromeos/network/host_resolver_impl_chromeos.cc
new file mode 100644
index 0000000000000000000000000000000000000000..749bb2cdcb47254bfddb7a3d09dde2d24398025e
--- /dev/null
+++ b/chromeos/network/host_resolver_impl_chromeos.cc
@@ -0,0 +1,223 @@
+// Copyright (c) 2014 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 "chromeos/network/host_resolver_impl_chromeos.h"
+
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/values.h"
+#include "chromeos/network/device_state.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_state_handler_observer.h"
+#include "net/base/address_list.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_util.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+// HostResolverImplChromeOS::NetworkStateHandlerObserver
+
+namespace chromeos {
+
+class HostResolverImplChromeOS::NetworkObserver
+ : public chromeos::NetworkStateHandlerObserver {
+ public:
+ NetworkObserver(scoped_refptr<base::MessageLoopProxy> owner_message_loop,
+ NetworkStateHandler* network_state_handler)
+ : owner_message_loop_(owner_message_loop),
+ network_state_handler_(network_state_handler),
+ weak_ptr_factory_owner_thread_(this) {
+ network_state_handler_->AddObserver(this, FROM_HERE);
+ DefaultNetworkChanged(network_state_handler_->DefaultNetwork());
+ }
+
+ virtual ~NetworkObserver() {
+ network_state_handler_->RemoveObserver(this, FROM_HERE);
+ }
+
+ // NetworkStateHandlerObserver
+ virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE {
+ if (!network) {
+ DVLOG(2) << "DefaultNetworkChanged: No Network.";
+ CallSetIpAddressOnOwnerThread("", "");
+ return;
+ }
+ std::string ipv4_address, ipv6_address;
+ const DeviceState* device_state =
+ network_state_handler_->GetDeviceState(network->device_path());
+ if (!device_state) {
+ LOG(ERROR) << "DefaultNetworkChanged: Network missing device: "
+ << network->path();
+ CallSetIpAddressOnOwnerThread("", "");
+ return;
+ }
+ for (base::DictionaryValue::Iterator iter(device_state->ip_configs());
+ !iter.IsAtEnd(); iter.Advance()) {
+ const base::DictionaryValue* ip_config;
+ if (!iter.value().GetAsDictionary(&ip_config)) {
+ LOG(ERROR) << "Badly formatted IPConfigs: " << network->path();
+ continue;
+ }
+ std::string method, address;
+ if (ip_config->GetString(shill::kMethodProperty, &method) &&
+ ip_config->GetString(shill::kAddressProperty, &address)) {
+ if (method == shill::kTypeIPv4 || method == shill::kTypeDHCP)
+ ipv4_address = address;
+ else if (method == shill::kTypeIPv6 || method == shill::kTypeDHCP6)
+ ipv6_address = address;
+ } else {
+ LOG(ERROR) << "DefaultNetworkChanged: IPConfigs missing properties: "
+ << network->path();
+ }
+ }
+ DVLOG(2) << "DefaultNetworkChanged: " << network->name()
+ << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
+ CallSetIpAddressOnOwnerThread(ipv4_address, ipv6_address);
+ }
+
+ // These may be safely accessed by the owner thread.
+ std::string ipv4_address() const {
+ return ipv4_address_;
+ }
+ std::string ipv6_address() const {
+ return ipv6_address_;
+ }
+
+ private:
+ void CallSetIpAddressOnOwnerThread(const std::string& ipv4_address,
+ const std::string& ipv6_address) {
+ owner_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&NetworkObserver::SetIPAddresses,
+ weak_ptr_factory_owner_thread_.GetWeakPtr(),
+ ipv4_address, ipv6_address));
+ }
+
+ void SetIPAddresses(const std::string& ipv4_address,
+ const std::string& ipv6_address) {
+ ipv4_address_ = ipv4_address;
+ ipv6_address_ = ipv6_address;
+ }
+
+ std::string ipv4_address_;
+ std::string ipv6_address_;
+ scoped_refptr<base::MessageLoopProxy> owner_message_loop_;
+ NetworkStateHandler* network_state_handler_;
+ base::WeakPtrFactory<NetworkObserver> weak_ptr_factory_owner_thread_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkObserver);
+};
+
+// HostResolverImplChromeOS
+
+// TODO(stevenjb)/eroman: Consider re-factoring the HostResolverImpl
+// 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
+// static
+scoped_ptr<net::HostResolver> HostResolverImplChromeOS::CreateSystemResolver(
+ const Options& options,
+ net::NetLog* net_log) {
+ scoped_ptr<net::HostCache> cache;
+ if (options.enable_caching)
+ cache = net::HostCache::CreateDefaultCache();
+ return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
+ NetworkHandler::Get()->message_loop(),
+ NetworkHandler::Get()->network_state_handler(),
+ cache.Pass(),
+ options.GetDispatcherLimits(),
+ ProcTaskParams(NULL, options.max_retry_attempts),
+ net_log));
+}
+
+// static
+scoped_ptr<net::HostResolver>
+HostResolverImplChromeOS::CreateHostResolverForTest(
+ scoped_refptr<base::MessageLoopProxy> network_handler_message_loop,
+ NetworkStateHandler* network_state_handler) {
+ Options options;
+ scoped_ptr<net::HostCache> cache = net::HostCache::CreateDefaultCache();
+ return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
+ network_handler_message_loop,
+ network_state_handler,
+ cache.Pass(),
+ options.GetDispatcherLimits(),
+ ProcTaskParams(NULL, options.max_retry_attempts),
+ NULL));
+}
+
+HostResolverImplChromeOS::HostResolverImplChromeOS(
+ scoped_refptr<base::MessageLoopProxy> network_handler_message_loop,
+ NetworkStateHandler* network_state_handler,
+ scoped_ptr<net::HostCache> cache,
+ const net::PrioritizedDispatcher::Limits& job_limits,
+ const ProcTaskParams& proc_params,
+ net::NetLog* net_log)
+ : HostResolverImpl(cache.Pass(), job_limits, proc_params, net_log),
+ network_handler_message_loop_(network_handler_message_loop),
+ weak_ptr_factory_ui_thread_(this) {
+ network_handler_message_loop->PostTask(
+ FROM_HERE,
+ base::Bind(&HostResolverImplChromeOS::CreateNetworkObserver,
+ weak_ptr_factory_ui_thread_.GetWeakPtr(),
+ base::MessageLoopProxy::current(),
+ network_state_handler));
+}
+
+HostResolverImplChromeOS::~HostResolverImplChromeOS() {
+ NetworkObserver* network_observer = network_observer_.release();
+ if (!network_handler_message_loop_->DeleteSoon(FROM_HERE, network_observer))
+ 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
+}
+
+void HostResolverImplChromeOS::CreateNetworkObserver(
+ scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ chromeos::NetworkStateHandler* network_state_handler) {
+ network_observer_.reset(
+ new NetworkObserver(io_message_loop, network_state_handler));
+}
+
+int HostResolverImplChromeOS::Resolve(const RequestInfo& info,
+ net::RequestPriority priority,
+ net::AddressList* addresses,
+ const net::CompletionCallback& callback,
+ RequestHandle* out_req,
+ const net::BoundNetLog& source_net_log) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (ResolveLocalIPAddress(info, addresses))
+ return net::OK;
+ return net::HostResolverImpl::Resolve(
+ info, priority, addresses, callback, out_req, source_net_log);
+}
+
+bool HostResolverImplChromeOS::ResolveLocalIPAddress(
+ const RequestInfo& info,
+ net::AddressList* addresses) {
+ if (info.hostname() != net::GetHostName() || !network_observer_)
+ return false;
+
+ // Use IPConfig data for localhost address lookup.
+ addresses->clear();
+ std::string ipv6_address = network_observer_->ipv6_address();
+ if (info.address_family() != net::ADDRESS_FAMILY_IPV4 &&
+ !ipv6_address.empty()) {
+ net::IPAddressNumber ipv6;
+ if (net::ParseIPLiteralToNumber(ipv6_address, &ipv6))
+ addresses->push_back(net::IPEndPoint(ipv6, 0));
+ }
+ std::string ipv4_address = network_observer_->ipv4_address();
+ if (!ipv4_address.empty()) {
+ net::IPAddressNumber ipv4;
+ if (net::ParseIPLiteralToNumber(ipv4_address, &ipv4))
+ addresses->push_back(net::IPEndPoint(ipv4, 0));
+ }
+ DVLOG(2) << "ResolveLocalIPAddress("
+ << static_cast<int>(info.address_family()) << "): "
+ << addresses->size()
+ << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
+ if (addresses->empty())
+ return false;
+ addresses->SetDefaultCanonicalName();
+ return true;
+}
+
+} // namespace chromeos
« 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