Chromium Code Reviews| Index: net/base/address_tracker_linux.cc |
| diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc |
| index 27dd2019ab0dffd6392dee105b7ae11ba7b6e138..3659434092e7d08428a9d289d5a72c5064e42544 100644 |
| --- a/net/base/address_tracker_linux.cc |
| +++ b/net/base/address_tracker_linux.cc |
| @@ -4,6 +4,7 @@ |
| #include "net/base/address_tracker_linux.h" |
| +#include <arpa/inet.h> |
| #include <errno.h> |
| #include <linux/if.h> |
| #include <sys/ioctl.h> |
| @@ -11,6 +12,9 @@ |
| #include "base/logging.h" |
| #include "base/posix/eintr_wrapper.h" |
| #include "base/threading/thread_restrictions.h" |
| +#include "net/base/ip_endpoint.h" |
| +#include "net/base/net_util_linux.h" |
|
pauljensen
2015/01/15 15:05:10
net_util_linux.h#8 says it's not for general purpo
derekjchow1
2015/01/15 20:32:51
Done.
We use GetInterfaceName as an argument to G
|
| +#include "net/base/net_util_posix.h" |
| namespace net { |
| namespace internal { |
| @@ -76,25 +80,6 @@ bool GetAddress(const struct nlmsghdr* header, |
| return true; |
| } |
| -// Returns the name for the interface with interface index |interface_index|. |
| -// The return value points to a function-scoped static so it may be changed by |
| -// subsequent calls. This function could be replaced with if_indextoname() but |
| -// net/if.h cannot be mixed with linux/if.h so we'll stick with exclusively |
| -// talking to the kernel and not the C library. |
| -const char* GetInterfaceName(int interface_index) { |
| - int ioctl_socket = socket(AF_INET, SOCK_DGRAM, 0); |
| - if (ioctl_socket < 0) |
| - return ""; |
| - static struct ifreq ifr; |
| - memset(&ifr, 0, sizeof(ifr)); |
| - ifr.ifr_ifindex = interface_index; |
| - int rv = ioctl(ioctl_socket, SIOCGIFNAME, &ifr); |
| - close(ioctl_socket); |
| - if (rv != 0) |
| - return ""; |
| - return ifr.ifr_name; |
| -} |
| - |
| } // namespace |
| AddressTrackerLinux::AddressTrackerLinux() |
| @@ -103,9 +88,9 @@ AddressTrackerLinux::AddressTrackerLinux() |
| link_callback_(base::Bind(&base::DoNothing)), |
| tunnel_callback_(base::Bind(&base::DoNothing)), |
| netlink_fd_(-1), |
| - is_offline_(true), |
| - is_offline_initialized_(false), |
| - is_offline_initialized_cv_(&is_offline_lock_), |
| + connection_type_initialized_(false), |
| + connection_type_initialized_cv_(&connection_type_lock_), |
| + current_connection_type_(NetworkChangeNotifier::CONNECTION_NONE), |
| tracking_(false) { |
| } |
| @@ -117,9 +102,9 @@ AddressTrackerLinux::AddressTrackerLinux(const base::Closure& address_callback, |
| link_callback_(link_callback), |
| tunnel_callback_(tunnel_callback), |
| netlink_fd_(-1), |
| - is_offline_(true), |
| - is_offline_initialized_(false), |
| - is_offline_initialized_cv_(&is_offline_lock_), |
| + connection_type_initialized_(false), |
| + connection_type_initialized_cv_(&connection_type_lock_), |
| + current_connection_type_(NetworkChangeNotifier::CONNECTION_NONE), |
| tracking_(true) { |
| DCHECK(!address_callback.is_null()); |
| DCHECK(!link_callback.is_null()); |
| @@ -203,9 +188,9 @@ void AddressTrackerLinux::Init() { |
| // Consume pending message to populate links_online_, but don't notify. |
| ReadMessages(&address_changed, &link_changed, &tunnel_changed); |
| { |
| - AddressTrackerAutoLock lock(*this, is_offline_lock_); |
| - is_offline_initialized_ = true; |
| - is_offline_initialized_cv_.Signal(); |
| + AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| + connection_type_initialized_ = true; |
| + connection_type_initialized_cv_.Signal(); |
| } |
| if (tracking_) { |
| @@ -221,10 +206,10 @@ void AddressTrackerLinux::Init() { |
| void AddressTrackerLinux::AbortAndForceOnline() { |
| CloseSocket(); |
| - AddressTrackerAutoLock lock(*this, is_offline_lock_); |
| - is_offline_ = false; |
| - is_offline_initialized_ = true; |
| - is_offline_initialized_cv_.Signal(); |
| + AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| + current_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| + connection_type_initialized_ = true; |
| + connection_type_initialized_cv_.Signal(); |
| } |
| AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const { |
| @@ -241,15 +226,12 @@ NetworkChangeNotifier::ConnectionType |
| AddressTrackerLinux::GetCurrentConnectionType() { |
| // http://crbug.com/125097 |
| base::ThreadRestrictions::ScopedAllowWait allow_wait; |
| - AddressTrackerAutoLock lock(*this, is_offline_lock_); |
| - // Make sure the initial offline state is set before returning. |
| - while (!is_offline_initialized_) { |
| - is_offline_initialized_cv_.Wait(); |
| + AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| + // Make sure the initial connection type is set before returning. |
| + while (!connection_type_initialized_) { |
| + connection_type_initialized_cv_.Wait(); |
| } |
| - // TODO(droger): Return something more detailed than CONNECTION_UNKNOWN. |
| - // http://crbug.com/160537 |
| - return is_offline_ ? NetworkChangeNotifier::CONNECTION_NONE : |
| - NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| + return current_connection_type_; |
| } |
| void AddressTrackerLinux::ReadMessages(bool* address_changed, |
| @@ -279,14 +261,8 @@ void AddressTrackerLinux::ReadMessages(bool* address_changed, |
| } |
| HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed); |
| } |
| - if (*link_changed) { |
| - bool is_offline; |
| - { |
| - AddressTrackerAutoLock lock(*this, online_links_lock_); |
| - is_offline = online_links_.empty(); |
| - } |
| - AddressTrackerAutoLock lock(*this, is_offline_lock_); |
| - is_offline_ = is_offline; |
| + if (*link_changed || *address_changed) { |
|
pauljensen
2015/01/15 15:05:10
doesn't need curly braces anymore
derekjchow1
2015/01/15 20:32:51
Done.
|
| + UpdateCurrentConnectionType(); |
| } |
| } |
| @@ -403,7 +379,23 @@ void AddressTrackerLinux::CloseSocket() { |
| bool AddressTrackerLinux::IsTunnelInterface(const struct ifinfomsg* msg) const { |
| // Linux kernel drivers/net/tun.c uses "tun" name prefix. |
| - return strncmp(get_interface_name_(msg->ifi_index), "tun", 3) == 0; |
| + char buf[IFNAMSIZ] = {0}; |
| + return strncmp(get_interface_name_(msg->ifi_index, buf), "tun", 3) == 0; |
| +} |
| + |
| +void AddressTrackerLinux::UpdateCurrentConnectionType() { |
| + NetworkChangeNotifier::ConnectionType type = |
| + NetworkChangeNotifier::CONNECTION_NONE; |
| + base::hash_set<int> online_links = GetOnlineLinks(); |
| + AddressTrackerLinux::AddressMap address_map = GetAddressMap(); |
| + NetworkInterfaceList networks; |
| + if (GetNetworkListImpl(&networks, 0, online_links, address_map, |
| + get_interface_name_)) { |
| + type = ConnectionTypeFromInterfaceList(networks); |
| + } |
|
pauljensen
2015/01/15 15:05:10
if GetNetworkListImpl fails we should fall back to
derekjchow1
2015/01/15 20:32:51
Done.
|
| + |
| + AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| + current_connection_type_ = type; |
| } |
| AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock( |