summaryrefslogtreecommitdiff
path: root/chromium/net/base/address_tracker_linux.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/base/address_tracker_linux.h')
-rw-r--r--chromium/net/base/address_tracker_linux.h99
1 files changed, 99 insertions, 0 deletions
diff --git a/chromium/net/base/address_tracker_linux.h b/chromium/net/base/address_tracker_linux.h
new file mode 100644
index 00000000000..e5ab692c233
--- /dev/null
+++ b/chromium/net/base/address_tracker_linux.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 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.
+
+#ifndef NET_BASE_ADDRESS_TRACKER_LINUX_H_
+#define NET_BASE_ADDRESS_TRACKER_LINUX_H_
+
+#include <sys/socket.h> // Needed to include netlink.
+// Mask superfluous definition of |struct net|. This is fixed in Linux 2.6.38.
+#define net net_kernel
+#include <linux/rtnetlink.h>
+#undef net
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/containers/hash_tables.h"
+#include "base/message_loop/message_loop.h"
+#include "base/synchronization/condition_variable.h"
+#include "base/synchronization/lock.h"
+#include "net/base/net_util.h"
+#include "net/base/network_change_notifier.h"
+
+namespace net {
+namespace internal {
+
+// Keeps track of network interface addresses using rtnetlink. Used by
+// NetworkChangeNotifier to provide signals to registered IPAddressObservers.
+class NET_EXPORT_PRIVATE AddressTrackerLinux :
+ public base::MessageLoopForIO::Watcher {
+ public:
+ typedef std::map<IPAddressNumber, struct ifaddrmsg> AddressMap;
+
+ // Will run |address_callback| when the AddressMap changes and will run
+ // |link_callback| when the list of online links changes.
+ AddressTrackerLinux(const base::Closure& address_callback,
+ const base::Closure& link_callback);
+ virtual ~AddressTrackerLinux();
+
+ // Starts watching system configuration for changes. The current thread must
+ // have a MessageLoopForIO.
+ void Init();
+
+ AddressMap GetAddressMap() const;
+
+ // Implementation of NetworkChangeNotifierLinux::GetCurrentConnectionType().
+ // Safe to call from any thread, but will block until Init() has completed.
+ NetworkChangeNotifier::ConnectionType GetCurrentConnectionType();
+
+ private:
+ friend class AddressTrackerLinuxTest;
+
+ // Sets |*address_changed| to indicate whether |address_map_| changed and
+ // sets |*link_changed| to indicate if |online_links_| changed while reading
+ // messages from |netlink_fd_|.
+ void ReadMessages(bool* address_changed, bool* link_changed);
+
+ // Sets |*address_changed| to true if |address_map_| changed, sets
+ // |*link_changed| to true if |online_links_| changed while reading the
+ // message from |buffer|.
+ void HandleMessage(const char* buffer,
+ size_t length,
+ bool* address_changed,
+ bool* link_changed);
+
+ // Call when some part of initialization failed; forces online and unblocks.
+ void AbortAndForceOnline();
+
+ // MessageLoopForIO::Watcher:
+ virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
+ virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE;
+
+ // Close |netlink_fd_|
+ void CloseSocket();
+
+ base::Closure address_callback_;
+ base::Closure link_callback_;
+
+ int netlink_fd_;
+ base::MessageLoopForIO::FileDescriptorWatcher watcher_;
+
+ mutable base::Lock address_map_lock_;
+ AddressMap address_map_;
+
+ // Set of interface indices for links that are currently online.
+ base::hash_set<int> online_links_;
+
+ base::Lock is_offline_lock_;
+ bool is_offline_;
+ bool is_offline_initialized_;
+ base::ConditionVariable is_offline_initialized_cv_;
+};
+
+} // namespace internal
+} // namespace net
+
+#endif // NET_BASE_ADDRESS_TRACKER_LINUX_H_