From ccb380a5e43ecae201b71aca32e7c3de0d0b8fd6 Mon Sep 17 00:00:00 2001 From: Sho Amano Date: Fri, 5 Jun 2020 05:17:45 +0900 Subject: Fix: handle network interface removal (#2759) * fix: IP address isn't notified when network interface is removed When RTM_DELLINK is notified, corresponding network interface has been already destroyed so if_indextoname() won't return a valid name. To handle such case, status_table_ is updated to use network interface index as key. * fix: generate DeviceDisconnected event when network interface is removed * fix a few comments * Reflect review comments - Add const where applicable - Add more descriptions * Reflect code review Replace FindInterfaceStatus() with std::find_if() call. * Reflect code review Remove unnecessary include. * fix style issue --- ...form_specific_network_interface_listener_impl.h | 42 +++++- .../transport_manager/tcp/tcp_client_listener.h | 1 + ...platform_specific_network_interface_listener.cc | 96 ++++++++------ .../src/tcp/tcp_client_listener.cc | 20 ++- .../linux/linux_network_interface_listener_test.cc | 142 +++++++++++++-------- 5 files changed, 200 insertions(+), 101 deletions(-) diff --git a/src/components/transport_manager/include/transport_manager/tcp/platform_specific/linux/platform_specific_network_interface_listener_impl.h b/src/components/transport_manager/include/transport_manager/tcp/platform_specific/linux/platform_specific_network_interface_listener_impl.h index bb60b09a9d..4a78af4eb1 100644 --- a/src/components/transport_manager/include/transport_manager/tcp/platform_specific/linux/platform_specific_network_interface_listener_impl.h +++ b/src/components/transport_manager/include/transport_manager/tcp/platform_specific/linux/platform_specific_network_interface_listener_impl.h @@ -32,24 +32,32 @@ class InterfaceStatus { bool IsAvailable() const; bool IsLoopback() const; + const std::string& GetName() const { + return name_; + } // only for debugging output unsigned int GetFlags() const { return flags_; } bool HasIPAddress() const; - std::string GetIPv4Address() const; - std::string GetIPv6Address() const; + const std::string GetIPv4Address() const; + const std::string GetIPv6Address() const; + + void SetName(const std::string& name) { + name_ = name; + } void SetFlags(unsigned int flags) { flags_ = flags; } // specify NULL to remove existing address - void SetIPv4Address(struct in_addr* addr); - void SetIPv6Address(struct in6_addr* addr); + void SetIPv4Address(const struct in_addr* addr); + void SetIPv6Address(const struct in6_addr* addr); private: + std::string name_; unsigned int flags_; bool has_ipv4_; bool has_ipv6_; @@ -57,7 +65,11 @@ class InterfaceStatus { struct in6_addr ipv6_address_; }; -typedef std::map InterfaceStatusTable; +/** + * @brief A map to store various status (IP addresses, status flags, etc.) of + * network interfaces. Keys of the map are index numbers of interfaces. + */ +typedef std::map InterfaceStatusTable; /** * @brief Listener to detect various events on network interfaces @@ -126,6 +138,12 @@ class PlatformSpecificNetworkInterfaceListener const std::string& GetSelectedInterfaceName() const { return selected_interface_; } + + // for testing only: overwrites if_indextoname() by registering a dummy + // index-to-name mapping table + void SetDummyNameMap(const std::map& m) { + dummy_name_map_ = m; + } #endif // BUILD_TESTS private: @@ -140,6 +158,17 @@ class PlatformSpecificNetworkInterfaceListener : if_index(interface_index), flags(interface_flags), address() {} }; + // use with std::find_if() to search for an entry containing specified + // interface name + struct NamePredicate { + NamePredicate(const std::string& name) : name_(name) {} + bool operator()( + const std::pair& entry) const { + return entry.second.GetName() == name_; + } + const std::string& name_; + }; + // parent class which we will notify the events to TcpClientListener* tcp_client_listener_; // if configured, NetworkInterfaceListener will always look into the IP @@ -160,6 +189,7 @@ class PlatformSpecificNetworkInterfaceListener #ifdef BUILD_TESTS bool testing_; + std::map dummy_name_map_; #endif void Loop(); @@ -178,6 +208,8 @@ class PlatformSpecificNetworkInterfaceListener // convert ifaddrmsg to a list of EventParam structs std::vector ParseIFAddrMessage(struct ifaddrmsg* message, unsigned int size); + // return network interface name of the specified index + const std::string GetInterfaceName(unsigned int if_index) const; // for debugging void DumpTable() const; diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h index f033d35bf7..9eea8389e6 100644 --- a/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h +++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h @@ -150,6 +150,7 @@ class TcpClientListener : public ClientConnectionListener { threads::Thread* thread_; int socket_; bool thread_stop_requested_; + bool remove_devices_on_terminate_; int pipe_fds_[2]; NetworkInterfaceListener* interface_listener_; const std::string designated_interface_; diff --git a/src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc b/src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc index 2e79e84f2e..b37e5dc962 100644 --- a/src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc +++ b/src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc @@ -23,7 +23,6 @@ namespace transport_adapter { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") -static std::string GetInterfaceName(unsigned int if_index); static bool SetNonblocking(int s); bool InterfaceStatus::IsAvailable() const { @@ -39,7 +38,7 @@ bool InterfaceStatus::HasIPAddress() const { return has_ipv4_ || has_ipv6_; } -std::string InterfaceStatus::GetIPv4Address() const { +const std::string InterfaceStatus::GetIPv4Address() const { char buf[INET_ADDRSTRLEN] = ""; if (has_ipv4_ && IsAvailable()) { inet_ntop(AF_INET, &ipv4_address_, buf, sizeof(buf)); @@ -47,7 +46,7 @@ std::string InterfaceStatus::GetIPv4Address() const { return std::string(buf); } -std::string InterfaceStatus::GetIPv6Address() const { +const std::string InterfaceStatus::GetIPv6Address() const { char buf[INET6_ADDRSTRLEN] = ""; if (has_ipv6_ && IsAvailable()) { inet_ntop(AF_INET6, &ipv6_address_, buf, sizeof(buf)); @@ -55,7 +54,7 @@ std::string InterfaceStatus::GetIPv6Address() const { return std::string(buf); } -void InterfaceStatus::SetIPv4Address(struct in_addr* addr) { +void InterfaceStatus::SetIPv4Address(const struct in_addr* addr) { if (addr == NULL) { has_ipv4_ = false; } else { @@ -64,7 +63,7 @@ void InterfaceStatus::SetIPv4Address(struct in_addr* addr) { } } -void InterfaceStatus::SetIPv6Address(struct in6_addr* addr) { +void InterfaceStatus::SetIPv6Address(const struct in6_addr* addr) { if (addr == NULL) { has_ipv6_ = false; } else { @@ -376,8 +375,13 @@ bool PlatformSpecificNetworkInterfaceListener::InitializeStatus() { continue; } - std::string ifname(interface->ifa_name); - InterfaceStatus& status = status_table_[ifname]; + unsigned int index = if_nametoindex(interface->ifa_name); + if (index == 0) { + // network interface isn't found + continue; + } + + InterfaceStatus& status = status_table_[index]; switch (interface->ifa_addr->sa_family) { case AF_INET: { @@ -395,6 +399,7 @@ bool PlatformSpecificNetworkInterfaceListener::InitializeStatus() { default: continue; } + status.SetName(std::string(interface->ifa_name)); status.SetFlags(interface->ifa_flags); } @@ -412,25 +417,22 @@ bool PlatformSpecificNetworkInterfaceListener::UpdateStatus( for (std::vector::iterator it = params.begin(); it != params.end(); ++it) { - std::string ifname = GetInterfaceName(it->if_index); - if (ifname.empty()) { - continue; - } - - InterfaceStatus& status = status_table_[ifname]; - + InterfaceStatus& status = status_table_[it->if_index]; switch (type) { case RTM_NEWLINK: { + const std::string& ifname = GetInterfaceName(it->if_index); LOG4CXX_DEBUG( logger_, "netlink event: interface " << ifname << " created or updated"); + status.SetName(ifname); status.SetFlags(it->flags); break; } case RTM_DELLINK: - LOG4CXX_DEBUG(logger_, - "netlink event: interface " << ifname << " removed"); - status_table_.erase(ifname); + LOG4CXX_DEBUG( + logger_, + "netlink event: interface " << status.GetName() << " removed"); + status_table_.erase(it->if_index); break; case RTM_NEWADDR: { sockaddr* addr = reinterpret_cast(&it->address); @@ -439,14 +441,14 @@ bool PlatformSpecificNetworkInterfaceListener::UpdateStatus( status.SetIPv4Address(&addr_in->sin_addr); LOG4CXX_DEBUG(logger_, "netlink event: IPv4 address of interface " - << ifname << " updated to " + << status.GetName() << " updated to " << status.GetIPv4Address()); } else if (addr->sa_family == AF_INET6) { sockaddr_in6* addr_in6 = reinterpret_cast(addr); status.SetIPv6Address(&addr_in6->sin6_addr); LOG4CXX_DEBUG(logger_, "netlink event: IPv6 address of interface " - << ifname << " updated to " + << status.GetName() << " updated to " << status.GetIPv6Address()); } break; @@ -456,12 +458,12 @@ bool PlatformSpecificNetworkInterfaceListener::UpdateStatus( if (addr->sa_family == AF_INET) { LOG4CXX_DEBUG(logger_, "netlink event: IPv4 address of interface " - << ifname << " removed"); + << status.GetName() << " removed"); status.SetIPv4Address(NULL); } else if (addr->sa_family == AF_INET6) { LOG4CXX_DEBUG(logger_, "netlink event: IPv6 address of interface " - << ifname << " removed"); + << status.GetName() << " removed"); status.SetIPv6Address(NULL); } break; @@ -484,9 +486,12 @@ void PlatformSpecificNetworkInterfaceListener::NotifyIPAddresses() { // note that if interface_name is empty (i.e. no interface is selected), // the IP addresses will be empty if (!interface_name.empty()) { - InterfaceStatusTable::iterator it = status_table_.find(interface_name); + InterfaceStatusTable::const_iterator it = + std::find_if(status_table_.begin(), + status_table_.end(), + NamePredicate(interface_name)); if (status_table_.end() != it) { - InterfaceStatus& status = it->second; + const InterfaceStatus& status = it->second; ipv4_addr = status.GetIPv4Address(); ipv6_addr = status.GetIPv6Address(); } @@ -514,14 +519,16 @@ const std::string PlatformSpecificNetworkInterfaceListener::SelectInterface() { return designated_interface_; } - InterfaceStatusTable::iterator it; + InterfaceStatusTable::const_iterator it; if (!selected_interface_.empty()) { // if current network interface is still available and has IP address, then // we use it - it = status_table_.find(selected_interface_); + it = std::find_if(status_table_.begin(), + status_table_.end(), + NamePredicate(selected_interface_)); if (it != status_table_.end()) { - InterfaceStatus& status = it->second; + const InterfaceStatus& status = it->second; if (status.IsAvailable() && status.HasIPAddress()) { return selected_interface_; } @@ -530,17 +537,17 @@ const std::string PlatformSpecificNetworkInterfaceListener::SelectInterface() { // pick a network interface that has IP address for (it = status_table_.begin(); it != status_table_.end(); ++it) { - InterfaceStatus& status = it->second; + const InterfaceStatus& status = it->second; // ignore loopback interfaces if (status.IsLoopback()) { continue; } - // if the interface has to be UP and RUNNING, and must have an IP address + // the interface has to be UP and RUNNING, and must have an IP address if (!(status.IsAvailable() && status.HasIPAddress())) { continue; } - selected_interface_ = it->first; + selected_interface_ = status.GetName(); LOG4CXX_DEBUG(logger_, "selecting network interface: " << selected_interface_); return selected_interface_; @@ -618,13 +625,12 @@ void PlatformSpecificNetworkInterfaceListener::DumpTable() const { "Number of network interfaces: " << status_table_.size()); for (auto it = status_table_.begin(); it != status_table_.end(); ++it) { - const std::string ifname = it->first; const InterfaceStatus& status = it->second; UNUSED(status); LOG4CXX_DEBUG( logger_, - " " << ifname << " : flags=" << status.GetFlags() + " " << status.GetName() << " : flags=" << status.GetFlags() << " : available: " << (status.IsAvailable() ? "yes" : "no") << " IPv4: " << status.GetIPv4Address() << " IPv6: " << status.GetIPv6Address() @@ -632,6 +638,28 @@ void PlatformSpecificNetworkInterfaceListener::DumpTable() const { } } +const std::string PlatformSpecificNetworkInterfaceListener::GetInterfaceName( + unsigned int if_index) const { +#ifdef BUILD_TESTS + if (testing_) { + std::map::const_iterator it = + dummy_name_map_.find(if_index); + if (it == dummy_name_map_.end()) { + return std::string(); + } + return it->second; + } +#endif // BUILD_TESTS + + char buf[IFNAMSIZ + 1] = ""; + char* ret = if_indextoname(if_index, buf); + if (ret != NULL) { + return std::string(buf); + } else { + return std::string(); + } +} + PlatformSpecificNetworkInterfaceListener::ListenerThreadDelegate:: ListenerThreadDelegate(PlatformSpecificNetworkInterfaceListener* parent) : parent_(parent) {} @@ -646,12 +674,6 @@ void PlatformSpecificNetworkInterfaceListener::ListenerThreadDelegate:: parent_->StopLoop(); } -static std::string GetInterfaceName(unsigned int if_index) { - char buf[IFNAMSIZ + 1] = ""; - if_indextoname(if_index, buf); - return std::string(buf); -} - static bool SetNonblocking(int s) { int prev_flag = fcntl(s, F_GETFL, 0); if (prev_flag == -1) { diff --git a/src/components/transport_manager/src/tcp/tcp_client_listener.cc b/src/components/transport_manager/src/tcp/tcp_client_listener.cc index c2cbac4e13..df4409b8f3 100644 --- a/src/components/transport_manager/src/tcp/tcp_client_listener.cc +++ b/src/components/transport_manager/src/tcp/tcp_client_listener.cc @@ -86,6 +86,7 @@ TcpClientListener::TcpClientListener(TransportAdapterController* controller, , thread_(0) , socket_(-1) , thread_stop_requested_(false) + , remove_devices_on_terminate_(false) , designated_interface_(designated_interface) { pipe_fds_[0] = pipe_fds_[1] = -1; thread_ = threads::CreateThread("TcpClientListener", @@ -107,7 +108,7 @@ TransportAdapter::Error TcpClientListener::Init() { return TransportAdapter::FAIL; } } else { - // Network interface is specified and we wiill listen only on the interface. + // Network interface is specified and we will listen only on the interface. // In this case, the server socket will be created once // NetworkInterfaceListener notifies the interface's IP address. LOG4CXX_INFO(logger_, @@ -226,6 +227,7 @@ void TcpClientListener::Loop() { LOG4CXX_AUTO_TRACE(logger_); fd_set rfds; char dummy[16]; + std::vector device_uid_list; while (!thread_stop_requested_) { FD_ZERO(&rfds); @@ -323,10 +325,19 @@ void TcpClientListener::Loop() { if (TransportAdapter::OK != error) { LOG4CXX_ERROR(logger_, "TCP connection::Start() failed with error: " << error); + } else { + device_uid_list.push_back(device->unique_device_id()); } } } + if (remove_devices_on_terminate_) { + for (std::vector::iterator it = device_uid_list.begin(); + it != device_uid_list.end(); + ++it) { + controller_->DeviceDisconnected(*it, DisconnectDeviceError()); + } + } LOG4CXX_INFO(logger_, "TCP server socket loop is terminated."); } @@ -444,8 +455,7 @@ TransportAdapter::Error TcpClientListener::StartListeningThread() { if (pipe_fds_[0] < 0 || pipe_fds_[1] < 0) { // recreate the pipe every time, so that the thread loop will not get - // leftover - // data inside pipe after it is started + // leftover data inside pipe after it is started if (pipe(pipe_fds_) != 0) { LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create internal pipe"); return TransportAdapter::FAIL; @@ -534,6 +544,8 @@ bool TcpClientListener::StartOnNetworkInterface() { } } + remove_devices_on_terminate_ = true; + if (TransportAdapter::OK != StartListeningThread()) { LOG4CXX_WARN(logger_, "Failed to start TCP client listener"); return false; @@ -559,6 +571,8 @@ bool TcpClientListener::StopOnNetworkInterface() { socket_ = -1; } + remove_devices_on_terminate_ = false; + LOG4CXX_INFO( logger_, "TCP server socket on " << designated_interface_ << " stopped"); diff --git a/src/components/transport_manager/test/platform_specific/linux/linux_network_interface_listener_test.cc b/src/components/transport_manager/test/platform_specific/linux/linux_network_interface_listener_test.cc index 97c8fac9c9..0f2f0a2045 100644 --- a/src/components/transport_manager/test/platform_specific/linux/linux_network_interface_listener_test.cc +++ b/src/components/transport_manager/test/platform_specific/linux/linux_network_interface_listener_test.cc @@ -32,6 +32,7 @@ class NetworkInterfaceListenerTest : public ::testing::Test { protected: struct InterfaceEntry { const char* name; + const unsigned int index; const char* ipv4_address; const char* ipv6_address; unsigned int flags; @@ -48,8 +49,9 @@ class NetworkInterfaceListenerTest : public ::testing::Test { delete interface_listener_impl_; } - void SetDummyInterfaceTable(struct InterfaceEntry* entries) { + void SetDummyInterfaceTable(const struct InterfaceEntry* entries) { InterfaceStatusTable dummy_table; + std::map dummy_name_map; while (entries->name != NULL) { InterfaceStatus status; @@ -63,13 +65,16 @@ class NetworkInterfaceListenerTest : public ::testing::Test { ASSERT_EQ(1, inet_pton(AF_INET6, entries->ipv6_address, &addr6)); status.SetIPv6Address(&addr6); } + status.SetName(entries->name); status.SetFlags(entries->flags); - dummy_table.insert(std::make_pair(entries->name, status)); + dummy_table.insert(std::make_pair(entries->index, status)); + dummy_name_map[entries->index] = std::string(entries->name); entries++; } interface_listener_impl_->OverwriteStatusTable(dummy_table); + interface_listener_impl_->SetDummyNameMap(dummy_name_map); } void SleepFor(long msec) const { @@ -108,8 +113,8 @@ TEST_F(NetworkInterfaceListenerTest, Start_success) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries[] = { - {"dummy_int0", "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries); // after stated, it is expected that the listener notifies current IP address @@ -198,11 +203,11 @@ TEST_F(NetworkInterfaceListenerTest, DesignatedInterface_IPAddressChanged) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries1[] = { - {"dummy_int0", "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; struct InterfaceEntry entries2[] = { - {"dummy_int0", "5.6.7.8", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "5.6.7.8", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries1); @@ -230,13 +235,13 @@ TEST_F(NetworkInterfaceListenerTest, DesignatedInterface_IPAddressNotChanged) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries1[] = { - {"dummy_int0", "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, + {"dummy_int1", 2, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; struct InterfaceEntry entries2[] = { - {"dummy_int0", "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, - {"dummy_int1", "172.16.23.30", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, + {"dummy_int1", 2, "172.16.23.30", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries1); @@ -261,13 +266,13 @@ TEST_F(NetworkInterfaceListenerTest, DesignatedInterface_GoesUnavailable) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries1[] = { - {"dummy_int0", "1.2.3.4", "fdc2:12af:327a::1", IFF_UP | IFF_RUNNING}, - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "1.2.3.4", "fdc2:12af:327a::1", IFF_UP | IFF_RUNNING}, + {"dummy_int1", 2, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; struct InterfaceEntry entries2[] = { - {"dummy_int0", "1.2.3.4", "fdc2:12af:327a::1", IFF_UP}, - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "1.2.3.4", "fdc2:12af:327a::1", IFF_UP}, + {"dummy_int1", 2, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries1); @@ -292,12 +297,12 @@ TEST_F(NetworkInterfaceListenerTest, DesignatedInterface_Removed) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries1[] = { - {"dummy_int0", "1.2.3.4", "fdc2:12af:327a::1", IFF_UP | IFF_RUNNING}, - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int0", 1, "1.2.3.4", "fdc2:12af:327a::1", IFF_UP | IFF_RUNNING}, + {"dummy_int1", 2, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; struct InterfaceEntry entries2[] = { - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int1", 2, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries1); @@ -322,12 +327,12 @@ TEST_F(NetworkInterfaceListenerTest, DesignatedInterface_Added) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries1[] = { - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int1", 1, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; struct InterfaceEntry entries2[] = { - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {"dummy_int0", "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int1", 1, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {"dummy_int0", 2, "1.2.3.4", NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries1); @@ -350,9 +355,13 @@ TEST_F(NetworkInterfaceListenerTest, AutoSelectInterface_SelectInterface) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries[] = { - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {"net_dummy2", "192.168.2.3", "fdc2:12af:327a::22", IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int1", 1, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {"net_dummy2", + 2, + "192.168.2.3", + "fdc2:12af:327a::22", + IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries); @@ -384,9 +393,13 @@ TEST_F(NetworkInterfaceListenerTest, EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries[] = { - {"dummy_int1", "10.10.10.12", NULL, IFF_UP}, - {"net_dummy2", "192.168.2.3", "fdc2:12af:327a::22", IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int1", 1, "10.10.10.12", NULL, IFF_UP}, + {"net_dummy2", + 2, + "192.168.2.3", + "fdc2:12af:327a::22", + IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries); @@ -410,9 +423,9 @@ TEST_F(NetworkInterfaceListenerTest, AutoSelectInterface_SkipEmptyInterface) { EXPECT_TRUE(interface_listener_impl_->Init()); struct InterfaceEntry entries[] = { - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, - {"net_dummy2", NULL, NULL, IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + {"dummy_int1", 1, "10.10.10.12", NULL, IFF_UP | IFF_RUNNING}, + {"net_dummy2", 2, NULL, NULL, IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; SetDummyInterfaceTable(entries); @@ -435,10 +448,17 @@ TEST_F(NetworkInterfaceListenerTest, Init(""); EXPECT_TRUE(interface_listener_impl_->Init()); - struct InterfaceEntry entries[] = { - {"dummy_int1", "10.10.10.12", NULL, IFF_UP | IFF_RUNNING | IFF_LOOPBACK}, - {"net_dummy2", "192.168.2.3", "fdc2:12af:327a::22", IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + struct InterfaceEntry entries[] = {{"dummy_int1", + 1, + "10.10.10.12", + NULL, + IFF_UP | IFF_RUNNING | IFF_LOOPBACK}, + {"net_dummy2", + 2, + "192.168.2.3", + "fdc2:12af:327a::22", + IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; // dummy_int1 should not be selected struct InterfaceEntry* expected = &entries[1]; @@ -461,9 +481,12 @@ TEST_F(NetworkInterfaceListenerTest, AutoSelectInterface_DisableInterface) { Init(""); EXPECT_TRUE(interface_listener_impl_->Init()); - struct InterfaceEntry entries[] = { - {"net_dummy0", "192.168.2.3", "fdc2:12af:327a::22", IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + struct InterfaceEntry entries[] = {{"net_dummy0", + 1, + "192.168.2.3", + "fdc2:12af:327a::22", + IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; EXPECT_CALL(mock_tcp_client_listener_, OnIPAddressUpdated(_, _)).Times(1); SetDummyInterfaceTable(entries); @@ -487,9 +510,12 @@ TEST_F(NetworkInterfaceListenerTest, AutoSelectInterface_EnableInterface) { Init(""); EXPECT_TRUE(interface_listener_impl_->Init()); - struct InterfaceEntry entries[] = { - {"net_dummy0", "192.168.2.3", "fdc2:12af:327a::22", IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + struct InterfaceEntry entries[] = {{"net_dummy0", + 1, + "192.168.2.3", + "fdc2:12af:327a::22", + IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; EXPECT_CALL(mock_tcp_client_listener_, OnIPAddressUpdated(_, _)).Times(1); SetDummyInterfaceTable(entries); @@ -525,13 +551,17 @@ TEST_F(NetworkInterfaceListenerTest, AutoSelectInterface_SwitchInterface) { Init(""); EXPECT_TRUE(interface_listener_impl_->Init()); - struct InterfaceEntry entries[] = { - {"dummy_int1", - "10.10.10.12", - "fd53:ba79:241d:30c1::78", - IFF_UP | IFF_RUNNING}, - {"net_dummy2", "192.168.2.3", "fdc2:12af:327a::22", IFF_UP | IFF_RUNNING}, - {NULL, NULL, NULL, 0}}; + struct InterfaceEntry entries[] = {{"dummy_int1", + 1, + "10.10.10.12", + "fd53:ba79:241d:30c1::78", + IFF_UP | IFF_RUNNING}, + {"net_dummy2", + 2, + "192.168.2.3", + "fdc2:12af:327a::22", + IFF_UP | IFF_RUNNING}, + {NULL, 0, NULL, NULL, 0}}; EXPECT_CALL(mock_tcp_client_listener_, OnIPAddressUpdated(_, _)).Times(1); SetDummyInterfaceTable(entries); -- cgit v1.2.1