summaryrefslogtreecommitdiff
path: root/net/base/address_tracker_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/base/address_tracker_linux.cc')
-rw-r--r--net/base/address_tracker_linux.cc80
1 files changed, 72 insertions, 8 deletions
diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc
index d90e022b2..431820f20 100644
--- a/net/base/address_tracker_linux.cc
+++ b/net/base/address_tracker_linux.cc
@@ -15,6 +15,7 @@
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/sequence_checker.h"
#include "base/task/current_thread.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_restrictions.h"
@@ -172,11 +173,13 @@ AddressTrackerLinux::AddressTrackerLinux(
tracking_(true) {
DCHECK(!address_callback.is_null());
DCHECK(!link_callback.is_null());
+ DETACH_FROM_SEQUENCE(sequence_checker_);
}
AddressTrackerLinux::~AddressTrackerLinux() = default;
void AddressTrackerLinux::Init() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if BUILDFLAG(IS_ANDROID)
// RTM_GETLINK stopped working in Android 11 (see
// https://developer.android.com/preview/privacy/mac-address),
@@ -241,7 +244,8 @@ void AddressTrackerLinux::Init() {
bool address_changed;
bool link_changed;
bool tunnel_changed;
- ReadMessages(&address_changed, &link_changed, &tunnel_changed);
+ ReadMessages(&address_changed, &link_changed, &tunnel_changed, nullptr,
+ nullptr);
// Request dump of link state
request.header.nlmsg_type = RTM_GETLINK;
@@ -256,7 +260,8 @@ void AddressTrackerLinux::Init() {
}
// Consume pending message to populate links_online_, but don't notify.
- ReadMessages(&address_changed, &link_changed, &tunnel_changed);
+ ReadMessages(&address_changed, &link_changed, &tunnel_changed, nullptr,
+ nullptr);
{
AddressTrackerAutoLock lock(*this, connection_type_lock_);
connection_type_initialized_ = true;
@@ -272,11 +277,13 @@ void AddressTrackerLinux::Init() {
}
bool AddressTrackerLinux::DidTrackingInitSucceedForTesting() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
CHECK(tracking_);
return watcher_ != nullptr;
}
void AddressTrackerLinux::AbortAndForceOnline() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
watcher_.reset();
netlink_fd_.reset();
AddressTrackerAutoLock lock(*this, connection_type_lock_);
@@ -295,7 +302,28 @@ std::unordered_set<int> AddressTrackerLinux::GetOnlineLinks() const {
return online_links_;
}
+void AddressTrackerLinux::SetDiffCallback(DiffCallback diff_callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ diff_callback_ = std::move(diff_callback);
+
+ // Send the initial configuration to the diff callback.
+ AddressMap address_map = GetAddressMap();
+ AddressMapDiff address_map_diff;
+ for (const std::pair<const IPAddress, struct ifaddrmsg>& it : address_map) {
+ address_map_diff[it.first] = it.second;
+ }
+
+ std::unordered_set<int> online_links = GetOnlineLinks();
+ OnlineLinksDiff online_links_diff;
+ for (int online_link : online_links) {
+ online_links_diff[online_link] = true;
+ }
+
+ diff_callback_.Run(address_map_diff, online_links_diff);
+}
+
bool AddressTrackerLinux::IsInterfaceIgnored(int interface_index) const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (ignored_interfaces_.empty())
return false;
@@ -320,7 +348,10 @@ AddressTrackerLinux::GetCurrentConnectionType() {
void AddressTrackerLinux::ReadMessages(bool* address_changed,
bool* link_changed,
- bool* tunnel_changed) {
+ bool* tunnel_changed,
+ AddressMapDiff* address_map_diff,
+ OnlineLinksDiff* online_links_diff) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
*address_changed = false;
*link_changed = false;
*tunnel_changed = false;
@@ -349,7 +380,8 @@ void AddressTrackerLinux::ReadMessages(bool* address_changed,
PLOG(ERROR) << "Failed to recv from netlink socket";
return;
}
- HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
+ HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed,
+ address_map_diff, online_links_diff);
}
}
if (*link_changed || *address_changed)
@@ -360,7 +392,10 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
int length,
bool* address_changed,
bool* link_changed,
- bool* tunnel_changed) {
+ bool* tunnel_changed,
+ AddressMapDiff* address_map_diff,
+ OnlineLinksDiff* online_links_diff) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(buffer);
// Note that NLMSG_NEXT decrements |length| to reflect the number of bytes
// remaining in |buffer|.
@@ -411,6 +446,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
it->second = msg_copy;
*address_changed = true;
}
+ if (*address_changed && address_map_diff) {
+ (*address_map_diff)[address] = msg_copy;
+ }
}
} break;
case RTM_DELADDR: {
@@ -423,8 +461,12 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
break;
if (GetAddress(header, length, &address, nullptr)) {
AddressTrackerAutoLock lock(*this, address_map_lock_);
- if (address_map_.erase(address))
+ if (address_map_.erase(address)) {
*address_changed = true;
+ if (address_map_diff) {
+ (*address_map_diff)[address] = absl::nullopt;
+ }
+ }
}
} break;
case RTM_NEWLINK: {
@@ -443,6 +485,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
AddressTrackerAutoLock lock(*this, online_links_lock_);
if (online_links_.insert(msg->ifi_index).second) {
*link_changed = true;
+ if (online_links_diff) {
+ (*online_links_diff)[msg->ifi_index] = true;
+ }
if (IsTunnelInterface(msg->ifi_index))
*tunnel_changed = true;
}
@@ -450,6 +495,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
AddressTrackerAutoLock lock(*this, online_links_lock_);
if (online_links_.erase(msg->ifi_index)) {
*link_changed = true;
+ if (online_links_diff) {
+ (*online_links_diff)[msg->ifi_index] = false;
+ }
if (IsTunnelInterface(msg->ifi_index))
*tunnel_changed = true;
}
@@ -465,6 +513,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
AddressTrackerAutoLock lock(*this, online_links_lock_);
if (online_links_.erase(msg->ifi_index)) {
*link_changed = true;
+ if (online_links_diff) {
+ (*online_links_diff)[msg->ifi_index] = false;
+ }
if (IsTunnelInterface(msg->ifi_index))
*tunnel_changed = true;
}
@@ -476,10 +527,20 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
}
void AddressTrackerLinux::OnFileCanReadWithoutBlocking() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
bool address_changed;
bool link_changed;
bool tunnel_changed;
- ReadMessages(&address_changed, &link_changed, &tunnel_changed);
+ if (diff_callback_) {
+ AddressMapDiff address_map_diff;
+ OnlineLinksDiff online_links_diff;
+ ReadMessages(&address_changed, &link_changed, &tunnel_changed,
+ &address_map_diff, &online_links_diff);
+ diff_callback_.Run(address_map_diff, online_links_diff);
+ } else {
+ ReadMessages(&address_changed, &link_changed, &tunnel_changed, nullptr,
+ nullptr);
+ }
if (address_changed)
address_callback_.Run();
if (link_changed)
@@ -500,6 +561,7 @@ bool AddressTrackerLinux::IsTunnelInterfaceName(const char* name) {
}
void AddressTrackerLinux::UpdateCurrentConnectionType() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
AddressTrackerLinux::AddressMap address_map = GetAddressMap();
std::unordered_set<int> online_links = GetOnlineLinks();
@@ -539,7 +601,7 @@ AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock(
if (tracker_->tracking_) {
lock_->Acquire();
} else {
- DCHECK(tracker_->thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(tracker_->sequence_checker_);
}
}
@@ -547,6 +609,8 @@ AddressTrackerLinux::AddressTrackerAutoLock::~AddressTrackerAutoLock() {
if (tracker_->tracking_) {
lock_->AssertAcquired();
lock_->Release();
+ } else {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(tracker_->sequence_checker_);
}
}