Fix ifaddrs#getifaddrs_INET flakiness.

The interface name wasn't being nul-terminated for the ioctl. Also clean up
the code a bit to give more useful diagnostics on failure.

Bug: http://b/26887941
Change-Id: I30c6bdc1a32733971a27ed1fb7db9d8239b6262b
This commit is contained in:
Elliott Hughes 2016-02-03 07:42:33 -08:00
parent 3e75110bcb
commit 2d5e21f00d
1 changed files with 39 additions and 39 deletions

View File

@ -112,7 +112,7 @@ TEST(ifaddrs, getifaddrs_INET) {
std::multimap<std::string, in_addr_t> inetaddrs; std::multimap<std::string, in_addr_t> inetaddrs;
std::multimap<std::string, in_addr_t> broadinetaddrs; std::multimap<std::string, in_addr_t> broadinetaddrs;
{ // Collect the IPv4 addresses for each interface.
ifaddrs* addrs; ifaddrs* addrs;
ASSERT_EQ(0, getifaddrs(&addrs)); ASSERT_EQ(0, getifaddrs(&addrs));
for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) { for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
@ -126,18 +126,22 @@ TEST(ifaddrs, getifaddrs_INET) {
} }
} }
freeifaddrs(addrs); freeifaddrs(addrs);
}
{ // Check that the addresses returned by the SIOCGIFADDR and SIOCGIFBRDADDR ioctls
// are in our collections.
auto check_inet_agrees = [&](std::multimap<std::string, in_addr_t> addrs, int request)->void {
for (auto it = addrs.begin(); it != addrs.end(); ) {
std::string if_name(it->first);
ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
if_name.copy(ifr.ifr_name, IFNAMSIZ - 1);
int fd = socket(AF_INET, SOCK_DGRAM, 0); int fd = socket(AF_INET, SOCK_DGRAM, 0);
ASSERT_TRUE(fd != -1); ASSERT_TRUE(fd != -1);
ASSERT_EQ(0, ioctl(fd, request, &ifr)) << if_name << ' ' << strerror(errno);
auto check_inet_agrees = [&](std::multimap<std::string, in_addr_t> addrs, int request)->bool { close(fd);
for (auto it = addrs.begin(); it != addrs.end(); ) {
ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;
it->first.copy(ifr.ifr_name, IFNAMSIZ - 1);
ioctl(fd, request, &ifr);
sockaddr_in* sock = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr); sockaddr_in* sock = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr);
in_addr_t addr = sock->sin_addr.s_addr; in_addr_t addr = sock->sin_addr.s_addr;
@ -148,16 +152,12 @@ TEST(ifaddrs, getifaddrs_INET) {
found = true; found = true;
} }
} }
if (!found) return false; EXPECT_TRUE(found) << if_name;
} }
return true;
}; };
ASSERT_TRUE(check_inet_agrees(inetaddrs, SIOCGIFADDR)); check_inet_agrees(inetaddrs, SIOCGIFADDR);
ASSERT_TRUE(check_inet_agrees(broadinetaddrs, SIOCGIFBRDADDR)); check_inet_agrees(broadinetaddrs, SIOCGIFBRDADDR);
close(fd);
}
} }
static void print_sockaddr_ll(const char* what, const sockaddr* p) { static void print_sockaddr_ll(const char* what, const sockaddr* p) {