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

Side by Side Diff: net/base/address_tracker_linux.cc

Issue 571743002: Adding non-tracking mode support to AddressTracker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add track option in AddressTrackerLinux::Init Created 6 years, 3 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
« no previous file with comments | « net/base/address_tracker_linux.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/address_tracker_linux.h" 5 #include "net/base/address_tracker_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <linux/if.h> 8 #include <linux/if.h>
9 #include <sys/ioctl.h> 9 #include <sys/ioctl.h>
10 10
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 const base::Closure& tunnel_callback) 102 const base::Closure& tunnel_callback)
103 : get_interface_name_(GetInterfaceName), 103 : get_interface_name_(GetInterfaceName),
104 address_callback_(address_callback), 104 address_callback_(address_callback),
105 link_callback_(link_callback), 105 link_callback_(link_callback),
106 tunnel_callback_(tunnel_callback), 106 tunnel_callback_(tunnel_callback),
107 netlink_fd_(-1), 107 netlink_fd_(-1),
108 is_offline_(true), 108 is_offline_(true),
109 is_offline_initialized_(false), 109 is_offline_initialized_(false),
110 is_offline_initialized_cv_(&is_offline_lock_) { 110 is_offline_initialized_cv_(&is_offline_lock_) {
111 DCHECK(!address_callback.is_null()); 111 DCHECK(!address_callback.is_null());
112 DCHECK(!link_callback.is_null()); 112 DCHECK(!link_callback.is_null());
pauljensen 2014/09/18 13:56:15 I think these two lines will give you troubles whe
guoweis2 2014/09/18 19:41:11 There is a do nothing version used by unit tests.
113 } 113 }
114 114
115 AddressTrackerLinux::~AddressTrackerLinux() { 115 AddressTrackerLinux::~AddressTrackerLinux() {
116 CloseSocket(); 116 CloseSocket();
117 } 117 }
118 118
119 void AddressTrackerLinux::Init() { 119 void AddressTrackerLinux::Init(bool track) {
120 netlink_fd_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 120 netlink_fd_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
121 if (netlink_fd_ < 0) { 121 if (netlink_fd_ < 0) {
122 PLOG(ERROR) << "Could not create NETLINK socket"; 122 PLOG(ERROR) << "Could not create NETLINK socket";
123 AbortAndForceOnline(); 123 AbortAndForceOnline();
124 return; 124 return;
125 } 125 }
126 126
127 // Request notifications. 127 int rv;
128 struct sockaddr_nl addr = {}; 128
129 addr.nl_family = AF_NETLINK; 129 if (track) {
130 addr.nl_pid = getpid(); 130 // Request notifications.
131 // TODO(szym): Track RTMGRP_LINK as well for ifi_type, http://crbug.com/113993 131 struct sockaddr_nl addr = {};
132 addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY | 132 addr.nl_family = AF_NETLINK;
133 RTMGRP_LINK; 133 addr.nl_pid = getpid();
134 int rv = bind(netlink_fd_, 134 // TODO(szym): Track RTMGRP_LINK as well for ifi_type,
135 reinterpret_cast<struct sockaddr*>(&addr), 135 // http://crbug.com/113993
136 sizeof(addr)); 136 addr.nl_groups =
137 if (rv < 0) { 137 RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY | RTMGRP_LINK;
138 PLOG(ERROR) << "Could not bind NETLINK socket"; 138 rv = bind(
139 AbortAndForceOnline(); 139 netlink_fd_, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
140 return; 140 if (rv < 0) {
141 PLOG(ERROR) << "Could not bind NETLINK socket";
142 AbortAndForceOnline();
143 return;
144 }
141 } 145 }
142 146
143 // Request dump of addresses. 147 // Request dump of addresses.
144 struct sockaddr_nl peer = {}; 148 struct sockaddr_nl peer = {};
145 peer.nl_family = AF_NETLINK; 149 peer.nl_family = AF_NETLINK;
146 150
147 struct { 151 struct {
148 struct nlmsghdr header; 152 struct nlmsghdr header;
149 struct rtgenmsg msg; 153 struct rtgenmsg msg;
150 } request = {}; 154 } request = {};
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 } 188 }
185 189
186 // Consume pending message to populate links_online_, but don't notify. 190 // Consume pending message to populate links_online_, but don't notify.
187 ReadMessages(&address_changed, &link_changed, &tunnel_changed); 191 ReadMessages(&address_changed, &link_changed, &tunnel_changed);
188 { 192 {
189 base::AutoLock lock(is_offline_lock_); 193 base::AutoLock lock(is_offline_lock_);
190 is_offline_initialized_ = true; 194 is_offline_initialized_ = true;
191 is_offline_initialized_cv_.Signal(); 195 is_offline_initialized_cv_.Signal();
192 } 196 }
193 197
194 rv = base::MessageLoopForIO::current()->WatchFileDescriptor( 198 if (track) {
195 netlink_fd_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this); 199 rv = base::MessageLoopForIO::current()->WatchFileDescriptor(
196 if (rv < 0) { 200 netlink_fd_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
197 PLOG(ERROR) << "Could not watch NETLINK socket"; 201 if (rv < 0) {
198 AbortAndForceOnline(); 202 PLOG(ERROR) << "Could not watch NETLINK socket";
199 return; 203 AbortAndForceOnline();
204 return;
205 }
200 } 206 }
201 } 207 }
202 208
203 void AddressTrackerLinux::AbortAndForceOnline() { 209 void AddressTrackerLinux::AbortAndForceOnline() {
204 CloseSocket(); 210 CloseSocket();
205 base::AutoLock lock(is_offline_lock_); 211 base::AutoLock lock(is_offline_lock_);
206 is_offline_ = false; 212 is_offline_ = false;
207 is_offline_initialized_ = true; 213 is_offline_initialized_ = true;
208 is_offline_initialized_cv_.Signal(); 214 is_offline_initialized_cv_.Signal();
209 } 215 }
210 216
211 AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const { 217 AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const {
212 base::AutoLock lock(address_map_lock_); 218 base::AutoLock lock(address_map_lock_);
213 return address_map_; 219 return address_map_;
214 } 220 }
215 221
222 base::hash_set<int> AddressTrackerLinux::GetOnlineLinks() const {
223 base::AutoLock lock(online_links_lock_);
224 return online_links_;
225 }
226
216 NetworkChangeNotifier::ConnectionType 227 NetworkChangeNotifier::ConnectionType
217 AddressTrackerLinux::GetCurrentConnectionType() { 228 AddressTrackerLinux::GetCurrentConnectionType() {
218 // http://crbug.com/125097 229 // http://crbug.com/125097
219 base::ThreadRestrictions::ScopedAllowWait allow_wait; 230 base::ThreadRestrictions::ScopedAllowWait allow_wait;
220 base::AutoLock lock(is_offline_lock_); 231 base::AutoLock lock(is_offline_lock_);
221 // Make sure the initial offline state is set before returning. 232 // Make sure the initial offline state is set before returning.
222 while (!is_offline_initialized_) { 233 while (!is_offline_initialized_) {
223 is_offline_initialized_cv_.Wait(); 234 is_offline_initialized_cv_.Wait();
224 } 235 }
225 // TODO(droger): Return something more detailed than CONNECTION_UNKNOWN. 236 // TODO(droger): Return something more detailed than CONNECTION_UNKNOWN.
(...skipping 21 matching lines...) Expand all
247 LOG(ERROR) << "Unexpected shutdown of NETLINK socket."; 258 LOG(ERROR) << "Unexpected shutdown of NETLINK socket.";
248 return; 259 return;
249 } 260 }
250 if (rv < 0) { 261 if (rv < 0) {
251 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) 262 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
252 break; 263 break;
253 PLOG(ERROR) << "Failed to recv from netlink socket"; 264 PLOG(ERROR) << "Failed to recv from netlink socket";
254 return; 265 return;
255 } 266 }
256 HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed); 267 HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
257 }; 268 }
258 if (*link_changed) { 269 if (*link_changed) {
270 bool is_offline;
271 {
272 base::AutoLock lock(online_links_lock_);
273 is_offline = online_links_.empty();
274 }
259 base::AutoLock lock(is_offline_lock_); 275 base::AutoLock lock(is_offline_lock_);
260 is_offline_ = online_links_.empty(); 276 is_offline_ = is_offline;
261 } 277 }
262 } 278 }
263 279
264 void AddressTrackerLinux::HandleMessage(char* buffer, 280 void AddressTrackerLinux::HandleMessage(char* buffer,
265 size_t length, 281 size_t length,
266 bool* address_changed, 282 bool* address_changed,
267 bool* link_changed, 283 bool* link_changed,
268 bool* tunnel_changed) { 284 bool* tunnel_changed) {
269 DCHECK(buffer); 285 DCHECK(buffer);
270 for (struct nlmsghdr* header = reinterpret_cast<struct nlmsghdr*>(buffer); 286 for (struct nlmsghdr* header = reinterpret_cast<struct nlmsghdr*>(buffer);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 base::AutoLock lock(address_map_lock_); 328 base::AutoLock lock(address_map_lock_);
313 if (address_map_.erase(address)) 329 if (address_map_.erase(address))
314 *address_changed = true; 330 *address_changed = true;
315 } 331 }
316 } break; 332 } break;
317 case RTM_NEWLINK: { 333 case RTM_NEWLINK: {
318 const struct ifinfomsg* msg = 334 const struct ifinfomsg* msg =
319 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); 335 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header));
320 if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) && 336 if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) &&
321 (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) { 337 (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) {
338 base::AutoLock lock(online_links_lock_);
322 if (online_links_.insert(msg->ifi_index).second) { 339 if (online_links_.insert(msg->ifi_index).second) {
323 *link_changed = true; 340 *link_changed = true;
324 if (IsTunnelInterface(msg)) 341 if (IsTunnelInterface(msg))
325 *tunnel_changed = true; 342 *tunnel_changed = true;
326 } 343 }
327 } else { 344 } else {
345 base::AutoLock lock(online_links_lock_);
328 if (online_links_.erase(msg->ifi_index)) { 346 if (online_links_.erase(msg->ifi_index)) {
329 *link_changed = true; 347 *link_changed = true;
330 if (IsTunnelInterface(msg)) 348 if (IsTunnelInterface(msg))
331 *tunnel_changed = true; 349 *tunnel_changed = true;
332 } 350 }
333 } 351 }
334 } break; 352 } break;
335 case RTM_DELLINK: { 353 case RTM_DELLINK: {
336 const struct ifinfomsg* msg = 354 const struct ifinfomsg* msg =
337 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); 355 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header));
356 base::AutoLock lock(online_links_lock_);
338 if (online_links_.erase(msg->ifi_index)) { 357 if (online_links_.erase(msg->ifi_index)) {
339 *link_changed = true; 358 *link_changed = true;
340 if (IsTunnelInterface(msg)) 359 if (IsTunnelInterface(msg))
341 *tunnel_changed = true; 360 *tunnel_changed = true;
342 } 361 }
343 } break; 362 } break;
344 default: 363 default:
345 break; 364 break;
346 } 365 }
347 } 366 }
(...skipping 21 matching lines...) Expand all
369 netlink_fd_ = -1; 388 netlink_fd_ = -1;
370 } 389 }
371 390
372 bool AddressTrackerLinux::IsTunnelInterface(const struct ifinfomsg* msg) const { 391 bool AddressTrackerLinux::IsTunnelInterface(const struct ifinfomsg* msg) const {
373 // Linux kernel drivers/net/tun.c uses "tun" name prefix. 392 // Linux kernel drivers/net/tun.c uses "tun" name prefix.
374 return strncmp(get_interface_name_(msg->ifi_index), "tun", 3) == 0; 393 return strncmp(get_interface_name_(msg->ifi_index), "tun", 3) == 0;
375 } 394 }
376 395
377 } // namespace internal 396 } // namespace internal
378 } // namespace net 397 } // namespace net
OLDNEW
« no previous file with comments | « net/base/address_tracker_linux.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698