1 // Copyright (c) 2012 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 #ifndef NET_BASE_ADDRESS_TRACKER_LINUX_H_ 6 #define NET_BASE_ADDRESS_TRACKER_LINUX_H_ 7 8 #include <sys/socket.h> // Needed to include netlink. 9 // Mask superfluous definition of |struct net|. This is fixed in Linux 2.6.38. 10 #define net net_kernel 11 #include <linux/rtnetlink.h> 12 #undef net 13 14 #include <map> 15 16 #include "base/basictypes.h" 17 #include "base/callback.h" 18 #include "base/compiler_specific.h" 19 #include "base/containers/hash_tables.h" 20 #include "base/message_loop/message_loop.h" 21 #include "base/synchronization/condition_variable.h" 22 #include "base/synchronization/lock.h" 23 #include "net/base/net_util.h" 24 #include "net/base/network_change_notifier.h" 25 26 namespace net { 27 namespace internal { 28 29 // Keeps track of network interface addresses using rtnetlink. Used by 30 // NetworkChangeNotifier to provide signals to registered IPAddressObservers. 31 class NET_EXPORT_PRIVATE AddressTrackerLinux : 32 public base::MessageLoopForIO::Watcher { 33 public: 34 typedef std::map<IPAddressNumber, struct ifaddrmsg> AddressMap; 35 36 // Will run |address_callback| when the AddressMap changes and will run 37 // |link_callback| when the list of online links changes. 38 AddressTrackerLinux(const base::Closure& address_callback, 39 const base::Closure& link_callback); 40 virtual ~AddressTrackerLinux(); 41 42 // Starts watching system configuration for changes. The current thread must 43 // have a MessageLoopForIO. 44 void Init(); 45 46 AddressMap GetAddressMap() const; 47 48 // Implementation of NetworkChangeNotifierLinux::GetCurrentConnectionType(). 49 // Safe to call from any thread, but will block until Init() has completed. 50 NetworkChangeNotifier::ConnectionType GetCurrentConnectionType(); 51 52 private: 53 friend class AddressTrackerLinuxTest; 54 55 // Sets |*address_changed| to indicate whether |address_map_| changed and 56 // sets |*link_changed| to indicate if |online_links_| changed while reading 57 // messages from |netlink_fd_|. 58 void ReadMessages(bool* address_changed, bool* link_changed); 59 60 // Sets |*address_changed| to true if |address_map_| changed, sets 61 // |*link_changed| to true if |online_links_| changed while reading the 62 // message from |buffer|. 63 void HandleMessage(const char* buffer, 64 size_t length, 65 bool* address_changed, 66 bool* link_changed); 67 68 // Call when some part of initialization failed; forces online and unblocks. 69 void AbortAndForceOnline(); 70 71 // MessageLoopForIO::Watcher: 72 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; 73 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE; 74 75 // Close |netlink_fd_| 76 void CloseSocket(); 77 78 base::Closure address_callback_; 79 base::Closure link_callback_; 80 81 int netlink_fd_; 82 base::MessageLoopForIO::FileDescriptorWatcher watcher_; 83 84 mutable base::Lock address_map_lock_; 85 AddressMap address_map_; 86 87 // Set of interface indices for links that are currently online. 88 base::hash_set<int> online_links_; 89 90 base::Lock is_offline_lock_; 91 bool is_offline_; 92 bool is_offline_initialized_; 93 base::ConditionVariable is_offline_initialized_cv_; 94 }; 95 96 } // namespace internal 97 } // namespace net 98 99 #endif // NET_BASE_ADDRESS_TRACKER_LINUX_H_ 100