Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / base / address_tracker_linux.h
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 "base/threading/thread_checker.h"
24 #include "net/base/net_util.h"
25 #include "net/base/network_change_notifier.h"
26
27 namespace net {
28 namespace internal {
29
30 // Keeps track of network interface addresses using rtnetlink. Used by
31 // NetworkChangeNotifier to provide signals to registered IPAddressObservers.
32 class NET_EXPORT_PRIVATE AddressTrackerLinux :
33     public base::MessageLoopForIO::Watcher {
34  public:
35   typedef std::map<IPAddressNumber, struct ifaddrmsg> AddressMap;
36
37   // Non-tracking version constructor: it takes a snapshot of the
38   // current system configuration. Once Init() returns, the
39   // configuration is available through GetOnlineLinks() and
40   // GetAddressMap().
41   AddressTrackerLinux();
42
43   // Tracking version constructor: it will run |address_callback| when
44   // the AddressMap changes, |link_callback| when the list of online
45   // links changes, and |tunnel_callback| when the list of online
46   // tunnels changes.
47   AddressTrackerLinux(const base::Closure& address_callback,
48                       const base::Closure& link_callback,
49                       const base::Closure& tunnel_callback);
50   ~AddressTrackerLinux() override;
51
52   // In tracking mode, it starts watching the system configuration for
53   // changes. The current thread must have a MessageLoopForIO. In
54   // non-tracking mode, once Init() returns, a snapshot of the system
55   // configuration is available through GetOnlineLinks() and
56   // GetAddressMap().
57   void Init();
58
59   AddressMap GetAddressMap() const;
60
61   // Returns set of interface indicies for online interfaces.
62   base::hash_set<int> GetOnlineLinks() const;
63
64   // Implementation of NetworkChangeNotifierLinux::GetCurrentConnectionType().
65   // Safe to call from any thread, but will block until Init() has completed.
66   NetworkChangeNotifier::ConnectionType GetCurrentConnectionType();
67
68  private:
69   friend class AddressTrackerLinuxTest;
70
71   // In tracking mode, holds |lock| while alive. In non-tracking mode,
72   // enforces single-threaded access.
73   class AddressTrackerAutoLock {
74    public:
75     AddressTrackerAutoLock(const AddressTrackerLinux& tracker,
76                            base::Lock& lock);
77     ~AddressTrackerAutoLock();
78
79    private:
80     const AddressTrackerLinux& tracker_;
81     base::Lock& lock_;
82     DISALLOW_COPY_AND_ASSIGN(AddressTrackerAutoLock);
83   };
84
85   // A function that returns the name of an interface given the interface index
86   // in |interface_index|.
87   typedef const char* (*GetInterfaceNameFunction)(int interface_index);
88
89   // Sets |*address_changed| to indicate whether |address_map_| changed and
90   // sets |*link_changed| to indicate if |online_links_| changed and sets
91   // |*tunnel_changed| to indicate if |online_links_| changed with regards to a
92   // tunnel interface while reading messages from |netlink_fd_|.
93   void ReadMessages(bool* address_changed,
94                     bool* link_changed,
95                     bool* tunnel_changed);
96
97   // Sets |*address_changed| to true if |address_map_| changed, sets
98   // |*link_changed| to true if |online_links_| changed, sets |*tunnel_changed|
99   // to true if |online_links_| changed with regards to a tunnel interface while
100   // reading the message from |buffer|.
101   void HandleMessage(char* buffer,
102                      size_t length,
103                      bool* address_changed,
104                      bool* link_changed,
105                      bool* tunnel_changed);
106
107   // Call when some part of initialization failed; forces online and unblocks.
108   void AbortAndForceOnline();
109
110   // MessageLoopForIO::Watcher:
111   void OnFileCanReadWithoutBlocking(int fd) override;
112   void OnFileCanWriteWithoutBlocking(int /* fd */) override;
113
114   // Close |netlink_fd_|
115   void CloseSocket();
116
117   // Does |msg| refer to a tunnel interface?
118   bool IsTunnelInterface(const struct ifinfomsg* msg) const;
119
120   // Gets the name of an interface given the interface index |interface_index|.
121   // May return empty string if it fails but should not return NULL. This is
122   // overridden by tests.
123   GetInterfaceNameFunction get_interface_name_;
124
125   base::Closure address_callback_;
126   base::Closure link_callback_;
127   base::Closure tunnel_callback_;
128
129   int netlink_fd_;
130   base::MessageLoopForIO::FileDescriptorWatcher watcher_;
131
132   mutable base::Lock address_map_lock_;
133   AddressMap address_map_;
134
135   // Set of interface indices for links that are currently online.
136   mutable base::Lock online_links_lock_;
137   base::hash_set<int> online_links_;
138
139   base::Lock is_offline_lock_;
140   bool is_offline_;
141   bool is_offline_initialized_;
142   base::ConditionVariable is_offline_initialized_cv_;
143   bool tracking_;
144
145   // Used to verify single-threaded access in non-tracking mode.
146   base::ThreadChecker thread_checker_;
147 };
148
149 }  // namespace internal
150 }  // namespace net
151
152 #endif  // NET_BASE_ADDRESS_TRACKER_LINUX_H_