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

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

Issue 899573002: Add WiFi SSID getter to NetworkChangeNotifier. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build Created 5 years, 10 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') | net/base/address_tracker_linux_unittest.cc » ('j') | 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 <linux/wireless.h>
9 #include <sys/ioctl.h> 10 #include <sys/ioctl.h>
10 11
11 #include "base/files/scoped_file.h" 12 #include "base/files/scoped_file.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/posix/eintr_wrapper.h" 14 #include "base/posix/eintr_wrapper.h"
14 #include "base/threading/thread_restrictions.h" 15 #include "base/threading/thread_restrictions.h"
15 #include "net/base/net_util_linux.h" 16 #include "net/base/net_util_linux.h"
16 17
17 namespace net { 18 namespace net {
18 namespace internal { 19 namespace internal {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 } 72 }
72 } 73 }
73 if (local) 74 if (local)
74 address = local; 75 address = local;
75 if (!address) 76 if (!address)
76 return false; 77 return false;
77 out->assign(address, address + address_length); 78 out->assign(address, address + address_length);
78 return true; 79 return true;
79 } 80 }
80 81
82 std::string GetInterfaceSSID(const std::string& ifname) {
83 int ioctl_socket = socket(AF_INET, SOCK_DGRAM, 0);
84 if (ioctl_socket < 0)
85 return "";
86 struct iwreq wreq;
87 memset(&wreq, 0, sizeof(wreq));
88 strncpy(wreq.ifr_name, ifname.c_str(), IFNAMSIZ - 1);
89
90 char ssid[IW_ESSID_MAX_SIZE + 1] = {0};
91 wreq.u.essid.pointer = ssid;
92 wreq.u.essid.length = IW_ESSID_MAX_SIZE;
93 int rv = ioctl(ioctl_socket, SIOCGIWESSID, &wreq);
94 close(ioctl_socket);
95 return (rv == 0) ? ssid : "";
96 }
97
81 } // namespace 98 } // namespace
82 99
83 // static 100 // static
84 char* AddressTrackerLinux::GetInterfaceName(int interface_index, char* buf) { 101 char* AddressTrackerLinux::GetInterfaceName(int interface_index, char* buf) {
85 memset(buf, 0, IFNAMSIZ); 102 memset(buf, 0, IFNAMSIZ);
86 base::ScopedFD ioctl_socket(socket(AF_INET, SOCK_DGRAM, 0)); 103 base::ScopedFD ioctl_socket(socket(AF_INET, SOCK_DGRAM, 0));
87 if (!ioctl_socket.is_valid()) 104 if (!ioctl_socket.is_valid())
88 return buf; 105 return buf;
89 106
90 struct ifreq ifr = {}; 107 struct ifreq ifr = {};
91 ifr.ifr_ifindex = interface_index; 108 ifr.ifr_ifindex = interface_index;
92 109
93 if (ioctl(ioctl_socket.get(), SIOCGIFNAME, &ifr) == 0) 110 if (ioctl(ioctl_socket.get(), SIOCGIFNAME, &ifr) == 0)
94 strncpy(buf, ifr.ifr_name, IFNAMSIZ - 1); 111 strncpy(buf, ifr.ifr_name, IFNAMSIZ - 1);
95 return buf; 112 return buf;
96 } 113 }
97 114
115 // static
116 std::string AddressTrackerLinux::ConnectionSSIDFromInterfaceList(
117 const NetworkInterfaceList& interfaces,
118 GetInterfaceSSIDFunction get_interface_ssid) {
119 std::string connected_ssid;
120 bool first = true;
121 for (size_t i = 0; i < interfaces.size(); ++i) {
122 if (interfaces[i].type != NetworkChangeNotifier::CONNECTION_WIFI)
123 return "";
124 std::string ssid = get_interface_ssid(interfaces[i].name);
125 if (first) {
126 first = false;
127 connected_ssid = ssid;
128 } else if (ssid != connected_ssid) {
129 return "";
130 }
131 }
132 return connected_ssid;
133 }
134
98 AddressTrackerLinux::AddressTrackerLinux() 135 AddressTrackerLinux::AddressTrackerLinux()
99 : get_interface_name_(GetInterfaceName), 136 : get_interface_name_(GetInterfaceName),
100 address_callback_(base::Bind(&base::DoNothing)), 137 address_callback_(base::Bind(&base::DoNothing)),
101 link_callback_(base::Bind(&base::DoNothing)), 138 link_callback_(base::Bind(&base::DoNothing)),
102 tunnel_callback_(base::Bind(&base::DoNothing)), 139 tunnel_callback_(base::Bind(&base::DoNothing)),
103 netlink_fd_(-1), 140 netlink_fd_(-1),
104 connection_type_initialized_(false), 141 connection_type_initialized_(false),
105 connection_type_initialized_cv_(&connection_type_lock_), 142 connection_type_initialized_cv_(&connection_type_lock_),
106 current_connection_type_(NetworkChangeNotifier::CONNECTION_NONE), 143 current_connection_type_(NetworkChangeNotifier::CONNECTION_NONE),
107 tracking_(false) { 144 tracking_(false) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } 253 }
217 } 254 }
218 } 255 }
219 256
220 void AddressTrackerLinux::AbortAndForceOnline() { 257 void AddressTrackerLinux::AbortAndForceOnline() {
221 CloseSocket(); 258 CloseSocket();
222 AddressTrackerAutoLock lock(*this, connection_type_lock_); 259 AddressTrackerAutoLock lock(*this, connection_type_lock_);
223 current_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN; 260 current_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN;
224 connection_type_initialized_ = true; 261 connection_type_initialized_ = true;
225 connection_type_initialized_cv_.Signal(); 262 connection_type_initialized_cv_.Signal();
263 current_wifi_ssid_ = "";
226 } 264 }
227 265
228 AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const { 266 AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const {
229 AddressTrackerAutoLock lock(*this, address_map_lock_); 267 AddressTrackerAutoLock lock(*this, address_map_lock_);
230 return address_map_; 268 return address_map_;
231 } 269 }
232 270
233 base::hash_set<int> AddressTrackerLinux::GetOnlineLinks() const { 271 base::hash_set<int> AddressTrackerLinux::GetOnlineLinks() const {
234 AddressTrackerAutoLock lock(*this, online_links_lock_); 272 AddressTrackerAutoLock lock(*this, online_links_lock_);
235 return online_links_; 273 return online_links_;
236 } 274 }
237 275
238 NetworkChangeNotifier::ConnectionType 276 NetworkChangeNotifier::ConnectionType
239 AddressTrackerLinux::GetCurrentConnectionType() { 277 AddressTrackerLinux::GetCurrentConnectionType() {
240 // http://crbug.com/125097 278 // http://crbug.com/125097
241 base::ThreadRestrictions::ScopedAllowWait allow_wait; 279 base::ThreadRestrictions::ScopedAllowWait allow_wait;
242 AddressTrackerAutoLock lock(*this, connection_type_lock_); 280 AddressTrackerAutoLock lock(*this, connection_type_lock_);
243 // Make sure the initial connection type is set before returning. 281 // Make sure the initial connection type is set before returning.
244 while (!connection_type_initialized_) { 282 while (!connection_type_initialized_) {
245 connection_type_initialized_cv_.Wait(); 283 connection_type_initialized_cv_.Wait();
246 } 284 }
247 return current_connection_type_; 285 return current_connection_type_;
248 } 286 }
249 287
288 std::string AddressTrackerLinux::GetCurrentWiFiSSID() {
289 // Don't wait for initialization, return an empty SSID if not initialized.
290 AddressTrackerAutoLock lock(*this, wifi_ssid_lock_);
291 return current_wifi_ssid_;
292 }
293
250 void AddressTrackerLinux::ReadMessages(bool* address_changed, 294 void AddressTrackerLinux::ReadMessages(bool* address_changed,
251 bool* link_changed, 295 bool* link_changed,
252 bool* tunnel_changed) { 296 bool* tunnel_changed) {
253 *address_changed = false; 297 *address_changed = false;
254 *link_changed = false; 298 *link_changed = false;
255 *tunnel_changed = false; 299 *tunnel_changed = false;
256 char buffer[4096]; 300 char buffer[4096];
257 bool first_loop = true; 301 bool first_loop = true;
258 for (;;) { 302 for (;;) {
259 int rv = HANDLE_EINTR(recv(netlink_fd_, 303 int rv = HANDLE_EINTR(recv(netlink_fd_,
260 buffer, 304 buffer,
261 sizeof(buffer), 305 sizeof(buffer),
262 // Block the first time through loop. 306 // Block the first time through loop.
263 first_loop ? 0 : MSG_DONTWAIT)); 307 first_loop ? 0 : MSG_DONTWAIT));
264 first_loop = false; 308 first_loop = false;
265 if (rv == 0) { 309 if (rv == 0) {
266 LOG(ERROR) << "Unexpected shutdown of NETLINK socket."; 310 LOG(ERROR) << "Unexpected shutdown of NETLINK socket.";
267 return; 311 return;
268 } 312 }
269 if (rv < 0) { 313 if (rv < 0) {
270 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) 314 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
271 break; 315 break;
272 PLOG(ERROR) << "Failed to recv from netlink socket"; 316 PLOG(ERROR) << "Failed to recv from netlink socket";
273 return; 317 return;
274 } 318 }
275 HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed); 319 HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
276 } 320 }
277 if (*link_changed || *address_changed) 321 if (*link_changed || *address_changed)
278 UpdateCurrentConnectionType(); 322 UpdateCurrentConnectionTypeAndSSID();
279 } 323 }
280 324
281 void AddressTrackerLinux::HandleMessage(char* buffer, 325 void AddressTrackerLinux::HandleMessage(char* buffer,
282 size_t length, 326 size_t length,
283 bool* address_changed, 327 bool* address_changed,
284 bool* link_changed, 328 bool* link_changed,
285 bool* tunnel_changed) { 329 bool* tunnel_changed) {
286 DCHECK(buffer); 330 DCHECK(buffer);
287 for (struct nlmsghdr* header = reinterpret_cast<struct nlmsghdr*>(buffer); 331 for (struct nlmsghdr* header = reinterpret_cast<struct nlmsghdr*>(buffer);
288 NLMSG_OK(header, length); 332 NLMSG_OK(header, length);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 PLOG(ERROR) << "Could not close NETLINK socket."; 432 PLOG(ERROR) << "Could not close NETLINK socket.";
389 netlink_fd_ = -1; 433 netlink_fd_ = -1;
390 } 434 }
391 435
392 bool AddressTrackerLinux::IsTunnelInterface(int interface_index) const { 436 bool AddressTrackerLinux::IsTunnelInterface(int interface_index) const {
393 // Linux kernel drivers/net/tun.c uses "tun" name prefix. 437 // Linux kernel drivers/net/tun.c uses "tun" name prefix.
394 char buf[IFNAMSIZ] = {0}; 438 char buf[IFNAMSIZ] = {0};
395 return strncmp(get_interface_name_(interface_index, buf), "tun", 3) == 0; 439 return strncmp(get_interface_name_(interface_index, buf), "tun", 3) == 0;
396 } 440 }
397 441
398 void AddressTrackerLinux::UpdateCurrentConnectionType() { 442 void AddressTrackerLinux::UpdateCurrentConnectionTypeAndSSID() {
399 AddressTrackerLinux::AddressMap address_map = GetAddressMap(); 443 AddressTrackerLinux::AddressMap address_map = GetAddressMap();
400 base::hash_set<int> online_links = GetOnlineLinks(); 444 base::hash_set<int> online_links = GetOnlineLinks();
401 445
402 // Strip out tunnel interfaces from online_links 446 // Strip out tunnel interfaces from online_links
403 for (base::hash_set<int>::const_iterator it = online_links.begin(); 447 for (base::hash_set<int>::const_iterator it = online_links.begin();
404 it != online_links.end();) { 448 it != online_links.end();) {
405 if (IsTunnelInterface(*it)) { 449 if (IsTunnelInterface(*it)) {
406 base::hash_set<int>::const_iterator tunnel_it = it; 450 base::hash_set<int>::const_iterator tunnel_it = it;
407 ++it; 451 ++it;
408 online_links.erase(*tunnel_it); 452 online_links.erase(*tunnel_it);
409 } else { 453 } else {
410 ++it; 454 ++it;
411 } 455 }
412 } 456 }
413 457
414 NetworkInterfaceList networks; 458 NetworkInterfaceList networks;
415 NetworkChangeNotifier::ConnectionType type = 459 NetworkChangeNotifier::ConnectionType type =
416 NetworkChangeNotifier::CONNECTION_NONE; 460 NetworkChangeNotifier::CONNECTION_NONE;
461 std::string ssid;
417 if (GetNetworkListImpl(&networks, 0, online_links, address_map, 462 if (GetNetworkListImpl(&networks, 0, online_links, address_map,
418 get_interface_name_)) { 463 get_interface_name_)) {
419 type = NetworkChangeNotifier::ConnectionTypeFromInterfaceList(networks); 464 type = NetworkChangeNotifier::ConnectionTypeFromInterfaceList(networks);
465 ssid = ConnectionSSIDFromInterfaceList(networks, GetInterfaceSSID);
420 } else { 466 } else {
421 type = online_links.empty() ? NetworkChangeNotifier::CONNECTION_NONE 467 type = online_links.empty() ? NetworkChangeNotifier::CONNECTION_NONE
422 : NetworkChangeNotifier::CONNECTION_UNKNOWN; 468 : NetworkChangeNotifier::CONNECTION_UNKNOWN;
423 } 469 }
424 470
425 AddressTrackerAutoLock lock(*this, connection_type_lock_); 471 {
426 current_connection_type_ = type; 472 AddressTrackerAutoLock lock(*this, connection_type_lock_);
473 current_connection_type_ = type;
474 }
475 {
476 AddressTrackerAutoLock lock(*this, wifi_ssid_lock_);
477 current_wifi_ssid_ = ssid;
478 }
427 } 479 }
428 480
429 AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock( 481 AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock(
430 const AddressTrackerLinux& tracker, 482 const AddressTrackerLinux& tracker,
431 base::Lock& lock) 483 base::Lock& lock)
432 : tracker_(tracker), lock_(lock) { 484 : tracker_(tracker), lock_(lock) {
433 if (tracker_.tracking_) { 485 if (tracker_.tracking_) {
434 lock_.Acquire(); 486 lock_.Acquire();
435 } else { 487 } else {
436 DCHECK(tracker_.thread_checker_.CalledOnValidThread()); 488 DCHECK(tracker_.thread_checker_.CalledOnValidThread());
437 } 489 }
438 } 490 }
439 491
440 AddressTrackerLinux::AddressTrackerAutoLock::~AddressTrackerAutoLock() { 492 AddressTrackerLinux::AddressTrackerAutoLock::~AddressTrackerAutoLock() {
441 if (tracker_.tracking_) { 493 if (tracker_.tracking_) {
442 lock_.AssertAcquired(); 494 lock_.AssertAcquired();
443 lock_.Release(); 495 lock_.Release();
444 } 496 }
445 } 497 }
446 498
447 } // namespace internal 499 } // namespace internal
448 } // namespace net 500 } // namespace net
OLDNEW
« no previous file with comments | « net/base/address_tracker_linux.h ('k') | net/base/address_tracker_linux_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698