address_tracker_linux_unittest.cc 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/base/address_tracker_linux.h"
  5. #include <linux/if.h>
  6. #include <sched.h>
  7. #include <memory>
  8. #include <unordered_set>
  9. #include <vector>
  10. #include "base/bind.h"
  11. #include "base/callback_helpers.h"
  12. #include "base/command_line.h"
  13. #include "base/files/file_util.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/strings/string_number_conversions.h"
  16. #include "base/synchronization/waitable_event.h"
  17. #include "base/test/multiprocess_test.h"
  18. #include "base/test/spin_wait.h"
  19. #include "base/test/task_environment.h"
  20. #include "base/test/test_simple_task_runner.h"
  21. #include "base/threading/simple_thread.h"
  22. #include "build/build_config.h"
  23. #include "net/base/ip_address.h"
  24. #include "testing/gtest/include/gtest/gtest.h"
  25. #include "testing/multiprocess_func_list.h"
  26. #if BUILDFLAG(IS_ANDROID)
  27. #include "base/android/build_info.h"
  28. #endif
  29. #ifndef IFA_F_HOMEADDRESS
  30. #define IFA_F_HOMEADDRESS 0x10
  31. #endif
  32. namespace net::internal {
  33. namespace {
  34. const int kTestInterfaceEth = 1;
  35. const int kTestInterfaceWifi = 2;
  36. const int kTestInterfaceTun = 123;
  37. const int kTestInterfaceAp = 456;
  38. const char kIgnoredInterfaceName[] = "uap0";
  39. char* TestGetInterfaceName(int interface_index, char* buf) {
  40. if (interface_index == kTestInterfaceEth) {
  41. snprintf(buf, IFNAMSIZ, "%s", "eth0");
  42. } else if (interface_index == kTestInterfaceTun) {
  43. snprintf(buf, IFNAMSIZ, "%s", "tun0");
  44. } else if (interface_index == kTestInterfaceAp) {
  45. snprintf(buf, IFNAMSIZ, "%s", kIgnoredInterfaceName);
  46. } else {
  47. snprintf(buf, IFNAMSIZ, "%s", "");
  48. }
  49. return buf;
  50. }
  51. } // namespace
  52. typedef std::vector<char> Buffer;
  53. class AddressTrackerLinuxTest : public testing::Test {
  54. protected:
  55. AddressTrackerLinuxTest() = default;
  56. void InitializeAddressTracker(bool tracking) {
  57. if (tracking) {
  58. tracker_ = std::make_unique<AddressTrackerLinux>(
  59. base::DoNothing(), base::DoNothing(), base::DoNothing(),
  60. ignored_interfaces_);
  61. } else {
  62. tracker_ = std::make_unique<AddressTrackerLinux>();
  63. }
  64. original_get_interface_name_ = tracker_->get_interface_name_;
  65. tracker_->get_interface_name_ = TestGetInterfaceName;
  66. }
  67. bool HandleAddressMessage(const Buffer& buf) {
  68. Buffer writable_buf = buf;
  69. bool address_changed = false;
  70. bool link_changed = false;
  71. bool tunnel_changed = false;
  72. tracker_->HandleMessage(&writable_buf[0], buf.size(),
  73. &address_changed, &link_changed, &tunnel_changed);
  74. EXPECT_FALSE(link_changed);
  75. return address_changed;
  76. }
  77. bool HandleLinkMessage(const Buffer& buf) {
  78. Buffer writable_buf = buf;
  79. bool address_changed = false;
  80. bool link_changed = false;
  81. bool tunnel_changed = false;
  82. tracker_->HandleMessage(&writable_buf[0], buf.size(),
  83. &address_changed, &link_changed, &tunnel_changed);
  84. EXPECT_FALSE(address_changed);
  85. return link_changed;
  86. }
  87. bool HandleTunnelMessage(const Buffer& buf) {
  88. Buffer writable_buf = buf;
  89. bool address_changed = false;
  90. bool link_changed = false;
  91. bool tunnel_changed = false;
  92. tracker_->HandleMessage(&writable_buf[0], buf.size(),
  93. &address_changed, &link_changed, &tunnel_changed);
  94. EXPECT_FALSE(address_changed);
  95. return tunnel_changed;
  96. }
  97. AddressTrackerLinux::AddressMap GetAddressMap() {
  98. return tracker_->GetAddressMap();
  99. }
  100. const std::unordered_set<int> GetOnlineLinks() const {
  101. return tracker_->GetOnlineLinks();
  102. }
  103. void IgnoreInterface(const std::string& interface_name) {
  104. ignored_interfaces_.insert(interface_name);
  105. }
  106. int GetThreadsWaitingForConnectionTypeInit() {
  107. return tracker_->GetThreadsWaitingForConnectionTypeInitForTesting();
  108. }
  109. std::unordered_set<std::string> ignored_interfaces_;
  110. std::unique_ptr<AddressTrackerLinux> tracker_;
  111. AddressTrackerLinux::GetInterfaceNameFunction original_get_interface_name_;
  112. };
  113. namespace {
  114. class NetlinkMessage {
  115. public:
  116. explicit NetlinkMessage(uint16_t type) : buffer_(NLMSG_HDRLEN) {
  117. header()->nlmsg_type = type;
  118. Align();
  119. }
  120. void AddPayload(const void* data, size_t length) {
  121. CHECK_EQ(static_cast<size_t>(NLMSG_HDRLEN),
  122. buffer_.size()) << "Payload must be added first";
  123. Append(data, length);
  124. Align();
  125. }
  126. void AddAttribute(uint16_t type, const void* data, size_t length) {
  127. struct nlattr attr;
  128. attr.nla_len = NLA_HDRLEN + length;
  129. attr.nla_type = type;
  130. Append(&attr, sizeof(attr));
  131. Align();
  132. Append(data, length);
  133. Align();
  134. }
  135. void AppendTo(Buffer* output) const {
  136. CHECK_EQ(NLMSG_ALIGN(output->size()), output->size());
  137. output->reserve(output->size() + NLMSG_LENGTH(buffer_.size()));
  138. output->insert(output->end(), buffer_.begin(), buffer_.end());
  139. }
  140. private:
  141. void Append(const void* data, size_t length) {
  142. const char* chardata = reinterpret_cast<const char*>(data);
  143. buffer_.insert(buffer_.end(), chardata, chardata + length);
  144. }
  145. void Align() {
  146. header()->nlmsg_len = buffer_.size();
  147. buffer_.insert(buffer_.end(), NLMSG_ALIGN(buffer_.size()) - buffer_.size(),
  148. 0);
  149. CHECK(NLMSG_OK(header(), buffer_.size()));
  150. }
  151. struct nlmsghdr* header() {
  152. return reinterpret_cast<struct nlmsghdr*>(&buffer_[0]);
  153. }
  154. Buffer buffer_;
  155. };
  156. #define INFINITY_LIFE_TIME 0xFFFFFFFF
  157. void MakeAddrMessageWithCacheInfo(uint16_t type,
  158. uint8_t flags,
  159. uint8_t family,
  160. int index,
  161. const IPAddress& address,
  162. const IPAddress& local,
  163. uint32_t preferred_lifetime,
  164. Buffer* output) {
  165. NetlinkMessage nlmsg(type);
  166. struct ifaddrmsg msg = {};
  167. msg.ifa_family = family;
  168. msg.ifa_flags = flags;
  169. msg.ifa_index = index;
  170. nlmsg.AddPayload(&msg, sizeof(msg));
  171. if (address.size())
  172. nlmsg.AddAttribute(IFA_ADDRESS, address.bytes().data(), address.size());
  173. if (local.size())
  174. nlmsg.AddAttribute(IFA_LOCAL, local.bytes().data(), local.size());
  175. struct ifa_cacheinfo cache_info = {};
  176. cache_info.ifa_prefered = preferred_lifetime;
  177. cache_info.ifa_valid = INFINITY_LIFE_TIME;
  178. nlmsg.AddAttribute(IFA_CACHEINFO, &cache_info, sizeof(cache_info));
  179. nlmsg.AppendTo(output);
  180. }
  181. void MakeAddrMessage(uint16_t type,
  182. uint8_t flags,
  183. uint8_t family,
  184. int index,
  185. const IPAddress& address,
  186. const IPAddress& local,
  187. Buffer* output) {
  188. MakeAddrMessageWithCacheInfo(type, flags, family, index, address, local,
  189. INFINITY_LIFE_TIME, output);
  190. }
  191. void MakeLinkMessage(uint16_t type,
  192. uint32_t flags,
  193. uint32_t index,
  194. Buffer* output) {
  195. NetlinkMessage nlmsg(type);
  196. struct ifinfomsg msg = {};
  197. msg.ifi_index = index;
  198. msg.ifi_flags = flags;
  199. nlmsg.AddPayload(&msg, sizeof(msg));
  200. output->clear();
  201. nlmsg.AppendTo(output);
  202. }
  203. // Creates a netlink message generated by wireless_send_event. These events
  204. // should be ignored.
  205. void MakeWirelessLinkMessage(uint16_t type,
  206. uint32_t flags,
  207. uint32_t index,
  208. Buffer* output) {
  209. NetlinkMessage nlmsg(type);
  210. struct ifinfomsg msg = {};
  211. msg.ifi_index = index;
  212. msg.ifi_flags = flags;
  213. msg.ifi_change = 0;
  214. nlmsg.AddPayload(&msg, sizeof(msg));
  215. char data[8] = {0};
  216. nlmsg.AddAttribute(IFLA_WIRELESS, data, sizeof(data));
  217. output->clear();
  218. nlmsg.AppendTo(output);
  219. }
  220. const unsigned char kAddress0[] = { 127, 0, 0, 1 };
  221. const unsigned char kAddress1[] = { 10, 0, 0, 1 };
  222. const unsigned char kAddress2[] = { 192, 168, 0, 1 };
  223. const unsigned char kAddress3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  224. 0, 0, 0, 1 };
  225. TEST_F(AddressTrackerLinuxTest, NewAddress) {
  226. InitializeAddressTracker(true);
  227. const IPAddress kEmpty;
  228. const IPAddress kAddr0(kAddress0);
  229. const IPAddress kAddr1(kAddress1);
  230. const IPAddress kAddr2(kAddress2);
  231. const IPAddress kAddr3(kAddress3);
  232. Buffer buffer;
  233. MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kTestInterfaceEth,
  234. kAddr0, kEmpty, &buffer);
  235. EXPECT_TRUE(HandleAddressMessage(buffer));
  236. AddressTrackerLinux::AddressMap map = GetAddressMap();
  237. EXPECT_EQ(1u, map.size());
  238. EXPECT_EQ(1u, map.count(kAddr0));
  239. EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
  240. buffer.clear();
  241. MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kTestInterfaceEth,
  242. kAddr1, kAddr2, &buffer);
  243. EXPECT_TRUE(HandleAddressMessage(buffer));
  244. map = GetAddressMap();
  245. EXPECT_EQ(2u, map.size());
  246. EXPECT_EQ(1u, map.count(kAddr0));
  247. EXPECT_EQ(1u, map.count(kAddr2));
  248. EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr2].ifa_flags);
  249. buffer.clear();
  250. MakeAddrMessage(RTM_NEWADDR, 0, AF_INET6, kTestInterfaceEth, kEmpty, kAddr3,
  251. &buffer);
  252. EXPECT_TRUE(HandleAddressMessage(buffer));
  253. map = GetAddressMap();
  254. EXPECT_EQ(3u, map.size());
  255. EXPECT_EQ(1u, map.count(kAddr3));
  256. }
  257. TEST_F(AddressTrackerLinuxTest, NewAddressChange) {
  258. InitializeAddressTracker(true);
  259. const IPAddress kEmpty;
  260. const IPAddress kAddr0(kAddress0);
  261. Buffer buffer;
  262. MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kTestInterfaceEth,
  263. kAddr0, kEmpty, &buffer);
  264. EXPECT_TRUE(HandleAddressMessage(buffer));
  265. AddressTrackerLinux::AddressMap map = GetAddressMap();
  266. EXPECT_EQ(1u, map.size());
  267. EXPECT_EQ(1u, map.count(kAddr0));
  268. EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
  269. buffer.clear();
  270. MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kTestInterfaceEth,
  271. kAddr0, kEmpty, &buffer);
  272. EXPECT_TRUE(HandleAddressMessage(buffer));
  273. map = GetAddressMap();
  274. EXPECT_EQ(1u, map.size());
  275. EXPECT_EQ(1u, map.count(kAddr0));
  276. EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr0].ifa_flags);
  277. // Both messages in one buffer.
  278. buffer.clear();
  279. MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kTestInterfaceEth,
  280. kAddr0, kEmpty, &buffer);
  281. MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kTestInterfaceEth,
  282. kAddr0, kEmpty, &buffer);
  283. EXPECT_TRUE(HandleAddressMessage(buffer));
  284. map = GetAddressMap();
  285. EXPECT_EQ(1u, map.size());
  286. EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr0].ifa_flags);
  287. }
  288. TEST_F(AddressTrackerLinuxTest, NewAddressDuplicate) {
  289. InitializeAddressTracker(true);
  290. const IPAddress kAddr0(kAddress0);
  291. Buffer buffer;
  292. MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kTestInterfaceEth,
  293. kAddr0, kAddr0, &buffer);
  294. EXPECT_TRUE(HandleAddressMessage(buffer));
  295. AddressTrackerLinux::AddressMap map = GetAddressMap();
  296. EXPECT_EQ(1u, map.size());
  297. EXPECT_EQ(1u, map.count(kAddr0));
  298. EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
  299. EXPECT_FALSE(HandleAddressMessage(buffer));
  300. map = GetAddressMap();
  301. EXPECT_EQ(1u, map.size());
  302. EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
  303. }
  304. TEST_F(AddressTrackerLinuxTest, DeleteAddress) {
  305. InitializeAddressTracker(true);
  306. const IPAddress kEmpty;
  307. const IPAddress kAddr0(kAddress0);
  308. const IPAddress kAddr1(kAddress1);
  309. const IPAddress kAddr2(kAddress2);
  310. Buffer buffer;
  311. MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kTestInterfaceEth, kAddr0, kEmpty,
  312. &buffer);
  313. MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kTestInterfaceEth, kAddr1, kAddr2,
  314. &buffer);
  315. EXPECT_TRUE(HandleAddressMessage(buffer));
  316. AddressTrackerLinux::AddressMap map = GetAddressMap();
  317. EXPECT_EQ(2u, map.size());
  318. buffer.clear();
  319. MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kTestInterfaceEth, kEmpty, kAddr0,
  320. &buffer);
  321. EXPECT_TRUE(HandleAddressMessage(buffer));
  322. map = GetAddressMap();
  323. EXPECT_EQ(1u, map.size());
  324. EXPECT_EQ(0u, map.count(kAddr0));
  325. EXPECT_EQ(1u, map.count(kAddr2));
  326. buffer.clear();
  327. MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kTestInterfaceEth, kAddr2, kAddr1,
  328. &buffer);
  329. // kAddr1 does not exist in the map.
  330. EXPECT_FALSE(HandleAddressMessage(buffer));
  331. map = GetAddressMap();
  332. EXPECT_EQ(1u, map.size());
  333. buffer.clear();
  334. MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kTestInterfaceEth, kAddr2, kEmpty,
  335. &buffer);
  336. EXPECT_TRUE(HandleAddressMessage(buffer));
  337. map = GetAddressMap();
  338. EXPECT_EQ(0u, map.size());
  339. }
  340. TEST_F(AddressTrackerLinuxTest, DeprecatedLifetime) {
  341. InitializeAddressTracker(true);
  342. const IPAddress kEmpty;
  343. const IPAddress kAddr3(kAddress3);
  344. Buffer buffer;
  345. MakeAddrMessage(RTM_NEWADDR, 0, AF_INET6, kTestInterfaceEth, kEmpty, kAddr3,
  346. &buffer);
  347. EXPECT_TRUE(HandleAddressMessage(buffer));
  348. AddressTrackerLinux::AddressMap map = GetAddressMap();
  349. EXPECT_EQ(1u, map.size());
  350. EXPECT_EQ(1u, map.count(kAddr3));
  351. EXPECT_EQ(0, map[kAddr3].ifa_flags);
  352. // Verify 0 preferred lifetime implies deprecated.
  353. buffer.clear();
  354. MakeAddrMessageWithCacheInfo(RTM_NEWADDR, 0, AF_INET6, kTestInterfaceEth,
  355. kEmpty, kAddr3, 0, &buffer);
  356. EXPECT_TRUE(HandleAddressMessage(buffer));
  357. map = GetAddressMap();
  358. EXPECT_EQ(1u, map.size());
  359. EXPECT_EQ(IFA_F_DEPRECATED, map[kAddr3].ifa_flags);
  360. // Verify properly flagged message doesn't imply change.
  361. buffer.clear();
  362. MakeAddrMessageWithCacheInfo(RTM_NEWADDR, IFA_F_DEPRECATED, AF_INET6,
  363. kTestInterfaceEth, kEmpty, kAddr3, 0, &buffer);
  364. EXPECT_FALSE(HandleAddressMessage(buffer));
  365. map = GetAddressMap();
  366. EXPECT_EQ(1u, map.size());
  367. EXPECT_EQ(IFA_F_DEPRECATED, map[kAddr3].ifa_flags);
  368. // Verify implied deprecated doesn't imply change.
  369. buffer.clear();
  370. MakeAddrMessageWithCacheInfo(RTM_NEWADDR, 0, AF_INET6, kTestInterfaceEth,
  371. kEmpty, kAddr3, 0, &buffer);
  372. EXPECT_FALSE(HandleAddressMessage(buffer));
  373. map = GetAddressMap();
  374. EXPECT_EQ(1u, map.size());
  375. EXPECT_EQ(IFA_F_DEPRECATED, map[kAddr3].ifa_flags);
  376. }
  377. TEST_F(AddressTrackerLinuxTest, IgnoredMessage) {
  378. InitializeAddressTracker(true);
  379. const IPAddress kEmpty;
  380. const IPAddress kAddr0(kAddress0);
  381. const IPAddress kAddr3(kAddress3);
  382. Buffer buffer;
  383. // Ignored family.
  384. MakeAddrMessage(RTM_NEWADDR, 0, AF_UNSPEC, kTestInterfaceEth, kAddr3, kAddr0,
  385. &buffer);
  386. // No address.
  387. MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kTestInterfaceEth, kEmpty, kEmpty,
  388. &buffer);
  389. // Ignored type.
  390. MakeAddrMessage(RTM_DELROUTE, 0, AF_INET6, kTestInterfaceEth, kAddr3, kEmpty,
  391. &buffer);
  392. EXPECT_FALSE(HandleAddressMessage(buffer));
  393. EXPECT_TRUE(GetAddressMap().empty());
  394. // Valid message after ignored messages.
  395. NetlinkMessage nlmsg(RTM_NEWADDR);
  396. struct ifaddrmsg msg = {};
  397. msg.ifa_family = AF_INET;
  398. nlmsg.AddPayload(&msg, sizeof(msg));
  399. // Ignored attribute.
  400. struct ifa_cacheinfo cache_info = {};
  401. nlmsg.AddAttribute(IFA_CACHEINFO, &cache_info, sizeof(cache_info));
  402. nlmsg.AddAttribute(IFA_ADDRESS, kAddr0.bytes().data(), kAddr0.size());
  403. nlmsg.AppendTo(&buffer);
  404. EXPECT_TRUE(HandleAddressMessage(buffer));
  405. EXPECT_EQ(1u, GetAddressMap().size());
  406. }
  407. TEST_F(AddressTrackerLinuxTest, AddInterface) {
  408. InitializeAddressTracker(true);
  409. Buffer buffer;
  410. // Ignores loopback.
  411. MakeLinkMessage(RTM_NEWLINK,
  412. IFF_LOOPBACK | IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  413. kTestInterfaceEth, &buffer);
  414. EXPECT_FALSE(HandleLinkMessage(buffer));
  415. EXPECT_TRUE(GetOnlineLinks().empty());
  416. // Ignores not IFF_LOWER_UP.
  417. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, kTestInterfaceEth,
  418. &buffer);
  419. EXPECT_FALSE(HandleLinkMessage(buffer));
  420. EXPECT_TRUE(GetOnlineLinks().empty());
  421. // Ignores deletion.
  422. MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  423. kTestInterfaceEth, &buffer);
  424. EXPECT_FALSE(HandleLinkMessage(buffer));
  425. EXPECT_TRUE(GetOnlineLinks().empty());
  426. // Verify success.
  427. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  428. kTestInterfaceEth, &buffer);
  429. EXPECT_TRUE(HandleLinkMessage(buffer));
  430. EXPECT_EQ(1u, GetOnlineLinks().count(kTestInterfaceEth));
  431. EXPECT_EQ(1u, GetOnlineLinks().size());
  432. // Ignores redundant enables.
  433. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  434. kTestInterfaceEth, &buffer);
  435. EXPECT_FALSE(HandleLinkMessage(buffer));
  436. EXPECT_EQ(1u, GetOnlineLinks().count(kTestInterfaceEth));
  437. EXPECT_EQ(1u, GetOnlineLinks().size());
  438. // Ignores messages from wireless_send_event.
  439. MakeWirelessLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  440. kTestInterfaceWifi, &buffer);
  441. EXPECT_FALSE(HandleLinkMessage(buffer));
  442. EXPECT_EQ(0u, GetOnlineLinks().count(kTestInterfaceWifi));
  443. EXPECT_EQ(1u, GetOnlineLinks().size());
  444. // Verify adding another online device (e.g. VPN) is considered a change.
  445. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 2, &buffer);
  446. EXPECT_TRUE(HandleLinkMessage(buffer));
  447. EXPECT_EQ(1u, GetOnlineLinks().count(kTestInterfaceEth));
  448. EXPECT_EQ(1u, GetOnlineLinks().count(2));
  449. EXPECT_EQ(2u, GetOnlineLinks().size());
  450. }
  451. TEST_F(AddressTrackerLinuxTest, RemoveInterface) {
  452. InitializeAddressTracker(true);
  453. Buffer buffer;
  454. // Should disappear when not IFF_LOWER_UP.
  455. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  456. kTestInterfaceEth, &buffer);
  457. EXPECT_TRUE(HandleLinkMessage(buffer));
  458. EXPECT_FALSE(GetOnlineLinks().empty());
  459. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, kTestInterfaceEth,
  460. &buffer);
  461. EXPECT_TRUE(HandleLinkMessage(buffer));
  462. EXPECT_TRUE(GetOnlineLinks().empty());
  463. // Ignores redundant disables.
  464. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, kTestInterfaceEth,
  465. &buffer);
  466. EXPECT_FALSE(HandleLinkMessage(buffer));
  467. EXPECT_TRUE(GetOnlineLinks().empty());
  468. // Ignores deleting down interfaces.
  469. MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_RUNNING, kTestInterfaceEth,
  470. &buffer);
  471. EXPECT_FALSE(HandleLinkMessage(buffer));
  472. EXPECT_TRUE(GetOnlineLinks().empty());
  473. // Should disappear when deleted.
  474. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  475. kTestInterfaceEth, &buffer);
  476. EXPECT_TRUE(HandleLinkMessage(buffer));
  477. EXPECT_FALSE(GetOnlineLinks().empty());
  478. MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  479. kTestInterfaceEth, &buffer);
  480. EXPECT_TRUE(HandleLinkMessage(buffer));
  481. EXPECT_TRUE(GetOnlineLinks().empty());
  482. // Ignores messages from wireless_send_event.
  483. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  484. kTestInterfaceWifi, &buffer);
  485. EXPECT_TRUE(HandleLinkMessage(buffer));
  486. EXPECT_FALSE(GetOnlineLinks().empty());
  487. MakeWirelessLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP,
  488. kTestInterfaceWifi, &buffer);
  489. EXPECT_FALSE(HandleLinkMessage(buffer));
  490. EXPECT_FALSE(GetOnlineLinks().empty());
  491. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, kTestInterfaceWifi,
  492. &buffer);
  493. EXPECT_TRUE(HandleLinkMessage(buffer));
  494. EXPECT_TRUE(GetOnlineLinks().empty());
  495. }
  496. TEST_F(AddressTrackerLinuxTest, IgnoreInterface) {
  497. IgnoreInterface(kIgnoredInterfaceName);
  498. InitializeAddressTracker(true);
  499. Buffer buffer;
  500. const IPAddress kEmpty;
  501. const IPAddress kAddr0(kAddress0);
  502. // Verify online links and address map has been not been updated
  503. MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kTestInterfaceAp,
  504. kAddr0, kEmpty, &buffer);
  505. EXPECT_FALSE(HandleAddressMessage(buffer));
  506. AddressTrackerLinux::AddressMap map = GetAddressMap();
  507. EXPECT_EQ(0u, map.size());
  508. EXPECT_EQ(0u, map.count(kAddr0));
  509. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  510. kTestInterfaceAp, &buffer);
  511. EXPECT_FALSE(HandleLinkMessage(buffer));
  512. EXPECT_EQ(0u, GetOnlineLinks().count(kTestInterfaceAp));
  513. EXPECT_EQ(0u, GetOnlineLinks().size());
  514. }
  515. TEST_F(AddressTrackerLinuxTest, IgnoreInterface_NonIgnoredInterface) {
  516. IgnoreInterface(kIgnoredInterfaceName);
  517. InitializeAddressTracker(true);
  518. Buffer buffer;
  519. const IPAddress kEmpty;
  520. const IPAddress kAddr0(kAddress0);
  521. // Verify eth0 is not ignored when only uap0 is ignored
  522. MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kTestInterfaceEth,
  523. kAddr0, kEmpty, &buffer);
  524. EXPECT_TRUE(HandleAddressMessage(buffer));
  525. AddressTrackerLinux::AddressMap map = GetAddressMap();
  526. EXPECT_EQ(1u, map.size());
  527. EXPECT_EQ(1u, map.count(kAddr0));
  528. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
  529. kTestInterfaceEth, &buffer);
  530. EXPECT_TRUE(HandleLinkMessage(buffer));
  531. EXPECT_EQ(1u, GetOnlineLinks().count(kTestInterfaceEth));
  532. EXPECT_EQ(1u, GetOnlineLinks().size());
  533. }
  534. TEST_F(AddressTrackerLinuxTest, TunnelInterface) {
  535. InitializeAddressTracker(true);
  536. Buffer buffer;
  537. // Ignores without "tun" prefixed name.
  538. MakeLinkMessage(RTM_NEWLINK,
  539. IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT,
  540. kTestInterfaceEth, &buffer);
  541. EXPECT_FALSE(HandleTunnelMessage(buffer));
  542. // Verify success.
  543. MakeLinkMessage(RTM_NEWLINK,
  544. IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT,
  545. kTestInterfaceTun, &buffer);
  546. EXPECT_TRUE(HandleTunnelMessage(buffer));
  547. // Ignores redundant enables.
  548. MakeLinkMessage(RTM_NEWLINK,
  549. IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT,
  550. kTestInterfaceTun, &buffer);
  551. EXPECT_FALSE(HandleTunnelMessage(buffer));
  552. // Ignores deleting without "tun" prefixed name.
  553. MakeLinkMessage(RTM_DELLINK,
  554. IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT,
  555. 0, &buffer);
  556. EXPECT_FALSE(HandleTunnelMessage(buffer));
  557. // Verify successful deletion
  558. MakeLinkMessage(RTM_DELLINK,
  559. IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT,
  560. kTestInterfaceTun, &buffer);
  561. EXPECT_TRUE(HandleTunnelMessage(buffer));
  562. // Ignores redundant deletions.
  563. MakeLinkMessage(RTM_DELLINK,
  564. IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT,
  565. kTestInterfaceTun, &buffer);
  566. EXPECT_FALSE(HandleTunnelMessage(buffer));
  567. }
  568. // Check AddressTrackerLinux::get_interface_name_ original implementation
  569. // doesn't crash or return NULL.
  570. TEST_F(AddressTrackerLinuxTest, GetInterfaceName) {
  571. InitializeAddressTracker(true);
  572. for (int i = 0; i < 10; i++) {
  573. char buf[IFNAMSIZ] = {0};
  574. EXPECT_NE((const char*)nullptr, original_get_interface_name_(i, buf));
  575. }
  576. }
  577. TEST_F(AddressTrackerLinuxTest, NonTrackingMode) {
  578. InitializeAddressTracker(false);
  579. const IPAddress kEmpty;
  580. const IPAddress kAddr0(kAddress0);
  581. Buffer buffer;
  582. MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kTestInterfaceEth,
  583. kAddr0, kEmpty, &buffer);
  584. EXPECT_TRUE(HandleAddressMessage(buffer));
  585. AddressTrackerLinux::AddressMap map = GetAddressMap();
  586. EXPECT_EQ(1u, map.size());
  587. EXPECT_EQ(1u, map.count(kAddr0));
  588. EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
  589. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 1, &buffer);
  590. EXPECT_TRUE(HandleLinkMessage(buffer));
  591. EXPECT_EQ(1u, GetOnlineLinks().count(1));
  592. EXPECT_EQ(1u, GetOnlineLinks().size());
  593. }
  594. TEST_F(AddressTrackerLinuxTest, NonTrackingModeInit) {
  595. #if BUILDFLAG(IS_ANDROID)
  596. // Calling Init() on Android P+ isn't supported.
  597. if (base::android::BuildInfo::GetInstance()->sdk_int() >=
  598. base::android::SDK_VERSION_P)
  599. return;
  600. #endif
  601. AddressTrackerLinux tracker;
  602. tracker.Init();
  603. }
  604. class GetCurrentConnectionTypeRunner
  605. : public base::DelegateSimpleThread::Delegate {
  606. public:
  607. explicit GetCurrentConnectionTypeRunner(AddressTrackerLinux* tracker,
  608. const std::string& thread_name)
  609. : tracker_(tracker),
  610. done_(base::WaitableEvent::ResetPolicy::MANUAL,
  611. base::WaitableEvent::InitialState::NOT_SIGNALED),
  612. thread_(this, thread_name) {}
  613. ~GetCurrentConnectionTypeRunner() override = default;
  614. void Run() override {
  615. tracker_->GetCurrentConnectionType();
  616. done_.Signal();
  617. }
  618. void Start() {
  619. thread_.Start();
  620. }
  621. void VerifyCompletes() {
  622. EXPECT_TRUE(done_.TimedWait(base::Seconds(5)));
  623. thread_.Join();
  624. }
  625. private:
  626. const raw_ptr<AddressTrackerLinux> tracker_;
  627. base::WaitableEvent done_;
  628. base::DelegateSimpleThread thread_;
  629. };
  630. TEST_F(AddressTrackerLinuxTest, BroadcastInit) {
  631. #if BUILDFLAG(IS_ANDROID)
  632. // Calling Init() on Android P+ isn't supported.
  633. if (base::android::BuildInfo::GetInstance()->sdk_int() >=
  634. base::android::SDK_VERSION_P)
  635. return;
  636. #endif
  637. base::test::TaskEnvironment task_environment(
  638. base::test::TaskEnvironment::MainThreadType::IO);
  639. InitializeAddressTracker(true);
  640. GetCurrentConnectionTypeRunner runner1(tracker_.get(), "waiter_thread_1");
  641. GetCurrentConnectionTypeRunner runner2(tracker_.get(), "waiter_thread_2");
  642. runner1.Start();
  643. runner2.Start();
  644. SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(
  645. GetThreadsWaitingForConnectionTypeInit() == 2);
  646. tracker_->Init();
  647. runner1.VerifyCompletes();
  648. runner2.VerifyCompletes();
  649. }
  650. TEST_F(AddressTrackerLinuxTest, TunnelInterfaceName) {
  651. EXPECT_TRUE(AddressTrackerLinux::IsTunnelInterfaceName("tun0"));
  652. EXPECT_FALSE(AddressTrackerLinux::IsTunnelInterfaceName("wlan0"));
  653. }
  654. } // namespace
  655. // This is a regression test for https://crbug.com/1224428.
  656. //
  657. // This test initializes two instances of `AddressTrackerLinux` in the same
  658. // process. The test will fail if the implementation reuses the value of
  659. // `sockaddr_nl::nl_pid`.
  660. //
  661. // Note: consumers generally should not need to create two tracking instances of
  662. // `AddressTrackerLinux` in the same process.
  663. TEST(AddressTrackerLinuxNetlinkTest, TestInitializeTwoTrackers) {
  664. #if BUILDFLAG(IS_ANDROID)
  665. // Calling Init() on Android P+ isn't supported.
  666. if (base::android::BuildInfo::GetInstance()->sdk_int() >=
  667. base::android::SDK_VERSION_P)
  668. return;
  669. #endif
  670. base::test::TaskEnvironment task_env(
  671. base::test::TaskEnvironment::MainThreadType::IO);
  672. AddressTrackerLinux tracker1(base::DoNothing(), base::DoNothing(),
  673. base::DoNothing(), {});
  674. AddressTrackerLinux tracker2(base::DoNothing(), base::DoNothing(),
  675. base::DoNothing(), {});
  676. tracker1.Init();
  677. tracker2.Init();
  678. EXPECT_TRUE(tracker1.DidTrackingInitSucceedForTesting());
  679. EXPECT_TRUE(tracker2.DidTrackingInitSucceedForTesting());
  680. }
  681. // These tests use `base::LaunchOptions::clone_flags` for fine-grained control
  682. // over the clone syscall, but the field is only defined on Linux and ChromeOS.
  683. // Unfortunately, this means these tests do not have coverage on Android.
  684. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  685. // These tests require specific flag values defined in <sched.h>.
  686. #if defined(CLONE_NEWUSER) && defined(CLONE_NEWPID)
  687. namespace {
  688. const char* const kSwitchParentWriteFd = "addresstrackerlinux_parent_write_fd";
  689. const char* const kSwitchReadFd = "addresstrackerlinux_read_fd";
  690. enum IPCMessage {
  691. // Sent from child to parent once the child has initialized its tracker.
  692. kChildInitializedAndWaiting,
  693. // Sent from child to parent when it was unable to initialize its tracker.
  694. kChildFailed,
  695. // Sent from parent to child when all children are permitted to exit.
  696. kChildMayExit,
  697. };
  698. base::File GetSwitchValueFile(const base::CommandLine* command_line,
  699. base::StringPiece name) {
  700. std::string value = command_line->GetSwitchValueASCII(name);
  701. int fd;
  702. CHECK(base::StringToInt(value, &fd));
  703. return base::File(fd);
  704. }
  705. } // namespace
  706. // This is a regression test for https://crbug.com/1224428.
  707. //
  708. // This test creates multiple concurrent `AddressTrackerLinux` instances in
  709. // separate processes, each in their own PID namespaces.
  710. TEST(AddressTrackerLinuxNetlinkTest, TestInitializeTwoTrackersInPidNamespaces) {
  711. // This test initializes `kNumChildren` instances of `AddressTrackerLinux` in
  712. // tracking mode, each in their own child process running in a PID namespace.
  713. // The test will fail if the implementation reuses the value of
  714. // `sockaddr_nl::nl_pid`.
  715. //
  716. // The child processes use pipes to synchronize. Each child initializes a
  717. // tracker, sends a message to the parent, and waits for the parent to
  718. // respond, indicating that all children are done setting up. This ensures
  719. // that the tracker objects have overlapping lifetimes, and thus that the
  720. // underlying netlink sockets have overlapping lifetimes. This coexistence is
  721. // necessary, but not sufficient, for a `sockaddr_nl::nl_pid` value collision.
  722. constexpr size_t kNumChildren = 2;
  723. base::ScopedFD parent_read_fd, parent_write_fd;
  724. ASSERT_TRUE(base::CreatePipe(&parent_read_fd, &parent_write_fd));
  725. struct Child {
  726. base::ScopedFD read_fd;
  727. base::ScopedFD write_fd;
  728. base::Process process;
  729. } children[kNumChildren];
  730. for (Child& child : children) {
  731. ASSERT_TRUE(base::CreatePipe(&child.read_fd, &child.write_fd));
  732. // Since the child process will wipe its address space by calling execvp, we
  733. // must share the file descriptors via its command line.
  734. base::CommandLine command_line(
  735. base::GetMultiProcessTestChildBaseCommandLine());
  736. command_line.AppendSwitchASCII(kSwitchParentWriteFd,
  737. base::NumberToString(parent_write_fd.get()));
  738. command_line.AppendSwitchASCII(kSwitchReadFd,
  739. base::NumberToString(child.read_fd.get()));
  740. base::LaunchOptions options;
  741. // Indicate that the child process requires these file descriptors.
  742. // Otherwise, they will be closed. See `base::CloseSuperfluousFds`.
  743. options.fds_to_remap = {{child.read_fd.get(), child.read_fd.get()},
  744. {parent_write_fd.get(), parent_write_fd.get()}};
  745. // Clone into a new PID namespace. Making it a new user namespace as well to
  746. // skirt the CAP_SYS_ADMIN requirement.
  747. options.clone_flags = CLONE_NEWPID | CLONE_NEWUSER;
  748. child.process = base::SpawnMultiProcessTestChild(
  749. "ChildProcessInitializeTrackerForTesting", command_line, options);
  750. }
  751. // Wait for all children to finish initializing their tracking
  752. // AddressTrackerLinuxes.
  753. base::File parent_reader(std::move(parent_read_fd));
  754. for (const Child& child : children) {
  755. ASSERT_TRUE(child.process.IsValid());
  756. uint8_t message[] = {0};
  757. ASSERT_TRUE(parent_reader.ReadAtCurrentPosAndCheck(message));
  758. ASSERT_EQ(message[0], kChildInitializedAndWaiting);
  759. }
  760. // Tell children to exit and wait for them to exit.
  761. for (Child& child : children) {
  762. base::File child_writer(std::move(child.write_fd));
  763. const uint8_t kMessage[] = {kChildMayExit};
  764. ASSERT_TRUE(child_writer.WriteAtCurrentPosAndCheck(kMessage));
  765. int exit_code = 0;
  766. ASSERT_TRUE(child.process.WaitForExit(&exit_code));
  767. ASSERT_EQ(exit_code, 0);
  768. }
  769. }
  770. MULTIPROCESS_TEST_MAIN(ChildProcessInitializeTrackerForTesting) {
  771. base::test::TaskEnvironment task_env(
  772. base::test::TaskEnvironment::MainThreadType::IO);
  773. const base::CommandLine* command_line =
  774. base::CommandLine::ForCurrentProcess();
  775. base::File reader = GetSwitchValueFile(command_line, kSwitchReadFd);
  776. base::File parent_writer =
  777. GetSwitchValueFile(command_line, kSwitchParentWriteFd);
  778. // Initialize an `AddressTrackerLinux` in tracking mode and ensure that it
  779. // created a netlink socket.
  780. AddressTrackerLinux tracker(base::DoNothing(), base::DoNothing(),
  781. base::DoNothing(), {});
  782. tracker.Init();
  783. if (!tracker.DidTrackingInitSucceedForTesting()) {
  784. const uint8_t kMessage[] = {kChildFailed};
  785. parent_writer.WriteAtCurrentPosAndCheck(kMessage);
  786. return 1;
  787. }
  788. // Signal to the parent that we have initialized the tracker.
  789. const uint8_t kMessage[] = {kChildInitializedAndWaiting};
  790. if (!parent_writer.WriteAtCurrentPosAndCheck(kMessage))
  791. return 1;
  792. // Block until the parent says all children have initialized their trackers.
  793. uint8_t message[] = {0};
  794. if (!reader.ReadAtCurrentPosAndCheck(message) || message[0] != kChildMayExit)
  795. return 1;
  796. return 0;
  797. }
  798. #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  799. #endif // defined(CLONE_NEWUSER) && defined(CLONE_NEWPID)
  800. } // namespace net::internal