| Index: net/base/address_tracker_linux.cc
|
| diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc
|
| index 367381366954f3280e9171f5d93405f05ed667d7..afed4d56fa674a40ebf2ae9f25362d0f75abda3f 100644
|
| --- a/net/base/address_tracker_linux.cc
|
| +++ b/net/base/address_tracker_linux.cc
|
| @@ -116,7 +116,7 @@ AddressTrackerLinux::~AddressTrackerLinux() {
|
| CloseSocket();
|
| }
|
|
|
| -void AddressTrackerLinux::Init() {
|
| +void AddressTrackerLinux::Init(bool track) {
|
| netlink_fd_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
| if (netlink_fd_ < 0) {
|
| PLOG(ERROR) << "Could not create NETLINK socket";
|
| @@ -124,20 +124,24 @@ void AddressTrackerLinux::Init() {
|
| return;
|
| }
|
|
|
| - // Request notifications.
|
| - struct sockaddr_nl addr = {};
|
| - addr.nl_family = AF_NETLINK;
|
| - addr.nl_pid = getpid();
|
| - // TODO(szym): Track RTMGRP_LINK as well for ifi_type, http://crbug.com/113993
|
| - addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY |
|
| - RTMGRP_LINK;
|
| - int rv = bind(netlink_fd_,
|
| - reinterpret_cast<struct sockaddr*>(&addr),
|
| - sizeof(addr));
|
| - if (rv < 0) {
|
| - PLOG(ERROR) << "Could not bind NETLINK socket";
|
| - AbortAndForceOnline();
|
| - return;
|
| + int rv;
|
| +
|
| + if (track) {
|
| + // Request notifications.
|
| + struct sockaddr_nl addr = {};
|
| + addr.nl_family = AF_NETLINK;
|
| + addr.nl_pid = getpid();
|
| + // TODO(szym): Track RTMGRP_LINK as well for ifi_type,
|
| + // http://crbug.com/113993
|
| + addr.nl_groups =
|
| + RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY | RTMGRP_LINK;
|
| + rv = bind(
|
| + netlink_fd_, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
|
| + if (rv < 0) {
|
| + PLOG(ERROR) << "Could not bind NETLINK socket";
|
| + AbortAndForceOnline();
|
| + return;
|
| + }
|
| }
|
|
|
| // Request dump of addresses.
|
| @@ -191,12 +195,14 @@ void AddressTrackerLinux::Init() {
|
| is_offline_initialized_cv_.Signal();
|
| }
|
|
|
| - rv = base::MessageLoopForIO::current()->WatchFileDescriptor(
|
| - netlink_fd_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
|
| - if (rv < 0) {
|
| - PLOG(ERROR) << "Could not watch NETLINK socket";
|
| - AbortAndForceOnline();
|
| - return;
|
| + if (track) {
|
| + rv = base::MessageLoopForIO::current()->WatchFileDescriptor(
|
| + netlink_fd_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
|
| + if (rv < 0) {
|
| + PLOG(ERROR) << "Could not watch NETLINK socket";
|
| + AbortAndForceOnline();
|
| + return;
|
| + }
|
| }
|
| }
|
|
|
| @@ -213,6 +219,11 @@ AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const {
|
| return address_map_;
|
| }
|
|
|
| +base::hash_set<int> AddressTrackerLinux::GetOnlineLinks() const {
|
| + base::AutoLock lock(online_links_lock_);
|
| + return online_links_;
|
| +}
|
| +
|
| NetworkChangeNotifier::ConnectionType
|
| AddressTrackerLinux::GetCurrentConnectionType() {
|
| // http://crbug.com/125097
|
| @@ -254,10 +265,15 @@ void AddressTrackerLinux::ReadMessages(bool* address_changed,
|
| return;
|
| }
|
| HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
|
| - };
|
| + }
|
| if (*link_changed) {
|
| + bool is_offline;
|
| + {
|
| + base::AutoLock lock(online_links_lock_);
|
| + is_offline = online_links_.empty();
|
| + }
|
| base::AutoLock lock(is_offline_lock_);
|
| - is_offline_ = online_links_.empty();
|
| + is_offline_ = is_offline;
|
| }
|
| }
|
|
|
| @@ -319,12 +335,14 @@ void AddressTrackerLinux::HandleMessage(char* buffer,
|
| reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header));
|
| if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) &&
|
| (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) {
|
| + base::AutoLock lock(online_links_lock_);
|
| if (online_links_.insert(msg->ifi_index).second) {
|
| *link_changed = true;
|
| if (IsTunnelInterface(msg))
|
| *tunnel_changed = true;
|
| }
|
| } else {
|
| + base::AutoLock lock(online_links_lock_);
|
| if (online_links_.erase(msg->ifi_index)) {
|
| *link_changed = true;
|
| if (IsTunnelInterface(msg))
|
| @@ -335,6 +353,7 @@ void AddressTrackerLinux::HandleMessage(char* buffer,
|
| case RTM_DELLINK: {
|
| const struct ifinfomsg* msg =
|
| reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header));
|
| + base::AutoLock lock(online_links_lock_);
|
| if (online_links_.erase(msg->ifi_index)) {
|
| *link_changed = true;
|
| if (IsTunnelInterface(msg))
|
|
|