| OLD | NEW |
| (Empty) |
| 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 | |
| 5 #include "base/memory/scoped_ptr.h" | |
| 6 #include "net/base/address_tracker_linux.h" | |
| 7 | |
| 8 #include <linux/if.h> | |
| 9 | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/bind.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 #ifndef IFA_F_HOMEADDRESS | |
| 16 #define IFA_F_HOMEADDRESS 0x10 | |
| 17 #endif | |
| 18 | |
| 19 namespace net { | |
| 20 namespace internal { | |
| 21 namespace { | |
| 22 | |
| 23 const int kTestInterfaceTun = 123; | |
| 24 | |
| 25 char* TestGetInterfaceName(int interface_index, char* buf) { | |
| 26 if (interface_index == kTestInterfaceTun) | |
| 27 return strncpy(buf, "tun0", IFNAMSIZ); | |
| 28 return strncpy(buf, "eth0", IFNAMSIZ); | |
| 29 } | |
| 30 | |
| 31 } // namespace | |
| 32 | |
| 33 typedef std::vector<char> Buffer; | |
| 34 | |
| 35 class AddressTrackerLinuxTest : public testing::Test { | |
| 36 protected: | |
| 37 AddressTrackerLinuxTest() {} | |
| 38 | |
| 39 void InitializeAddressTracker(bool tracking) { | |
| 40 if (tracking) { | |
| 41 tracker_.reset(new AddressTrackerLinux(base::Bind(&base::DoNothing), | |
| 42 base::Bind(&base::DoNothing), | |
| 43 base::Bind(&base::DoNothing))); | |
| 44 } else { | |
| 45 tracker_.reset(new AddressTrackerLinux()); | |
| 46 } | |
| 47 original_get_interface_name_ = tracker_->get_interface_name_; | |
| 48 tracker_->get_interface_name_ = TestGetInterfaceName; | |
| 49 } | |
| 50 | |
| 51 bool HandleAddressMessage(const Buffer& buf) { | |
| 52 Buffer writable_buf = buf; | |
| 53 bool address_changed = false; | |
| 54 bool link_changed = false; | |
| 55 bool tunnel_changed = false; | |
| 56 tracker_->HandleMessage(&writable_buf[0], buf.size(), | |
| 57 &address_changed, &link_changed, &tunnel_changed); | |
| 58 EXPECT_FALSE(link_changed); | |
| 59 return address_changed; | |
| 60 } | |
| 61 | |
| 62 bool HandleLinkMessage(const Buffer& buf) { | |
| 63 Buffer writable_buf = buf; | |
| 64 bool address_changed = false; | |
| 65 bool link_changed = false; | |
| 66 bool tunnel_changed = false; | |
| 67 tracker_->HandleMessage(&writable_buf[0], buf.size(), | |
| 68 &address_changed, &link_changed, &tunnel_changed); | |
| 69 EXPECT_FALSE(address_changed); | |
| 70 return link_changed; | |
| 71 } | |
| 72 | |
| 73 bool HandleTunnelMessage(const Buffer& buf) { | |
| 74 Buffer writable_buf = buf; | |
| 75 bool address_changed = false; | |
| 76 bool link_changed = false; | |
| 77 bool tunnel_changed = false; | |
| 78 tracker_->HandleMessage(&writable_buf[0], buf.size(), | |
| 79 &address_changed, &link_changed, &tunnel_changed); | |
| 80 EXPECT_FALSE(address_changed); | |
| 81 return tunnel_changed; | |
| 82 } | |
| 83 | |
| 84 AddressTrackerLinux::AddressMap GetAddressMap() { | |
| 85 return tracker_->GetAddressMap(); | |
| 86 } | |
| 87 | |
| 88 const base::hash_set<int> GetOnlineLinks() const { | |
| 89 return tracker_->GetOnlineLinks(); | |
| 90 } | |
| 91 | |
| 92 scoped_ptr<AddressTrackerLinux> tracker_; | |
| 93 AddressTrackerLinux::GetInterfaceNameFunction original_get_interface_name_; | |
| 94 }; | |
| 95 | |
| 96 namespace { | |
| 97 | |
| 98 class NetlinkMessage { | |
| 99 public: | |
| 100 explicit NetlinkMessage(uint16 type) : buffer_(NLMSG_HDRLEN) { | |
| 101 header()->nlmsg_type = type; | |
| 102 Align(); | |
| 103 } | |
| 104 | |
| 105 void AddPayload(const void* data, size_t length) { | |
| 106 CHECK_EQ(static_cast<size_t>(NLMSG_HDRLEN), | |
| 107 buffer_.size()) << "Payload must be added first"; | |
| 108 Append(data, length); | |
| 109 Align(); | |
| 110 } | |
| 111 | |
| 112 void AddAttribute(uint16 type, const void* data, size_t length) { | |
| 113 struct nlattr attr; | |
| 114 attr.nla_len = NLA_HDRLEN + length; | |
| 115 attr.nla_type = type; | |
| 116 Append(&attr, sizeof(attr)); | |
| 117 Align(); | |
| 118 Append(data, length); | |
| 119 Align(); | |
| 120 } | |
| 121 | |
| 122 void AppendTo(Buffer* output) const { | |
| 123 CHECK_EQ(NLMSG_ALIGN(output->size()), output->size()); | |
| 124 output->reserve(output->size() + NLMSG_LENGTH(buffer_.size())); | |
| 125 output->insert(output->end(), buffer_.begin(), buffer_.end()); | |
| 126 } | |
| 127 | |
| 128 private: | |
| 129 void Append(const void* data, size_t length) { | |
| 130 const char* chardata = reinterpret_cast<const char*>(data); | |
| 131 buffer_.insert(buffer_.end(), chardata, chardata + length); | |
| 132 } | |
| 133 | |
| 134 void Align() { | |
| 135 header()->nlmsg_len = buffer_.size(); | |
| 136 buffer_.insert(buffer_.end(), NLMSG_ALIGN(buffer_.size()) - buffer_.size(), | |
| 137 0); | |
| 138 CHECK(NLMSG_OK(header(), buffer_.size())); | |
| 139 } | |
| 140 | |
| 141 struct nlmsghdr* header() { | |
| 142 return reinterpret_cast<struct nlmsghdr*>(&buffer_[0]); | |
| 143 } | |
| 144 | |
| 145 Buffer buffer_; | |
| 146 }; | |
| 147 | |
| 148 #define INFINITY_LIFE_TIME 0xFFFFFFFF | |
| 149 | |
| 150 void MakeAddrMessageWithCacheInfo(uint16 type, | |
| 151 uint8 flags, | |
| 152 uint8 family, | |
| 153 const IPAddressNumber& address, | |
| 154 const IPAddressNumber& local, | |
| 155 uint32 preferred_lifetime, | |
| 156 Buffer* output) { | |
| 157 NetlinkMessage nlmsg(type); | |
| 158 struct ifaddrmsg msg = {}; | |
| 159 msg.ifa_family = family; | |
| 160 msg.ifa_flags = flags; | |
| 161 nlmsg.AddPayload(&msg, sizeof(msg)); | |
| 162 if (address.size()) | |
| 163 nlmsg.AddAttribute(IFA_ADDRESS, &address[0], address.size()); | |
| 164 if (local.size()) | |
| 165 nlmsg.AddAttribute(IFA_LOCAL, &local[0], local.size()); | |
| 166 struct ifa_cacheinfo cache_info = {}; | |
| 167 cache_info.ifa_prefered = preferred_lifetime; | |
| 168 cache_info.ifa_valid = INFINITY_LIFE_TIME; | |
| 169 nlmsg.AddAttribute(IFA_CACHEINFO, &cache_info, sizeof(cache_info)); | |
| 170 nlmsg.AppendTo(output); | |
| 171 } | |
| 172 | |
| 173 void MakeAddrMessage(uint16 type, | |
| 174 uint8 flags, | |
| 175 uint8 family, | |
| 176 const IPAddressNumber& address, | |
| 177 const IPAddressNumber& local, | |
| 178 Buffer* output) { | |
| 179 MakeAddrMessageWithCacheInfo(type, flags, family, address, local, | |
| 180 INFINITY_LIFE_TIME, output); | |
| 181 } | |
| 182 | |
| 183 void MakeLinkMessage(uint16 type, uint32 flags, uint32 index, Buffer* output) { | |
| 184 NetlinkMessage nlmsg(type); | |
| 185 struct ifinfomsg msg = {}; | |
| 186 msg.ifi_index = index; | |
| 187 msg.ifi_flags = flags; | |
| 188 nlmsg.AddPayload(&msg, sizeof(msg)); | |
| 189 output->clear(); | |
| 190 nlmsg.AppendTo(output); | |
| 191 } | |
| 192 | |
| 193 const unsigned char kAddress0[] = { 127, 0, 0, 1 }; | |
| 194 const unsigned char kAddress1[] = { 10, 0, 0, 1 }; | |
| 195 const unsigned char kAddress2[] = { 192, 168, 0, 1 }; | |
| 196 const unsigned char kAddress3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 197 0, 0, 0, 1 }; | |
| 198 | |
| 199 TEST_F(AddressTrackerLinuxTest, NewAddress) { | |
| 200 InitializeAddressTracker(true); | |
| 201 | |
| 202 const IPAddressNumber kEmpty; | |
| 203 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0)); | |
| 204 const IPAddressNumber kAddr1(kAddress1, kAddress1 + arraysize(kAddress1)); | |
| 205 const IPAddressNumber kAddr2(kAddress2, kAddress2 + arraysize(kAddress2)); | |
| 206 const IPAddressNumber kAddr3(kAddress3, kAddress3 + arraysize(kAddress3)); | |
| 207 | |
| 208 Buffer buffer; | |
| 209 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty, | |
| 210 &buffer); | |
| 211 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 212 AddressTrackerLinux::AddressMap map = GetAddressMap(); | |
| 213 EXPECT_EQ(1u, map.size()); | |
| 214 EXPECT_EQ(1u, map.count(kAddr0)); | |
| 215 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags); | |
| 216 | |
| 217 buffer.clear(); | |
| 218 MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kAddr1, kAddr2, | |
| 219 &buffer); | |
| 220 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 221 map = GetAddressMap(); | |
| 222 EXPECT_EQ(2u, map.size()); | |
| 223 EXPECT_EQ(1u, map.count(kAddr0)); | |
| 224 EXPECT_EQ(1u, map.count(kAddr2)); | |
| 225 EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr2].ifa_flags); | |
| 226 | |
| 227 buffer.clear(); | |
| 228 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET6, kEmpty, kAddr3, &buffer); | |
| 229 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 230 map = GetAddressMap(); | |
| 231 EXPECT_EQ(3u, map.size()); | |
| 232 EXPECT_EQ(1u, map.count(kAddr3)); | |
| 233 } | |
| 234 | |
| 235 TEST_F(AddressTrackerLinuxTest, NewAddressChange) { | |
| 236 InitializeAddressTracker(true); | |
| 237 | |
| 238 const IPAddressNumber kEmpty; | |
| 239 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0)); | |
| 240 | |
| 241 Buffer buffer; | |
| 242 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty, | |
| 243 &buffer); | |
| 244 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 245 AddressTrackerLinux::AddressMap map = GetAddressMap(); | |
| 246 EXPECT_EQ(1u, map.size()); | |
| 247 EXPECT_EQ(1u, map.count(kAddr0)); | |
| 248 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags); | |
| 249 | |
| 250 buffer.clear(); | |
| 251 MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kAddr0, kEmpty, | |
| 252 &buffer); | |
| 253 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 254 map = GetAddressMap(); | |
| 255 EXPECT_EQ(1u, map.size()); | |
| 256 EXPECT_EQ(1u, map.count(kAddr0)); | |
| 257 EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr0].ifa_flags); | |
| 258 | |
| 259 // Both messages in one buffer. | |
| 260 buffer.clear(); | |
| 261 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty, | |
| 262 &buffer); | |
| 263 MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kAddr0, kEmpty, | |
| 264 &buffer); | |
| 265 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 266 map = GetAddressMap(); | |
| 267 EXPECT_EQ(1u, map.size()); | |
| 268 EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr0].ifa_flags); | |
| 269 } | |
| 270 | |
| 271 TEST_F(AddressTrackerLinuxTest, NewAddressDuplicate) { | |
| 272 InitializeAddressTracker(true); | |
| 273 | |
| 274 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0)); | |
| 275 | |
| 276 Buffer buffer; | |
| 277 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kAddr0, | |
| 278 &buffer); | |
| 279 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 280 AddressTrackerLinux::AddressMap map = GetAddressMap(); | |
| 281 EXPECT_EQ(1u, map.size()); | |
| 282 EXPECT_EQ(1u, map.count(kAddr0)); | |
| 283 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags); | |
| 284 | |
| 285 EXPECT_FALSE(HandleAddressMessage(buffer)); | |
| 286 map = GetAddressMap(); | |
| 287 EXPECT_EQ(1u, map.size()); | |
| 288 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags); | |
| 289 } | |
| 290 | |
| 291 TEST_F(AddressTrackerLinuxTest, DeleteAddress) { | |
| 292 InitializeAddressTracker(true); | |
| 293 | |
| 294 const IPAddressNumber kEmpty; | |
| 295 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0)); | |
| 296 const IPAddressNumber kAddr1(kAddress1, kAddress1 + arraysize(kAddress1)); | |
| 297 const IPAddressNumber kAddr2(kAddress2, kAddress2 + arraysize(kAddress2)); | |
| 298 | |
| 299 Buffer buffer; | |
| 300 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kAddr0, kEmpty, &buffer); | |
| 301 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kAddr1, kAddr2, &buffer); | |
| 302 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 303 AddressTrackerLinux::AddressMap map = GetAddressMap(); | |
| 304 EXPECT_EQ(2u, map.size()); | |
| 305 | |
| 306 buffer.clear(); | |
| 307 MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kEmpty, kAddr0, &buffer); | |
| 308 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 309 map = GetAddressMap(); | |
| 310 EXPECT_EQ(1u, map.size()); | |
| 311 EXPECT_EQ(0u, map.count(kAddr0)); | |
| 312 EXPECT_EQ(1u, map.count(kAddr2)); | |
| 313 | |
| 314 buffer.clear(); | |
| 315 MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kAddr2, kAddr1, &buffer); | |
| 316 // kAddr1 does not exist in the map. | |
| 317 EXPECT_FALSE(HandleAddressMessage(buffer)); | |
| 318 map = GetAddressMap(); | |
| 319 EXPECT_EQ(1u, map.size()); | |
| 320 | |
| 321 buffer.clear(); | |
| 322 MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kAddr2, kEmpty, &buffer); | |
| 323 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 324 map = GetAddressMap(); | |
| 325 EXPECT_EQ(0u, map.size()); | |
| 326 } | |
| 327 | |
| 328 TEST_F(AddressTrackerLinuxTest, DeprecatedLifetime) { | |
| 329 InitializeAddressTracker(true); | |
| 330 | |
| 331 const IPAddressNumber kEmpty; | |
| 332 const IPAddressNumber kAddr3(kAddress3, kAddress3 + arraysize(kAddress3)); | |
| 333 | |
| 334 Buffer buffer; | |
| 335 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET6, kEmpty, kAddr3, &buffer); | |
| 336 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 337 AddressTrackerLinux::AddressMap map = GetAddressMap(); | |
| 338 EXPECT_EQ(1u, map.size()); | |
| 339 EXPECT_EQ(1u, map.count(kAddr3)); | |
| 340 EXPECT_EQ(0, map[kAddr3].ifa_flags); | |
| 341 | |
| 342 // Verify 0 preferred lifetime implies deprecated. | |
| 343 buffer.clear(); | |
| 344 MakeAddrMessageWithCacheInfo(RTM_NEWADDR, 0, AF_INET6, kEmpty, kAddr3, 0, | |
| 345 &buffer); | |
| 346 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 347 map = GetAddressMap(); | |
| 348 EXPECT_EQ(1u, map.size()); | |
| 349 EXPECT_EQ(IFA_F_DEPRECATED, map[kAddr3].ifa_flags); | |
| 350 | |
| 351 // Verify properly flagged message doesn't imply change. | |
| 352 buffer.clear(); | |
| 353 MakeAddrMessageWithCacheInfo(RTM_NEWADDR, IFA_F_DEPRECATED, AF_INET6, kEmpty, | |
| 354 kAddr3, 0, &buffer); | |
| 355 EXPECT_FALSE(HandleAddressMessage(buffer)); | |
| 356 map = GetAddressMap(); | |
| 357 EXPECT_EQ(1u, map.size()); | |
| 358 EXPECT_EQ(IFA_F_DEPRECATED, map[kAddr3].ifa_flags); | |
| 359 | |
| 360 // Verify implied deprecated doesn't imply change. | |
| 361 buffer.clear(); | |
| 362 MakeAddrMessageWithCacheInfo(RTM_NEWADDR, 0, AF_INET6, kEmpty, kAddr3, 0, | |
| 363 &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 } | |
| 369 | |
| 370 TEST_F(AddressTrackerLinuxTest, IgnoredMessage) { | |
| 371 InitializeAddressTracker(true); | |
| 372 | |
| 373 const IPAddressNumber kEmpty; | |
| 374 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0)); | |
| 375 const IPAddressNumber kAddr3(kAddress3, kAddress3 + arraysize(kAddress3)); | |
| 376 | |
| 377 Buffer buffer; | |
| 378 // Ignored family. | |
| 379 MakeAddrMessage(RTM_NEWADDR, 0, AF_UNSPEC, kAddr3, kAddr0, &buffer); | |
| 380 // No address. | |
| 381 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kEmpty, kEmpty, &buffer); | |
| 382 // Ignored type. | |
| 383 MakeAddrMessage(RTM_DELROUTE, 0, AF_INET6, kAddr3, kEmpty, &buffer); | |
| 384 EXPECT_FALSE(HandleAddressMessage(buffer)); | |
| 385 EXPECT_TRUE(GetAddressMap().empty()); | |
| 386 | |
| 387 // Valid message after ignored messages. | |
| 388 NetlinkMessage nlmsg(RTM_NEWADDR); | |
| 389 struct ifaddrmsg msg = {}; | |
| 390 msg.ifa_family = AF_INET; | |
| 391 nlmsg.AddPayload(&msg, sizeof(msg)); | |
| 392 // Ignored attribute. | |
| 393 struct ifa_cacheinfo cache_info = {}; | |
| 394 nlmsg.AddAttribute(IFA_CACHEINFO, &cache_info, sizeof(cache_info)); | |
| 395 nlmsg.AddAttribute(IFA_ADDRESS, &kAddr0[0], kAddr0.size()); | |
| 396 nlmsg.AppendTo(&buffer); | |
| 397 | |
| 398 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 399 EXPECT_EQ(1u, GetAddressMap().size()); | |
| 400 } | |
| 401 | |
| 402 TEST_F(AddressTrackerLinuxTest, AddInterface) { | |
| 403 InitializeAddressTracker(true); | |
| 404 | |
| 405 Buffer buffer; | |
| 406 | |
| 407 // Ignores loopback. | |
| 408 MakeLinkMessage(RTM_NEWLINK, | |
| 409 IFF_LOOPBACK | IFF_UP | IFF_LOWER_UP | IFF_RUNNING, | |
| 410 0, &buffer); | |
| 411 EXPECT_FALSE(HandleLinkMessage(buffer)); | |
| 412 EXPECT_TRUE(GetOnlineLinks().empty()); | |
| 413 | |
| 414 // Ignores not IFF_LOWER_UP. | |
| 415 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer); | |
| 416 EXPECT_FALSE(HandleLinkMessage(buffer)); | |
| 417 EXPECT_TRUE(GetOnlineLinks().empty()); | |
| 418 | |
| 419 // Ignores deletion. | |
| 420 MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer); | |
| 421 EXPECT_FALSE(HandleLinkMessage(buffer)); | |
| 422 EXPECT_TRUE(GetOnlineLinks().empty()); | |
| 423 | |
| 424 // Verify success. | |
| 425 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer); | |
| 426 EXPECT_TRUE(HandleLinkMessage(buffer)); | |
| 427 EXPECT_EQ(1u, GetOnlineLinks().count(0)); | |
| 428 EXPECT_EQ(1u, GetOnlineLinks().size()); | |
| 429 | |
| 430 // Ignores redundant enables. | |
| 431 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer); | |
| 432 EXPECT_FALSE(HandleLinkMessage(buffer)); | |
| 433 EXPECT_EQ(1u, GetOnlineLinks().count(0)); | |
| 434 EXPECT_EQ(1u, GetOnlineLinks().size()); | |
| 435 | |
| 436 // Verify adding another online device (e.g. VPN) is considered a change. | |
| 437 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 1, &buffer); | |
| 438 EXPECT_TRUE(HandleLinkMessage(buffer)); | |
| 439 EXPECT_EQ(1u, GetOnlineLinks().count(0)); | |
| 440 EXPECT_EQ(1u, GetOnlineLinks().count(1)); | |
| 441 EXPECT_EQ(2u, GetOnlineLinks().size()); | |
| 442 } | |
| 443 | |
| 444 TEST_F(AddressTrackerLinuxTest, RemoveInterface) { | |
| 445 InitializeAddressTracker(true); | |
| 446 | |
| 447 Buffer buffer; | |
| 448 | |
| 449 // Should disappear when not IFF_LOWER_UP. | |
| 450 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer); | |
| 451 EXPECT_TRUE(HandleLinkMessage(buffer)); | |
| 452 EXPECT_FALSE(GetOnlineLinks().empty()); | |
| 453 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer); | |
| 454 EXPECT_TRUE(HandleLinkMessage(buffer)); | |
| 455 EXPECT_TRUE(GetOnlineLinks().empty()); | |
| 456 | |
| 457 // Ignores redundant disables. | |
| 458 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer); | |
| 459 EXPECT_FALSE(HandleLinkMessage(buffer)); | |
| 460 EXPECT_TRUE(GetOnlineLinks().empty()); | |
| 461 | |
| 462 // Ignores deleting down interfaces. | |
| 463 MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_RUNNING, 0, &buffer); | |
| 464 EXPECT_FALSE(HandleLinkMessage(buffer)); | |
| 465 EXPECT_TRUE(GetOnlineLinks().empty()); | |
| 466 | |
| 467 // Should disappear when deleted. | |
| 468 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer); | |
| 469 EXPECT_TRUE(HandleLinkMessage(buffer)); | |
| 470 EXPECT_FALSE(GetOnlineLinks().empty()); | |
| 471 MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer); | |
| 472 EXPECT_TRUE(HandleLinkMessage(buffer)); | |
| 473 EXPECT_TRUE(GetOnlineLinks().empty()); | |
| 474 } | |
| 475 | |
| 476 TEST_F(AddressTrackerLinuxTest, TunnelInterface) { | |
| 477 InitializeAddressTracker(true); | |
| 478 | |
| 479 Buffer buffer; | |
| 480 | |
| 481 // Ignores without "tun" prefixed name. | |
| 482 MakeLinkMessage(RTM_NEWLINK, | |
| 483 IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT, | |
| 484 0, &buffer); | |
| 485 EXPECT_FALSE(HandleTunnelMessage(buffer)); | |
| 486 | |
| 487 // Verify success. | |
| 488 MakeLinkMessage(RTM_NEWLINK, | |
| 489 IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT, | |
| 490 kTestInterfaceTun, &buffer); | |
| 491 EXPECT_TRUE(HandleTunnelMessage(buffer)); | |
| 492 | |
| 493 // Ignores redundant enables. | |
| 494 MakeLinkMessage(RTM_NEWLINK, | |
| 495 IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT, | |
| 496 kTestInterfaceTun, &buffer); | |
| 497 EXPECT_FALSE(HandleTunnelMessage(buffer)); | |
| 498 | |
| 499 // Ignores deleting without "tun" prefixed name. | |
| 500 MakeLinkMessage(RTM_DELLINK, | |
| 501 IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT, | |
| 502 0, &buffer); | |
| 503 EXPECT_FALSE(HandleTunnelMessage(buffer)); | |
| 504 | |
| 505 // Verify successful deletion | |
| 506 MakeLinkMessage(RTM_DELLINK, | |
| 507 IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT, | |
| 508 kTestInterfaceTun, &buffer); | |
| 509 EXPECT_TRUE(HandleTunnelMessage(buffer)); | |
| 510 | |
| 511 // Ignores redundant deletions. | |
| 512 MakeLinkMessage(RTM_DELLINK, | |
| 513 IFF_UP | IFF_LOWER_UP | IFF_RUNNING | IFF_POINTOPOINT, | |
| 514 kTestInterfaceTun, &buffer); | |
| 515 EXPECT_FALSE(HandleTunnelMessage(buffer)); | |
| 516 } | |
| 517 | |
| 518 // Check AddressTrackerLinux::get_interface_name_ original implementation | |
| 519 // doesn't crash or return NULL. | |
| 520 TEST_F(AddressTrackerLinuxTest, GetInterfaceName) { | |
| 521 InitializeAddressTracker(true); | |
| 522 | |
| 523 for (int i = 0; i < 10; i++) { | |
| 524 char buf[IFNAMSIZ] = {0}; | |
| 525 EXPECT_NE((const char*)NULL, original_get_interface_name_(i, buf)); | |
| 526 } | |
| 527 } | |
| 528 | |
| 529 TEST_F(AddressTrackerLinuxTest, NonTrackingMode) { | |
| 530 InitializeAddressTracker(false); | |
| 531 | |
| 532 const IPAddressNumber kEmpty; | |
| 533 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0)); | |
| 534 | |
| 535 Buffer buffer; | |
| 536 MakeAddrMessage( | |
| 537 RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty, &buffer); | |
| 538 EXPECT_TRUE(HandleAddressMessage(buffer)); | |
| 539 AddressTrackerLinux::AddressMap map = GetAddressMap(); | |
| 540 EXPECT_EQ(1u, map.size()); | |
| 541 EXPECT_EQ(1u, map.count(kAddr0)); | |
| 542 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags); | |
| 543 | |
| 544 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer); | |
| 545 EXPECT_TRUE(HandleLinkMessage(buffer)); | |
| 546 EXPECT_EQ(1u, GetOnlineLinks().count(0)); | |
| 547 EXPECT_EQ(1u, GetOnlineLinks().size()); | |
| 548 } | |
| 549 | |
| 550 TEST_F(AddressTrackerLinuxTest, NonTrackingModeInit) { | |
| 551 AddressTrackerLinux tracker; | |
| 552 tracker.Init(); | |
| 553 } | |
| 554 | |
| 555 } // namespace | |
| 556 | |
| 557 } // namespace internal | |
| 558 } // namespace net | |
| OLD | NEW |