Avi Drissman | 6459548 | 2022-09-14 20:52:29 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "net/base/address_tracker_linux.h" |
| 6 | |
| 7 | #include <errno.h> |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 8 | #include <linux/if.h> |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 9 | #include <stdint.h> |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 10 | #include <sys/ioctl.h> |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 11 | #include <utility> |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 12 | |
Dan McArdle | 3a2da5a | 2021-07-16 21:45:47 | [diff] [blame] | 13 | #include "base/check.h" |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 14 | #include "base/files/scoped_file.h" |
Avi Drissman | 41c4a41 | 2023-01-11 22:45:37 | [diff] [blame^] | 15 | #include "base/functional/callback_helpers.h" |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 16 | #include "base/logging.h" |
[email protected] | 2025d00 | 2012-11-14 20:54:35 | [diff] [blame] | 17 | #include "base/posix/eintr_wrapper.h" |
Carlos Caballero | b25fe847 | 2020-07-17 10:27:17 | [diff] [blame] | 18 | #include "base/task/current_thread.h" |
Francois Doray | 6d62244 | 2018-05-31 22:46:32 | [diff] [blame] | 19 | #include "base/threading/scoped_blocking_call.h" |
Paul Jensen | 3a75497 | 2020-07-25 13:47:45 | [diff] [blame] | 20 | #include "build/build_config.h" |
eroman | c69886a4 | 2015-06-03 18:19:52 | [diff] [blame] | 21 | #include "net/base/network_interfaces_linux.h" |
Anton Bikineev | 068d291 | 2021-05-15 20:43:52 | [diff] [blame] | 22 | #include "third_party/abseil-cpp/absl/types/optional.h" |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 23 | |
Xiaohan Wang | 2a6845b | 2022-01-08 04:40:57 | [diff] [blame] | 24 | #if BUILDFLAG(IS_ANDROID) |
Paul Jensen | 3a75497 | 2020-07-25 13:47:45 | [diff] [blame] | 25 | #include "base/android/build_info.h" |
| 26 | #endif |
| 27 | |
Tsuyoshi Horo | 4f516be | 2022-06-14 11:53:13 | [diff] [blame] | 28 | namespace net::internal { |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 29 | |
| 30 | namespace { |
| 31 | |
derekjchow | 72407efa | 2015-06-20 02:59:43 | [diff] [blame] | 32 | // Some kernel functions such as wireless_send_event and rtnetlink_ifinfo_prep |
| 33 | // may send spurious messages over rtnetlink. RTM_NEWLINK messages where |
| 34 | // ifi_change == 0 and rta_type == IFLA_WIRELESS should be ignored. |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 35 | bool IgnoreWirelessChange(const struct ifinfomsg* msg, int length) { |
derekjchow | 72407efa | 2015-06-20 02:59:43 | [diff] [blame] | 36 | for (const struct rtattr* attr = IFLA_RTA(msg); RTA_OK(attr, length); |
| 37 | attr = RTA_NEXT(attr, length)) { |
| 38 | if (attr->rta_type == IFLA_WIRELESS && msg->ifi_change == 0) |
| 39 | return true; |
| 40 | } |
| 41 | return false; |
| 42 | } |
| 43 | |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 44 | // Retrieves address from NETLINK address message. |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 45 | // Sets |really_deprecated| for IPv6 addresses with preferred lifetimes of 0. |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 46 | // Precondition: |header| must already be validated with NLMSG_OK. |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 47 | bool GetAddress(const struct nlmsghdr* header, |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 48 | int header_length, |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 49 | IPAddress* out, |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 50 | bool* really_deprecated) { |
| 51 | if (really_deprecated) |
| 52 | *really_deprecated = false; |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 53 | |
| 54 | // Extract the message and update |header_length| to be the number of |
| 55 | // remaining bytes. |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 56 | const struct ifaddrmsg* msg = |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 57 | reinterpret_cast<const struct ifaddrmsg*>(NLMSG_DATA(header)); |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 58 | header_length -= NLMSG_HDRLEN; |
| 59 | |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 60 | size_t address_length = 0; |
| 61 | switch (msg->ifa_family) { |
| 62 | case AF_INET: |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 63 | address_length = IPAddress::kIPv4AddressSize; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 64 | break; |
| 65 | case AF_INET6: |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 66 | address_length = IPAddress::kIPv6AddressSize; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 67 | break; |
| 68 | default: |
| 69 | // Unknown family. |
| 70 | return false; |
| 71 | } |
| 72 | // Use IFA_ADDRESS unless IFA_LOCAL is present. This behavior here is based on |
| 73 | // getaddrinfo in glibc (check_pf.c). Judging from kernel implementation of |
| 74 | // NETLINK, IPv4 addresses have only the IFA_ADDRESS attribute, while IPv6 |
| 75 | // have the IFA_LOCAL attribute. |
Tsuyoshi Horo | 291961af | 2022-06-16 08:51:27 | [diff] [blame] | 76 | uint8_t* address = nullptr; |
| 77 | uint8_t* local = nullptr; |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 78 | int length = IFA_PAYLOAD(header); |
| 79 | if (length > header_length) { |
| 80 | LOG(ERROR) << "ifaddrmsg length exceeds bounds"; |
| 81 | return false; |
| 82 | } |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 83 | for (const struct rtattr* attr = |
| 84 | reinterpret_cast<const struct rtattr*>(IFA_RTA(msg)); |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 85 | RTA_OK(attr, length); attr = RTA_NEXT(attr, length)) { |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 86 | switch (attr->rta_type) { |
| 87 | case IFA_ADDRESS: |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 88 | if (RTA_PAYLOAD(attr) < address_length) { |
| 89 | LOG(ERROR) << "attr does not have enough bytes to read an address"; |
| 90 | return false; |
| 91 | } |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 92 | address = reinterpret_cast<uint8_t*>(RTA_DATA(attr)); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 93 | break; |
| 94 | case IFA_LOCAL: |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 95 | if (RTA_PAYLOAD(attr) < address_length) { |
| 96 | LOG(ERROR) << "attr does not have enough bytes to read an address"; |
| 97 | return false; |
| 98 | } |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 99 | local = reinterpret_cast<uint8_t*>(RTA_DATA(attr)); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 100 | break; |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 101 | case IFA_CACHEINFO: { |
Daniel McArdle | 53be6a4 | 2019-11-27 16:57:39 | [diff] [blame] | 102 | if (RTA_PAYLOAD(attr) < sizeof(struct ifa_cacheinfo)) { |
| 103 | LOG(ERROR) |
| 104 | << "attr does not have enough bytes to read an ifa_cacheinfo"; |
| 105 | return false; |
| 106 | } |
| 107 | const struct ifa_cacheinfo* cache_info = |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 108 | reinterpret_cast<const struct ifa_cacheinfo*>(RTA_DATA(attr)); |
| 109 | if (really_deprecated) |
| 110 | *really_deprecated = (cache_info->ifa_prefered == 0); |
| 111 | } break; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 112 | default: |
| 113 | break; |
| 114 | } |
| 115 | } |
| 116 | if (local) |
| 117 | address = local; |
| 118 | if (!address) |
| 119 | return false; |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 120 | *out = IPAddress(address, address_length); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 121 | return true; |
| 122 | } |
| 123 | |
Daniel McArdle | d499a04 | 2019-11-04 18:33:00 | [diff] [blame] | 124 | // SafelyCastNetlinkMsgData<T> performs a bounds check before casting |header|'s |
| 125 | // data to a |T*|. When the bounds check fails, returns nullptr. |
| 126 | template <typename T> |
| 127 | T* SafelyCastNetlinkMsgData(const struct nlmsghdr* header, int length) { |
| 128 | DCHECK(NLMSG_OK(header, static_cast<__u32>(length))); |
| 129 | if (length <= 0 || static_cast<size_t>(length) < NLMSG_HDRLEN + sizeof(T)) |
| 130 | return nullptr; |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 131 | return reinterpret_cast<const T*>(NLMSG_DATA(header)); |
Daniel McArdle | d499a04 | 2019-11-04 18:33:00 | [diff] [blame] | 132 | } |
| 133 | |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 134 | } // namespace |
| 135 | |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 136 | // static |
| 137 | char* AddressTrackerLinux::GetInterfaceName(int interface_index, char* buf) { |
| 138 | memset(buf, 0, IFNAMSIZ); |
pauljensen | 7a0c9f8 | 2017-05-17 20:52:00 | [diff] [blame] | 139 | base::ScopedFD ioctl_socket = GetSocketForIoctl(); |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 140 | if (!ioctl_socket.is_valid()) |
| 141 | return buf; |
| 142 | |
| 143 | struct ifreq ifr = {}; |
| 144 | ifr.ifr_ifindex = interface_index; |
| 145 | |
| 146 | if (ioctl(ioctl_socket.get(), SIOCGIFNAME, &ifr) == 0) |
| 147 | strncpy(buf, ifr.ifr_name, IFNAMSIZ - 1); |
| 148 | return buf; |
| 149 | } |
| 150 | |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 151 | AddressTrackerLinux::AddressTrackerLinux() |
| 152 | : get_interface_name_(GetInterfaceName), |
Peter Kasting | 341e1fb | 2018-02-24 00:03:01 | [diff] [blame] | 153 | address_callback_(base::DoNothing()), |
| 154 | link_callback_(base::DoNothing()), |
| 155 | tunnel_callback_(base::DoNothing()), |
dongseong.hwang | 425c269 | 2016-02-02 12:02:30 | [diff] [blame] | 156 | ignored_interfaces_(), |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 157 | connection_type_initialized_cv_(&connection_type_lock_), |
Tsuyoshi Horo | 432981d5 | 2022-06-09 09:50:13 | [diff] [blame] | 158 | tracking_(false) {} |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 159 | |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 160 | AddressTrackerLinux::AddressTrackerLinux( |
Anna Malova | ede0ba16 | 2020-03-03 15:50:08 | [diff] [blame] | 161 | const base::RepeatingClosure& address_callback, |
| 162 | const base::RepeatingClosure& link_callback, |
| 163 | const base::RepeatingClosure& tunnel_callback, |
davidben | 1e912ea | 2016-04-20 19:17:07 | [diff] [blame] | 164 | const std::unordered_set<std::string>& ignored_interfaces) |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 165 | : get_interface_name_(GetInterfaceName), |
| 166 | address_callback_(address_callback), |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 167 | link_callback_(link_callback), |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 168 | tunnel_callback_(tunnel_callback), |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 169 | ignored_interfaces_(ignored_interfaces), |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 170 | connection_type_initialized_cv_(&connection_type_lock_), |
Tsuyoshi Horo | 432981d5 | 2022-06-09 09:50:13 | [diff] [blame] | 171 | tracking_(true) { |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 172 | DCHECK(!address_callback.is_null()); |
| 173 | DCHECK(!link_callback.is_null()); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 174 | } |
| 175 | |
Paul Jensen | 05f0f978 | 2019-04-13 13:33:35 | [diff] [blame] | 176 | AddressTrackerLinux::~AddressTrackerLinux() = default; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 177 | |
| 178 | void AddressTrackerLinux::Init() { |
Xiaohan Wang | 2a6845b | 2022-01-08 04:40:57 | [diff] [blame] | 179 | #if BUILDFLAG(IS_ANDROID) |
Paul Jensen | 3a75497 | 2020-07-25 13:47:45 | [diff] [blame] | 180 | // RTM_GETLINK stopped working in Android 11 (see |
| 181 | // https://developer.android.com/preview/privacy/mac-address), |
| 182 | // so AddressTrackerLinux should not be used in later versions |
| 183 | // of Android. Chromium code doesn't need it past Android P. |
| 184 | DCHECK_LT(base::android::BuildInfo::GetInstance()->sdk_int(), |
| 185 | base::android::SDK_VERSION_P); |
| 186 | #endif |
Wez | 2d18a80 | 2019-02-01 23:44:50 | [diff] [blame] | 187 | netlink_fd_.reset(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)); |
| 188 | if (!netlink_fd_.is_valid()) { |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 189 | PLOG(ERROR) << "Could not create NETLINK socket"; |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 190 | AbortAndForceOnline(); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 191 | return; |
| 192 | } |
| 193 | |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 194 | int rv; |
| 195 | |
| 196 | if (tracking_) { |
| 197 | // Request notifications. |
| 198 | struct sockaddr_nl addr = {}; |
| 199 | addr.nl_family = AF_NETLINK; |
Dan McArdle | 70968d3 | 2021-07-19 22:15:15 | [diff] [blame] | 200 | addr.nl_pid = 0; // Let the kernel select a unique value. |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 201 | // TODO(szym): Track RTMGRP_LINK as well for ifi_type, |
| 202 | // http://crbug.com/113993 |
| 203 | addr.nl_groups = |
| 204 | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY | RTMGRP_LINK; |
Wez | 2d18a80 | 2019-02-01 23:44:50 | [diff] [blame] | 205 | rv = bind(netlink_fd_.get(), reinterpret_cast<struct sockaddr*>(&addr), |
| 206 | sizeof(addr)); |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 207 | if (rv < 0) { |
| 208 | PLOG(ERROR) << "Could not bind NETLINK socket"; |
| 209 | AbortAndForceOnline(); |
| 210 | return; |
| 211 | } |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 212 | } |
| 213 | |
| 214 | // Request dump of addresses. |
| 215 | struct sockaddr_nl peer = {}; |
| 216 | peer.nl_family = AF_NETLINK; |
| 217 | |
| 218 | struct { |
| 219 | struct nlmsghdr header; |
| 220 | struct rtgenmsg msg; |
| 221 | } request = {}; |
| 222 | |
[email protected] | ca3c1328 | 2012-12-03 21:13:29 | [diff] [blame] | 223 | request.header.nlmsg_len = NLMSG_LENGTH(sizeof(request.msg)); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 224 | request.header.nlmsg_type = RTM_GETADDR; |
| 225 | request.header.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; |
Dan McArdle | 70968d3 | 2021-07-19 22:15:15 | [diff] [blame] | 226 | request.header.nlmsg_pid = 0; // This field is opaque to netlink. |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 227 | request.msg.rtgen_family = AF_UNSPEC; |
| 228 | |
Wez | 2d18a80 | 2019-02-01 23:44:50 | [diff] [blame] | 229 | rv = HANDLE_EINTR( |
| 230 | sendto(netlink_fd_.get(), &request, request.header.nlmsg_len, 0, |
| 231 | reinterpret_cast<struct sockaddr*>(&peer), sizeof(peer))); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 232 | if (rv < 0) { |
| 233 | PLOG(ERROR) << "Could not send NETLINK request"; |
| 234 | AbortAndForceOnline(); |
| 235 | return; |
| 236 | } |
| 237 | |
| 238 | // Consume pending message to populate the AddressMap, but don't notify. |
| 239 | // Sending another request without first reading responses results in EBUSY. |
| 240 | bool address_changed; |
| 241 | bool link_changed; |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 242 | bool tunnel_changed; |
| 243 | ReadMessages(&address_changed, &link_changed, &tunnel_changed); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 244 | |
| 245 | // Request dump of link state |
| 246 | request.header.nlmsg_type = RTM_GETLINK; |
| 247 | |
Wez | 2d18a80 | 2019-02-01 23:44:50 | [diff] [blame] | 248 | rv = HANDLE_EINTR( |
| 249 | sendto(netlink_fd_.get(), &request, request.header.nlmsg_len, 0, |
| 250 | reinterpret_cast<struct sockaddr*>(&peer), sizeof(peer))); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 251 | if (rv < 0) { |
| 252 | PLOG(ERROR) << "Could not send NETLINK request"; |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 253 | AbortAndForceOnline(); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 254 | return; |
| 255 | } |
| 256 | |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 257 | // Consume pending message to populate links_online_, but don't notify. |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 258 | ReadMessages(&address_changed, &link_changed, &tunnel_changed); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 259 | { |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 260 | AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| 261 | connection_type_initialized_ = true; |
jbriance | 2600780 | 2015-11-06 20:34:34 | [diff] [blame] | 262 | connection_type_initialized_cv_.Broadcast(); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 263 | } |
[email protected] | a0a23c9 | 2012-09-05 14:28:26 | [diff] [blame] | 264 | |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 265 | if (tracking_) { |
Paul Jensen | 05f0f978 | 2019-04-13 13:33:35 | [diff] [blame] | 266 | watcher_ = base::FileDescriptorWatcher::WatchReadable( |
| 267 | netlink_fd_.get(), |
| 268 | base::BindRepeating(&AddressTrackerLinux::OnFileCanReadWithoutBlocking, |
| 269 | base::Unretained(this))); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 270 | } |
| 271 | } |
| 272 | |
Dan McArdle | 3a2da5a | 2021-07-16 21:45:47 | [diff] [blame] | 273 | bool AddressTrackerLinux::DidTrackingInitSucceedForTesting() const { |
| 274 | CHECK(tracking_); |
| 275 | return watcher_ != nullptr; |
| 276 | } |
| 277 | |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 278 | void AddressTrackerLinux::AbortAndForceOnline() { |
Paul Jensen | 05f0f978 | 2019-04-13 13:33:35 | [diff] [blame] | 279 | watcher_.reset(); |
Wez | 2d18a80 | 2019-02-01 23:44:50 | [diff] [blame] | 280 | netlink_fd_.reset(); |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 281 | AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| 282 | current_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| 283 | connection_type_initialized_ = true; |
jbriance | 2600780 | 2015-11-06 20:34:34 | [diff] [blame] | 284 | connection_type_initialized_cv_.Broadcast(); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 285 | } |
| 286 | |
| 287 | AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const { |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 288 | AddressTrackerAutoLock lock(*this, address_map_lock_); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 289 | return address_map_; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 290 | } |
| 291 | |
davidben | 1e912ea | 2016-04-20 19:17:07 | [diff] [blame] | 292 | std::unordered_set<int> AddressTrackerLinux::GetOnlineLinks() const { |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 293 | AddressTrackerAutoLock lock(*this, online_links_lock_); |
| 294 | return online_links_; |
| 295 | } |
| 296 | |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 297 | bool AddressTrackerLinux::IsInterfaceIgnored(int interface_index) const { |
| 298 | if (ignored_interfaces_.empty()) |
| 299 | return false; |
| 300 | |
| 301 | char buf[IFNAMSIZ] = {0}; |
| 302 | const char* interface_name = get_interface_name_(interface_index, buf); |
| 303 | return ignored_interfaces_.find(interface_name) != ignored_interfaces_.end(); |
| 304 | } |
| 305 | |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 306 | NetworkChangeNotifier::ConnectionType |
| 307 | AddressTrackerLinux::GetCurrentConnectionType() { |
| 308 | // http://crbug.com/125097 |
Etienne Pierre-doray | c39fa83 | 2018-11-08 17:48:18 | [diff] [blame] | 309 | base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 310 | AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| 311 | // Make sure the initial connection type is set before returning. |
jbriance | 2600780 | 2015-11-06 20:34:34 | [diff] [blame] | 312 | threads_waiting_for_connection_type_initialization_++; |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 313 | while (!connection_type_initialized_) { |
| 314 | connection_type_initialized_cv_.Wait(); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 315 | } |
jbriance | 2600780 | 2015-11-06 20:34:34 | [diff] [blame] | 316 | threads_waiting_for_connection_type_initialization_--; |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 317 | return current_connection_type_; |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 318 | } |
| 319 | |
| 320 | void AddressTrackerLinux::ReadMessages(bool* address_changed, |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 321 | bool* link_changed, |
| 322 | bool* tunnel_changed) { |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 323 | *address_changed = false; |
| 324 | *link_changed = false; |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 325 | *tunnel_changed = false; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 326 | char buffer[4096]; |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 327 | bool first_loop = true; |
Francois Doray | 6d62244 | 2018-05-31 22:46:32 | [diff] [blame] | 328 | { |
Anton Bikineev | 068d291 | 2021-05-15 20:43:52 | [diff] [blame] | 329 | absl::optional<base::ScopedBlockingCall> blocking_call; |
Etienne Pierre-doray | d98cee7 | 2018-08-24 17:55:11 | [diff] [blame] | 330 | if (tracking_) { |
| 331 | // If the loop below takes a long time to run, a new thread should added |
| 332 | // to the current thread pool to ensure forward progress of all tasks. |
Etienne Bergeron | 3d58bbd0 | 2019-02-27 18:19:21 | [diff] [blame] | 333 | blocking_call.emplace(FROM_HERE, base::BlockingType::MAY_BLOCK); |
Etienne Pierre-doray | d98cee7 | 2018-08-24 17:55:11 | [diff] [blame] | 334 | } |
Francois Doray | 6d62244 | 2018-05-31 22:46:32 | [diff] [blame] | 335 | |
| 336 | for (;;) { |
Wez | 2d18a80 | 2019-02-01 23:44:50 | [diff] [blame] | 337 | int rv = HANDLE_EINTR(recv(netlink_fd_.get(), buffer, sizeof(buffer), |
Francois Doray | 6d62244 | 2018-05-31 22:46:32 | [diff] [blame] | 338 | // Block the first time through loop. |
| 339 | first_loop ? 0 : MSG_DONTWAIT)); |
| 340 | first_loop = false; |
| 341 | if (rv == 0) { |
| 342 | LOG(ERROR) << "Unexpected shutdown of NETLINK socket."; |
| 343 | return; |
| 344 | } |
| 345 | if (rv < 0) { |
| 346 | if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) |
| 347 | break; |
| 348 | PLOG(ERROR) << "Failed to recv from netlink socket"; |
| 349 | return; |
| 350 | } |
| 351 | HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 352 | } |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 353 | } |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 354 | if (*link_changed || *address_changed) |
| 355 | UpdateCurrentConnectionType(); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 356 | } |
| 357 | |
Daniel McArdle | 9fb8369 | 2019-10-16 13:04:48 | [diff] [blame] | 358 | void AddressTrackerLinux::HandleMessage(const char* buffer, |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 359 | int length, |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 360 | bool* address_changed, |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 361 | bool* link_changed, |
| 362 | bool* tunnel_changed) { |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 363 | DCHECK(buffer); |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 364 | // Note that NLMSG_NEXT decrements |length| to reflect the number of bytes |
| 365 | // remaining in |buffer|. |
Daniel McArdle | 9fb8369 | 2019-10-16 13:04:48 | [diff] [blame] | 366 | for (const struct nlmsghdr* header = |
| 367 | reinterpret_cast<const struct nlmsghdr*>(buffer); |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 368 | length >= 0 && NLMSG_OK(header, static_cast<__u32>(length)); |
| 369 | header = NLMSG_NEXT(header, length)) { |
| 370 | // The |header| pointer should never precede |buffer|. |
| 371 | DCHECK_LE(buffer, reinterpret_cast<const char*>(header)); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 372 | switch (header->nlmsg_type) { |
| 373 | case NLMSG_DONE: |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 374 | return; |
| 375 | case NLMSG_ERROR: { |
| 376 | const struct nlmsgerr* msg = |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 377 | SafelyCastNetlinkMsgData<const struct nlmsgerr>(header, length); |
Daniel McArdle | d499a04 | 2019-11-04 18:33:00 | [diff] [blame] | 378 | if (msg == nullptr) |
| 379 | return; |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 380 | LOG(ERROR) << "Unexpected netlink error " << msg->error << "."; |
| 381 | } return; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 382 | case RTM_NEWADDR: { |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 383 | IPAddress address; |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 384 | bool really_deprecated; |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 385 | const struct ifaddrmsg* msg = |
| 386 | SafelyCastNetlinkMsgData<const struct ifaddrmsg>(header, length); |
Daniel McArdle | d499a04 | 2019-11-04 18:33:00 | [diff] [blame] | 387 | if (msg == nullptr) |
| 388 | return; |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 389 | if (IsInterfaceIgnored(msg->ifa_index)) |
| 390 | break; |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 391 | if (GetAddress(header, length, &address, &really_deprecated)) { |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 392 | struct ifaddrmsg msg_copy = *msg; |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 393 | AddressTrackerAutoLock lock(*this, address_map_lock_); |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 394 | // Routers may frequently (every few seconds) output the IPv6 ULA |
| 395 | // prefix which can cause the linux kernel to frequently output two |
| 396 | // back-to-back messages, one without the deprecated flag and one with |
| 397 | // the deprecated flag but both with preferred lifetimes of 0. Avoid |
Tsuyoshi Horo | 5c4f4e4 | 2022-07-29 05:51:51 | [diff] [blame] | 398 | // interpreting this as an actual change by canonicalizing the two |
[email protected] | fb5dead | 2014-01-23 18:12:20 | [diff] [blame] | 399 | // messages by setting the deprecated flag based on the preferred |
| 400 | // lifetime also. http://crbug.com/268042 |
| 401 | if (really_deprecated) |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 402 | msg_copy.ifa_flags |= IFA_F_DEPRECATED; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 403 | // Only indicate change if the address is new or ifaddrmsg info has |
| 404 | // changed. |
jdoerrie | 22a91d8b9 | 2018-10-05 08:43:26 | [diff] [blame] | 405 | auto it = address_map_.find(address); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 406 | if (it == address_map_.end()) { |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 407 | address_map_.insert(it, std::make_pair(address, msg_copy)); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 408 | *address_changed = true; |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 409 | } else if (memcmp(&it->second, &msg_copy, sizeof(msg_copy))) { |
| 410 | it->second = msg_copy; |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 411 | *address_changed = true; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 412 | } |
| 413 | } |
| 414 | } break; |
| 415 | case RTM_DELADDR: { |
martijn | fe8914e | 2016-03-09 08:33:44 | [diff] [blame] | 416 | IPAddress address; |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 417 | const struct ifaddrmsg* msg = |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 418 | SafelyCastNetlinkMsgData<const struct ifaddrmsg>(header, length); |
Daniel McArdle | d499a04 | 2019-11-04 18:33:00 | [diff] [blame] | 419 | if (msg == nullptr) |
| 420 | return; |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 421 | if (IsInterfaceIgnored(msg->ifa_index)) |
| 422 | break; |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 423 | if (GetAddress(header, length, &address, nullptr)) { |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 424 | AddressTrackerAutoLock lock(*this, address_map_lock_); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 425 | if (address_map_.erase(address)) |
| 426 | *address_changed = true; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 427 | } |
| 428 | } break; |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 429 | case RTM_NEWLINK: { |
| 430 | const struct ifinfomsg* msg = |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 431 | SafelyCastNetlinkMsgData<const struct ifinfomsg>(header, length); |
Daniel McArdle | d499a04 | 2019-11-04 18:33:00 | [diff] [blame] | 432 | if (msg == nullptr) |
| 433 | return; |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 434 | if (IsInterfaceIgnored(msg->ifi_index)) |
| 435 | break; |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 436 | if (IgnoreWirelessChange(msg, IFLA_PAYLOAD(header))) { |
derekjchow | 72407efa | 2015-06-20 02:59:43 | [diff] [blame] | 437 | VLOG(2) << "Ignoring RTM_NEWLINK message"; |
| 438 | break; |
| 439 | } |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 440 | if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) && |
| 441 | (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) { |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 442 | AddressTrackerAutoLock lock(*this, online_links_lock_); |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 443 | if (online_links_.insert(msg->ifi_index).second) { |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 444 | *link_changed = true; |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 445 | if (IsTunnelInterface(msg->ifi_index)) |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 446 | *tunnel_changed = true; |
| 447 | } |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 448 | } else { |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 449 | AddressTrackerAutoLock lock(*this, online_links_lock_); |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 450 | if (online_links_.erase(msg->ifi_index)) { |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 451 | *link_changed = true; |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 452 | if (IsTunnelInterface(msg->ifi_index)) |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 453 | *tunnel_changed = true; |
| 454 | } |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 455 | } |
| 456 | } break; |
| 457 | case RTM_DELLINK: { |
| 458 | const struct ifinfomsg* msg = |
Daniel McArdle | 69d47446 | 2019-12-02 16:36:03 | [diff] [blame] | 459 | SafelyCastNetlinkMsgData<const struct ifinfomsg>(header, length); |
Daniel McArdle | d499a04 | 2019-11-04 18:33:00 | [diff] [blame] | 460 | if (msg == nullptr) |
| 461 | return; |
derekjchow | ea1725c | 2015-05-08 03:16:01 | [diff] [blame] | 462 | if (IsInterfaceIgnored(msg->ifi_index)) |
| 463 | break; |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 464 | AddressTrackerAutoLock lock(*this, online_links_lock_); |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 465 | if (online_links_.erase(msg->ifi_index)) { |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 466 | *link_changed = true; |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 467 | if (IsTunnelInterface(msg->ifi_index)) |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 468 | *tunnel_changed = true; |
| 469 | } |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 470 | } break; |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 471 | default: |
| 472 | break; |
| 473 | } |
| 474 | } |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 475 | } |
| 476 | |
Paul Jensen | 05f0f978 | 2019-04-13 13:33:35 | [diff] [blame] | 477 | void AddressTrackerLinux::OnFileCanReadWithoutBlocking() { |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 478 | bool address_changed; |
| 479 | bool link_changed; |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 480 | bool tunnel_changed; |
| 481 | ReadMessages(&address_changed, &link_changed, &tunnel_changed); |
[email protected] | d3eada5 | 2012-11-29 17:11:55 | [diff] [blame] | 482 | if (address_changed) |
| 483 | address_callback_.Run(); |
| 484 | if (link_changed) |
| 485 | link_callback_.Run(); |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 486 | if (tunnel_changed) |
| 487 | tunnel_callback_.Run(); |
[email protected] | 6717280 | 2012-07-16 22:27:24 | [diff] [blame] | 488 | } |
| 489 | |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 490 | bool AddressTrackerLinux::IsTunnelInterface(int interface_index) const { |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 491 | char buf[IFNAMSIZ] = {0}; |
Miriam Gershenson | a97831b2 | 2018-01-31 16:06:14 | [diff] [blame] | 492 | return IsTunnelInterfaceName(get_interface_name_(interface_index, buf)); |
| 493 | } |
| 494 | |
| 495 | // static |
| 496 | bool AddressTrackerLinux::IsTunnelInterfaceName(const char* name) { |
| 497 | // Linux kernel drivers/net/tun.c uses "tun" name prefix. |
| 498 | return strncmp(name, "tun", 3) == 0; |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 499 | } |
| 500 | |
| 501 | void AddressTrackerLinux::UpdateCurrentConnectionType() { |
| 502 | AddressTrackerLinux::AddressMap address_map = GetAddressMap(); |
davidben | 1e912ea | 2016-04-20 19:17:07 | [diff] [blame] | 503 | std::unordered_set<int> online_links = GetOnlineLinks(); |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 504 | |
| 505 | // Strip out tunnel interfaces from online_links |
jdoerrie | 22a91d8b9 | 2018-10-05 08:43:26 | [diff] [blame] | 506 | for (auto it = online_links.cbegin(); it != online_links.cend();) { |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 507 | if (IsTunnelInterface(*it)) { |
jdoerrie | 22a91d8b9 | 2018-10-05 08:43:26 | [diff] [blame] | 508 | it = online_links.erase(it); |
derekjchow | 5482d5e | 2015-01-31 01:04:51 | [diff] [blame] | 509 | } else { |
| 510 | ++it; |
| 511 | } |
| 512 | } |
| 513 | |
| 514 | NetworkInterfaceList networks; |
| 515 | NetworkChangeNotifier::ConnectionType type = |
| 516 | NetworkChangeNotifier::CONNECTION_NONE; |
| 517 | if (GetNetworkListImpl(&networks, 0, online_links, address_map, |
| 518 | get_interface_name_)) { |
| 519 | type = NetworkChangeNotifier::ConnectionTypeFromInterfaceList(networks); |
| 520 | } else { |
| 521 | type = online_links.empty() ? NetworkChangeNotifier::CONNECTION_NONE |
| 522 | : NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| 523 | } |
| 524 | |
| 525 | AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| 526 | current_connection_type_ = type; |
[email protected] | cf71d77 | 2014-02-09 10:44:07 | [diff] [blame] | 527 | } |
| 528 | |
Daniel McArdle | 47d0507 | 2019-10-18 18:27:28 | [diff] [blame] | 529 | int AddressTrackerLinux::GetThreadsWaitingForConnectionTypeInitForTesting() { |
jbriance | 2600780 | 2015-11-06 20:34:34 | [diff] [blame] | 530 | AddressTrackerAutoLock lock(*this, connection_type_lock_); |
| 531 | return threads_waiting_for_connection_type_initialization_; |
| 532 | } |
| 533 | |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 534 | AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock( |
| 535 | const AddressTrackerLinux& tracker, |
| 536 | base::Lock& lock) |
| 537 | : tracker_(tracker), lock_(lock) { |
Ali Hijazi | 5517919 | 2022-11-09 16:28:51 | [diff] [blame] | 538 | if (tracker_->tracking_) { |
| 539 | lock_->Acquire(); |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 540 | } else { |
Ali Hijazi | 5517919 | 2022-11-09 16:28:51 | [diff] [blame] | 541 | DCHECK(tracker_->thread_checker_.CalledOnValidThread()); |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 542 | } |
| 543 | } |
| 544 | |
| 545 | AddressTrackerLinux::AddressTrackerAutoLock::~AddressTrackerAutoLock() { |
Ali Hijazi | 5517919 | 2022-11-09 16:28:51 | [diff] [blame] | 546 | if (tracker_->tracking_) { |
| 547 | lock_->AssertAcquired(); |
| 548 | lock_->Release(); |
guoweis | f09e997 | 2014-09-22 20:47:43 | [diff] [blame] | 549 | } |
| 550 | } |
| 551 | |
Tsuyoshi Horo | 4f516be | 2022-06-14 11:53:13 | [diff] [blame] | 552 | } // namespace net::internal |