// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/address_tracker_linux.h"

#include <errno.h>
#include <linux/if.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <vector>
#include <utility>

#include "base/check.h"
#include "base/dcheck_is_on.h"
#include "base/files/scoped_file.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/page_size.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"
#include "build/build_config.h"
#include "net/base/network_interfaces_linux.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#endif

namespace net::internal {

namespace {

// Some kernel functions such as wireless_send_event and rtnetlink_ifinfo_prep
// may send spurious messages over rtnetlink. RTM_NEWLINK messages where
// ifi_change == 0 and rta_type == IFLA_WIRELESS should be ignored.
bool IgnoreWirelessChange(const struct ifinfomsg* msg, int length) {
  for (const struct rtattr* attr = IFLA_RTA(msg); RTA_OK(attr, length);
       attr = RTA_NEXT(attr, length)) {
    if (attr->rta_type == IFLA_WIRELESS && msg->ifi_change == 0)
      return true;
  }
  return false;
}

// Retrieves address from NETLINK address message.
// Sets |really_deprecated| for IPv6 addresses with preferred lifetimes of 0.
// Precondition: |header| must already be validated with NLMSG_OK.
bool GetAddress(const struct nlmsghdr* header,
                int header_length,
                IPAddress* out,
                bool* really_deprecated) {
  if (really_deprecated)
    *really_deprecated = false;

  // Extract the message and update |header_length| to be the number of
  // remaining bytes.
  const struct ifaddrmsg* msg =
      reinterpret_cast<const struct ifaddrmsg*>(NLMSG_DATA(header));
  header_length -= NLMSG_HDRLEN;

  size_t address_length = 0;
  switch (msg->ifa_family) {
    case AF_INET:
      address_length = IPAddress::kIPv4AddressSize;
      break;
    case AF_INET6:
      address_length = IPAddress::kIPv6AddressSize;
      break;
    default:
      // Unknown family.
      return false;
  }
  // Use IFA_ADDRESS unless IFA_LOCAL is present. This behavior here is based on
  // getaddrinfo in glibc (check_pf.c). Judging from kernel implementation of
  // NETLINK, IPv4 addresses have only the IFA_ADDRESS attribute, while IPv6
  // have the IFA_LOCAL attribute.
  uint8_t* address = nullptr;
  uint8_t* local = nullptr;
  int length = IFA_PAYLOAD(header);
  if (length > header_length) {
    LOG(ERROR) << "ifaddrmsg length exceeds bounds";
    return false;
  }
  for (const struct rtattr* attr =
           reinterpret_cast<const struct rtattr*>(IFA_RTA(msg));
       RTA_OK(attr, length); attr = RTA_NEXT(attr, length)) {
    switch (attr->rta_type) {
      case IFA_ADDRESS:
        if (RTA_PAYLOAD(attr) < address_length) {
          LOG(ERROR) << "attr does not have enough bytes to read an address";
          return false;
        }
        address = reinterpret_cast<uint8_t*>(RTA_DATA(attr));
        break;
      case IFA_LOCAL:
        if (RTA_PAYLOAD(attr) < address_length) {
          LOG(ERROR) << "attr does not have enough bytes to read an address";
          return false;
        }
        local = reinterpret_cast<uint8_t*>(RTA_DATA(attr));
        break;
      case IFA_CACHEINFO: {
        if (RTA_PAYLOAD(attr) < sizeof(struct ifa_cacheinfo)) {
          LOG(ERROR)
              << "attr does not have enough bytes to read an ifa_cacheinfo";
          return false;
        }
        const struct ifa_cacheinfo* cache_info =
            reinterpret_cast<const struct ifa_cacheinfo*>(RTA_DATA(attr));
        if (really_deprecated)
          *really_deprecated = (cache_info->ifa_prefered == 0);
      } break;
      default:
        break;
    }
  }
  if (local)
    address = local;
  if (!address)
    return false;
  *out = IPAddress(address, address_length);
  return true;
}

// SafelyCastNetlinkMsgData<T> performs a bounds check before casting |header|'s
// data to a |T*|. When the bounds check fails, returns nullptr.
template <typename T>
T* SafelyCastNetlinkMsgData(const struct nlmsghdr* header, int length) {
  DCHECK(NLMSG_OK(header, static_cast<__u32>(length)));
  if (length <= 0 || static_cast<size_t>(length) < NLMSG_HDRLEN + sizeof(T))
    return nullptr;
  return reinterpret_cast<const T*>(NLMSG_DATA(header));
}

}  // namespace

// static
char* AddressTrackerLinux::GetInterfaceName(int interface_index, char* buf) {
  memset(buf, 0, IFNAMSIZ);
  base::ScopedFD ioctl_socket = GetSocketForIoctl();
  if (!ioctl_socket.is_valid())
    return buf;

  struct ifreq ifr = {};
  ifr.ifr_ifindex = interface_index;

  if (ioctl(ioctl_socket.get(), SIOCGIFNAME, &ifr) == 0)
    strncpy(buf, ifr.ifr_name, IFNAMSIZ - 1);
  return buf;
}

AddressTrackerLinux::AddressTrackerLinux()
    : get_interface_name_(GetInterfaceName),
      address_callback_(base::DoNothing()),
      link_callback_(base::DoNothing()),
      tunnel_callback_(base::DoNothing()),
      ignored_interfaces_(),
      connection_type_initialized_cv_(&connection_type_lock_),
      tracking_(false) {}

AddressTrackerLinux::AddressTrackerLinux(
    const base::RepeatingClosure& address_callback,
    const base::RepeatingClosure& link_callback,
    const base::RepeatingClosure& tunnel_callback,
    const std::unordered_set<std::string>& ignored_interfaces,
    scoped_refptr<base::SequencedTaskRunner> blocking_thread_runner)
    : get_interface_name_(GetInterfaceName),
      address_callback_(address_callback),
      link_callback_(link_callback),
      tunnel_callback_(tunnel_callback),
      ignored_interfaces_(ignored_interfaces),
      connection_type_initialized_cv_(&connection_type_lock_),
      tracking_(true),
      sequenced_task_runner_(std::move(blocking_thread_runner)) {
  DCHECK(!address_callback.is_null());
  DCHECK(!link_callback.is_null());
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

AddressTrackerLinux::~AddressTrackerLinux() = default;

void AddressTrackerLinux::InitWithFdForTesting(base::ScopedFD fd) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  netlink_fd_ = std::move(fd);
  DumpInitialAddressesAndWatch();
}

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),
  // so AddressTrackerLinux should not be used in later versions
  // of Android.  Chromium code doesn't need it past Android P.
  DCHECK_LT(base::android::BuildInfo::GetInstance()->sdk_int(),
            base::android::SDK_VERSION_P);
#endif
  netlink_fd_.reset(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE));
  if (!netlink_fd_.is_valid()) {
    PLOG(ERROR) << "Could not create NETLINK socket";
    AbortAndForceOnline();
    return;
  }

  int rv;

  if (tracking_) {
    // Request notifications.
    struct sockaddr_nl addr = {};
    addr.nl_family = AF_NETLINK;
    addr.nl_pid = 0;  // Let the kernel select a unique value.
    // 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_.get(), reinterpret_cast<struct sockaddr*>(&addr),
              sizeof(addr));
    if (rv < 0) {
      PLOG(ERROR) << "Could not bind NETLINK socket";
      AbortAndForceOnline();
      return;
    }
  }

  DumpInitialAddressesAndWatch();
}

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_);
  current_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN;
  connection_type_initialized_ = true;
  connection_type_initialized_cv_.Broadcast();
}

AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const {
  AddressTrackerAutoLock lock(*this, address_map_lock_);
  return address_map_;
}

std::unordered_set<int> AddressTrackerLinux::GetOnlineLinks() const {
  AddressTrackerAutoLock lock(*this, online_links_lock_);
  return online_links_;
}

AddressTrackerLinux* AddressTrackerLinux::GetAddressTrackerLinux() {
  return this;
}

std::pair<AddressTrackerLinux::AddressMap, std::unordered_set<int>>
AddressTrackerLinux::GetInitialDataAndStartRecordingDiffs() {
  DCHECK(tracking_);
  AddressTrackerAutoLock lock_address_map(*this, address_map_lock_);
  AddressTrackerAutoLock lock_online_links(*this, online_links_lock_);
  address_map_diff_ = AddressMapDiff();
  online_links_diff_ = OnlineLinksDiff();
  return {address_map_, online_links_};
}

void AddressTrackerLinux::SetDiffCallback(DiffCallback diff_callback) {
  DCHECK(tracking_);
  DCHECK(sequenced_task_runner_);

  if (!sequenced_task_runner_->RunsTasksInCurrentSequence()) {
    sequenced_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&AddressTrackerLinux::SetDiffCallback,
                                  weak_ptr_factory_.GetWeakPtr(),
                                  std::move(diff_callback)));
    return;
  }

  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
  {
    // GetInitialDataAndStartRecordingDiffs() must be called before
    // SetDiffCallback().
    AddressTrackerAutoLock lock_address_map(*this, address_map_lock_);
    AddressTrackerAutoLock lock_online_links(*this, online_links_lock_);
    DCHECK(address_map_diff_.has_value());
    DCHECK(online_links_diff_.has_value());
  }
#endif  // DCHECK_IS_ON()
  diff_callback_ = std::move(diff_callback);
  RunDiffCallback();
}

bool AddressTrackerLinux::IsInterfaceIgnored(int interface_index) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (ignored_interfaces_.empty())
    return false;

  char buf[IFNAMSIZ] = {0};
  const char* interface_name = get_interface_name_(interface_index, buf);
  return ignored_interfaces_.find(interface_name) != ignored_interfaces_.end();
}

NetworkChangeNotifier::ConnectionType
AddressTrackerLinux::GetCurrentConnectionType() {
  // http://crbug.com/125097
  base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
  AddressTrackerAutoLock lock(*this, connection_type_lock_);
  // Make sure the initial connection type is set before returning.
  threads_waiting_for_connection_type_initialization_++;
  while (!connection_type_initialized_) {
    connection_type_initialized_cv_.Wait();
  }
  threads_waiting_for_connection_type_initialization_--;
  return current_connection_type_;
}

void AddressTrackerLinux::DumpInitialAddressesAndWatch() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Request dump of addresses.
  struct sockaddr_nl peer = {};
  peer.nl_family = AF_NETLINK;

  struct {
    struct nlmsghdr header;
    struct rtgenmsg msg;
  } request = {};

  request.header.nlmsg_len = NLMSG_LENGTH(sizeof(request.msg));
  request.header.nlmsg_type = RTM_GETADDR;
  request.header.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  request.header.nlmsg_pid = 0;  // This field is opaque to netlink.
  request.msg.rtgen_family = AF_UNSPEC;

  int rv = HANDLE_EINTR(
      sendto(netlink_fd_.get(), &request, request.header.nlmsg_len, 0,
             reinterpret_cast<struct sockaddr*>(&peer), sizeof(peer)));
  if (rv < 0) {
    PLOG(ERROR) << "Could not send NETLINK request";
    AbortAndForceOnline();
    return;
  }

  // Consume pending message to populate the AddressMap, but don't notify.
  // Sending another request without first reading responses results in EBUSY.
  bool address_changed;
  bool link_changed;
  bool tunnel_changed;
  ReadMessages(&address_changed, &link_changed, &tunnel_changed);

  // Request dump of link state
  request.header.nlmsg_type = RTM_GETLINK;

  rv = HANDLE_EINTR(
      sendto(netlink_fd_.get(), &request, request.header.nlmsg_len, 0,
             reinterpret_cast<struct sockaddr*>(&peer), sizeof(peer)));
  if (rv < 0) {
    PLOG(ERROR) << "Could not send NETLINK request";
    AbortAndForceOnline();
    return;
  }

  // Consume pending message to populate links_online_, but don't notify.
  ReadMessages(&address_changed, &link_changed, &tunnel_changed);
  {
    AddressTrackerAutoLock lock(*this, connection_type_lock_);
    connection_type_initialized_ = true;
    connection_type_initialized_cv_.Broadcast();
  }

  if (tracking_) {
    DCHECK(!sequenced_task_runner_ ||
           sequenced_task_runner_->RunsTasksInCurrentSequence());

    watcher_ = base::FileDescriptorWatcher::WatchReadable(
        netlink_fd_.get(),
        base::BindRepeating(&AddressTrackerLinux::OnFileCanReadWithoutBlocking,
                            base::Unretained(this)));
  }
}

void AddressTrackerLinux::ReadMessages(bool* address_changed,
                                       bool* link_changed,
                                       bool* tunnel_changed) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  *address_changed = false;
  *link_changed = false;
  *tunnel_changed = false;
  bool first_loop = true;

  // Varying sources have different opinions regarding the buffer size needed
  // for netlink messages to avoid truncation:
  // - The official documentation on netlink says messages are generally 8kb
  //   or the system page size, whichever is *larger*:
  //   https://www.kernel.org/doc/html/v6.2/userspace-api/netlink/intro.html#buffer-sizing
  // - The kernel headers would imply that messages are generally the system
  //   page size or 8kb, whichever is *smaller*:
  //   https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/netlink.h?h=v6.2.2#n226
  //   (libmnl follows this.)
  // - The netlink(7) man page's example always uses a fixed size 8kb buffer:
  //   https://man7.org/linux/man-pages/man7/netlink.7.html
  // Here, we follow the guidelines in the documentation, for two primary
  // reasons:
  // - Erring on the side of a larger size is the safer way to go to avoid
  //   MSG_TRUNC.
  // - Since this is heap-allocated anyway, there's no risk to the stack by
  //   using the larger size.

  constexpr size_t kMinNetlinkBufferSize = 8 * 1024;
  std::vector<char> buffer(
      std::max(base::GetPageSize(), kMinNetlinkBufferSize));

  {
    absl::optional<base::ScopedBlockingCall> blocking_call;
    if (tracking_) {
      // If the loop below takes a long time to run, a new thread should added
      // to the current thread pool to ensure forward progress of all tasks.
      blocking_call.emplace(FROM_HERE, base::BlockingType::MAY_BLOCK);
    }

    for (;;) {
      int rv =
          HANDLE_EINTR(recv(netlink_fd_.get(), buffer.data(), buffer.size(),
                            // Block the first time through loop.
                            first_loop ? 0 : MSG_DONTWAIT));
      first_loop = false;
      if (rv == 0) {
        LOG(ERROR) << "Unexpected shutdown of NETLINK socket.";
        return;
      }
      if (rv < 0) {
        if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
          break;
        PLOG(ERROR) << "Failed to recv from netlink socket";
        return;
      }
      HandleMessage(buffer.data(), rv, address_changed, link_changed,
                    tunnel_changed);
    }
  }
  if (*link_changed || *address_changed)
    UpdateCurrentConnectionType();
}

void AddressTrackerLinux::HandleMessage(const char* buffer,
                                        int length,
                                        bool* address_changed,
                                        bool* link_changed,
                                        bool* tunnel_changed) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(buffer);
  // Note that NLMSG_NEXT decrements |length| to reflect the number of bytes
  // remaining in |buffer|.
  for (const struct nlmsghdr* header =
           reinterpret_cast<const struct nlmsghdr*>(buffer);
       length >= 0 && NLMSG_OK(header, static_cast<__u32>(length));
       header = NLMSG_NEXT(header, length)) {
    // The |header| pointer should never precede |buffer|.
    DCHECK_LE(buffer, reinterpret_cast<const char*>(header));
    switch (header->nlmsg_type) {
      case NLMSG_DONE:
        return;
      case NLMSG_ERROR: {
        const struct nlmsgerr* msg =
            SafelyCastNetlinkMsgData<const struct nlmsgerr>(header, length);
        if (msg == nullptr)
          return;
        LOG(ERROR) << "Unexpected netlink error " << msg->error << ".";
      } return;
      case RTM_NEWADDR: {
        IPAddress address;
        bool really_deprecated;
        const struct ifaddrmsg* msg =
            SafelyCastNetlinkMsgData<const struct ifaddrmsg>(header, length);
        if (msg == nullptr)
          return;
        if (IsInterfaceIgnored(msg->ifa_index))
          break;
        if (GetAddress(header, length, &address, &really_deprecated)) {
          struct ifaddrmsg msg_copy = *msg;
          AddressTrackerAutoLock lock(*this, address_map_lock_);
          // Routers may frequently (every few seconds) output the IPv6 ULA
          // prefix which can cause the linux kernel to frequently output two
          // back-to-back messages, one without the deprecated flag and one with
          // the deprecated flag but both with preferred lifetimes of 0. Avoid
          // interpreting this as an actual change by canonicalizing the two
          // messages by setting the deprecated flag based on the preferred
          // lifetime also.  http://crbug.com/268042
          if (really_deprecated)
            msg_copy.ifa_flags |= IFA_F_DEPRECATED;
          // Only indicate change if the address is new or ifaddrmsg info has
          // changed.
          auto it = address_map_.find(address);
          if (it == address_map_.end()) {
            address_map_.insert(it, std::make_pair(address, msg_copy));
            *address_changed = true;
          } else if (memcmp(&it->second, &msg_copy, sizeof(msg_copy))) {
            it->second = msg_copy;
            *address_changed = true;
          }
          if (*address_changed && address_map_diff_.has_value()) {
            (*address_map_diff_)[address] = msg_copy;
          }
        }
      } break;
      case RTM_DELADDR: {
        IPAddress address;
        const struct ifaddrmsg* msg =
            SafelyCastNetlinkMsgData<const struct ifaddrmsg>(header, length);
        if (msg == nullptr)
          return;
        if (IsInterfaceIgnored(msg->ifa_index))
          break;
        if (GetAddress(header, length, &address, nullptr)) {
          AddressTrackerAutoLock lock(*this, address_map_lock_);
          if (address_map_.erase(address)) {
            *address_changed = true;
            if (address_map_diff_.has_value()) {
              (*address_map_diff_)[address] = absl::nullopt;
            }
          }
        }
      } break;
      case RTM_NEWLINK: {
        const struct ifinfomsg* msg =
            SafelyCastNetlinkMsgData<const struct ifinfomsg>(header, length);
        if (msg == nullptr)
          return;
        if (IsInterfaceIgnored(msg->ifi_index))
          break;
        if (IgnoreWirelessChange(msg, IFLA_PAYLOAD(header))) {
          VLOG(2) << "Ignoring RTM_NEWLINK message";
          break;
        }
        if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) &&
            (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) {
          AddressTrackerAutoLock lock(*this, online_links_lock_);
          if (online_links_.insert(msg->ifi_index).second) {
            *link_changed = true;
            if (online_links_diff_.has_value()) {
              (*online_links_diff_)[msg->ifi_index] = true;
            }
            if (IsTunnelInterface(msg->ifi_index))
              *tunnel_changed = true;
          }
        } else {
          AddressTrackerAutoLock lock(*this, online_links_lock_);
          if (online_links_.erase(msg->ifi_index)) {
            *link_changed = true;
            if (online_links_diff_.has_value()) {
              (*online_links_diff_)[msg->ifi_index] = false;
            }
            if (IsTunnelInterface(msg->ifi_index))
              *tunnel_changed = true;
          }
        }
      } break;
      case RTM_DELLINK: {
        const struct ifinfomsg* msg =
            SafelyCastNetlinkMsgData<const struct ifinfomsg>(header, length);
        if (msg == nullptr)
          return;
        if (IsInterfaceIgnored(msg->ifi_index))
          break;
        AddressTrackerAutoLock lock(*this, online_links_lock_);
        if (online_links_.erase(msg->ifi_index)) {
          *link_changed = true;
          if (online_links_diff_.has_value()) {
            (*online_links_diff_)[msg->ifi_index] = false;
          }
          if (IsTunnelInterface(msg->ifi_index))
            *tunnel_changed = true;
        }
      } break;
      default:
        break;
    }
  }
}

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_) {
    RunDiffCallback();
  }
  if (address_changed) {
    address_callback_.Run();
  }
  if (link_changed) {
    link_callback_.Run();
  }
  if (tunnel_changed) {
    tunnel_callback_.Run();
  }
}

bool AddressTrackerLinux::IsTunnelInterface(int interface_index) const {
  char buf[IFNAMSIZ] = {0};
  return IsTunnelInterfaceName(get_interface_name_(interface_index, buf));
}

// static
bool AddressTrackerLinux::IsTunnelInterfaceName(const char* name) {
  // Linux kernel drivers/net/tun.c uses "tun" name prefix.
  return strncmp(name, "tun", 3) == 0;
}

void AddressTrackerLinux::UpdateCurrentConnectionType() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  AddressTrackerLinux::AddressMap address_map = GetAddressMap();
  std::unordered_set<int> online_links = GetOnlineLinks();

  // Strip out tunnel interfaces from online_links
  for (auto it = online_links.cbegin(); it != online_links.cend();) {
    if (IsTunnelInterface(*it)) {
      it = online_links.erase(it);
    } else {
      ++it;
    }
  }

  NetworkInterfaceList networks;
  NetworkChangeNotifier::ConnectionType type =
      NetworkChangeNotifier::CONNECTION_NONE;
  if (GetNetworkListImpl(&networks, 0, online_links, address_map,
                         get_interface_name_)) {
    type = NetworkChangeNotifier::ConnectionTypeFromInterfaceList(networks);
  } else {
    type = online_links.empty() ? NetworkChangeNotifier::CONNECTION_NONE
                                : NetworkChangeNotifier::CONNECTION_UNKNOWN;
  }

  AddressTrackerAutoLock lock(*this, connection_type_lock_);
  current_connection_type_ = type;
}

void AddressTrackerLinux::RunDiffCallback() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(tracking_);
  DCHECK(address_map_diff_.has_value());
  DCHECK(online_links_diff_.has_value());
  // It's fine to access `address_map_diff_` and `online_links_diff_` without
  // any locking here, as the only time they are ever accessed on another thread
  // is in GetInitialDataAndStartRecordingDiffs(). But
  // GetInitialDataAndStartRecordingDiffs() must be called before
  // SetDiffCallback(), which must be called before RunDiffCallback(), so this
  // function cannot overlap with any modifications on another thread.

  // There should be a diff or the DiffCallback shouldn't be run.
  if (address_map_diff_->empty() && online_links_diff_->empty()) {
    return;
  }
  diff_callback_.Run(address_map_diff_.value(), online_links_diff_.value());
  address_map_diff_->clear();
  online_links_diff_->clear();
}

int AddressTrackerLinux::GetThreadsWaitingForConnectionTypeInitForTesting() {
  AddressTrackerAutoLock lock(*this, connection_type_lock_);
  return threads_waiting_for_connection_type_initialization_;
}

AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock(
    const AddressTrackerLinux& tracker,
    base::Lock& lock)
    : tracker_(tracker), lock_(lock) {
  if (tracker_->tracking_) {
    lock_->Acquire();
  } else {
    DCHECK_CALLED_ON_VALID_SEQUENCE(tracker_->sequence_checker_);
  }
}

AddressTrackerLinux::AddressTrackerAutoLock::~AddressTrackerAutoLock() {
  if (tracker_->tracking_) {
    lock_->AssertAcquired();
    lock_->Release();
  } else {
    DCHECK_CALLED_ON_VALID_SEQUENCE(tracker_->sequence_checker_);
  }
}

}  // namespace net::internal
